1. 程式人生 > >主成分分析(PCA)

主成分分析(PCA)

一、PCA簡介

主成分分(Principal Component Analysis,PCA), 是一種統計方法。通過正交變換將一組可能存在相關性的變數轉換為一組線性不相關的變數,轉換後的這組變數叫主成分。

二、PCA提出的背景

在許多領域的研究與應用中,往往需要對反映事物的多個變數進行大量的觀測,收集大量資料以便進行分析尋找規律。多變數大樣本無疑會為研究和應用提供了豐富的資訊,但也在一定程度上增加了資料採集的工作量,更重要的是在多數情況下,許多變數之間可能存在相關性,從而增加了問題分析的複雜性,同時對分析帶來不便。如果分別對每個指標進行分析,分析往往是孤立的,而不是綜合的。盲目減少指標會損失很多資訊,容易產生錯誤的結論。

因此需要找到一個合理的方法,在減少需要分析的指標同時,儘量減少原指標包含資訊的損失,以達到對所收集資料進行全面分析的目的。由於各變數間存在一定的相關關係,因此有可能用較少的綜合指標分別綜合存在於各變數中的各類資訊。主成分分析與因子分析就屬於這類降維的方法。

三、PCA的推導

主成分的意思就是資料的主要成分,對於給定的一些資料,我們一般來說關心的是資料中變化的部分,變化的越多,我們得到的資訊也就越多,而資料中不變的地方,我們能收集到的資訊非常有限,所以,資料中變化較多的部分就構成了資料的主成分。

為了說明什麼是資料的主成分,先從資料降維說起。資料降維是怎麼回事兒?假設三維空間中有一系列點,這些點分佈在一個過原點的斜面上,如果你用自然座標系x,y,z這三個軸來表示這組資料的話,需要使用三個維度,而事實上,這些點的分佈僅僅是在一個二維的平面上,那麼,問題出在哪裡?如果你再仔細想想,能不能把x,y,z座標系旋轉一下,使資料所在平面與x,y平面重合?這就對了!如果把旋轉後的座標系記為x’,y’,z’,那麼這組資料的表示只用x’和y’兩個維度表示即可!當然了,如果想恢復原來的表示方式,那就得把這兩個座標之間的變換矩陣存下來。這樣就能把資料維度降下來了!但是,我們要看到這個過程的本質,如果把這些資料按行或者按列排成一個矩陣,那麼這個矩陣的秩就是2!這些資料之間是有相關性的,這些資料構成的過原點的向量的最大線性無關組包含2個向量,這就是為什麼一開始就假設平面過原點的原因!那麼如果平面不過原點呢?這就是資料中心化的緣故!將座標原點平移到資料中心,這樣原本不相關的資料在這個新座標系中就有相關性了!有趣的是,三點一定共面,也就是說三維空間中任意三點中心化後都是線性相關的,一般來講n維空間中的n個點一定能在一個n-1維子空間中分析!

上一段文字中,認為把資料降維後並沒有丟棄任何東西,因為這些資料在平面以外的第三個維度的分量都為0。現在,假設這些資料在z’軸有一個很小的抖動,那麼我們仍然用上述的二維表示這些資料,理由是我們可以認為這兩個軸的資訊是資料的主成分,而這些資訊對於我們的分析已經足夠了,z’軸上的抖動很有可能是噪聲,也就是說本來這組資料是有相關性的,噪聲的引入,導致了資料不完全相關,但是,這些資料在z’軸上的分佈與原點構成的夾角非常小,也就是說在z’軸上有很大的相關性,綜合這些考慮,就可以認為資料在x’,y’ 軸上的投影構成了資料的主成分。

PCA的思想是將n維特徵對映到k維上(k<n),這k維是全新的正交特徵。這k維特徵稱為主成分,

是重新構造出來的k維特徵,而不是簡單地從n維特徵中去除其餘n-k維特徵。

PCA的主要數學推導,參考下面的一篇文章:

總結一下,做PCA的主要步驟如下:

設有m條n維資料。

1)將原始資料按照m行n列排列的,如matlab和Python中都是這樣(每一列代表一個特徵)

2)將X的每一列(代表一個屬性欄位)進行零均值化,即減去這一列的均值

3)求出協方差矩陣

4)求出協方差矩陣的特徵值及對應的特徵向量

5)將上一步得到的特徵向量組成矩陣V

6)求Y=XV,再取Y的前k列得到Y'即為要求的矩陣

這裡註釋一下以上矩陣的維數便於理解,在程式設計時防止矩陣相乘時的維數錯誤:

矩陣X:m x n (n維m個數據)

矩陣V:n x n

矩陣Y:m x n(n維m個數據)

矩陣Y':m x k(k維m個數據)

四、PCA的演算法模擬

1.使用matlab中自帶的pca函式程式碼如下:
k=2;                            %將樣本降到k維引數設定  
X=[1 2 1 1;                     %樣本矩陣  
      3 3 1 2;   
      3 5 4 3;   
      5 4 5 4;  
      5 6 1 5;   
      6 5 2 6;  
      8 7 1 2;  
      9 8 3 7];  
[COEFF,SCORE,latent]=pca(X)
pcaData1=SCORE(:,1:k)

結果:

COEFF =

    0.7084   -0.2826   -0.2766   -0.5846
    0.5157   -0.2114   -0.1776    0.8111
    0.0894    0.7882   -0.6086    0.0153
    0.4735    0.5041    0.7222   -0.0116


SCORE =

   -5.7947   -0.6071    0.4140   -0.0823
   -3.3886   -0.8795    0.4054   -0.4519
   -1.6155    1.5665   -1.0535    1.2047
   -0.1513    2.5051   -1.3157   -0.7718
    0.9958   -0.5665    1.4859    0.7775
    1.7515    0.6546    1.5004   -0.6144
    2.2162   -3.1381   -1.6879   -0.1305
    5.9867    0.4650    0.2514    0.0689


latent =

   13.2151
    2.9550
    1.5069
    0.4660


pcaData1 =

   -5.7947   -0.6071
   -3.3886   -0.8795
   -1.6155    1.5665
   -0.1513    2.5051
    0.9958   -0.5665
    1.7515    0.6546
    2.2162   -3.1381
    5.9867    0.4650
其中,SCORE是按照主成分的大小排列成的列矩陣,LATENT為各個主成分的係數,pcaData1為提取出來的前兩個主成分

2.在matlab中自己編寫pca函式

方法已經解釋過了,程式碼如下:

k=2;                            %將樣本降到k維引數設定  
X=[1 2 1 1;                     %樣本矩陣  
      3 3 1 2;   
      3 5 4 3;   
      5 4 5 4;  
      5 6 1 5;   
      6 5 2 6;  
      8 7 1 2;  
      9 8 3 7];  
[Row, Col]=size(X);  
covX=cov(X);                                  %求樣本的協方差矩陣(散步矩陣除以(n-1)即為協方差矩陣)  
[V, D]=eigs(covX);                            %求協方差矩陣的特徵值D和特徵向量V  
meanX=mean(X);                                %樣本均值m  
tempX= repmat(meanX,Row,1);                   %所有樣本X減去樣本均值m,再乘以協方差矩陣(散步矩陣)的特徵向量V,即為樣本的主成份SCORE                          
SCORE2=(X-tempX)*fliplr(V)                    %主成份:SCORE2,V矩陣是按照特徵值從小到大的順序排列的,所以需要翻轉一下 
pcaData2=SCORE2(:,1:k)
結果如下:
SCORE2 =

   -5.7947    0.6071   -0.4140    0.0823
   -3.3886    0.8795   -0.4054    0.4519
   -1.6155   -1.5665    1.0535   -1.2047
   -0.1513   -2.5051    1.3157    0.7718
    0.9958    0.5665   -1.4859   -0.7775
    1.7515   -0.6546   -1.5004    0.6144
    2.2162    3.1381    1.6879    0.1305
    5.9867   -0.4650   -0.2514   -0.0689


pcaData2 =

   -5.7947    0.6071
   -3.3886    0.8795
   -1.6155   -1.5665
   -0.1513   -2.5051
    0.9958    0.5665
    1.7515   -0.6546
    2.2162    3.1381
    5.9867   -0.4650
可見於matlab內建的函式得到的結果是一致的


3.使用Python模擬pca
可以參考這個庫函式的說明:
點選開啟連結

文中說明了在sklearn.decomposition這個庫中pca方法的使用以及例子

注意:在pca的很多演算法中,都採用的SVD代替特徵值法來求解對角矩陣那麼SVD與PCA有什麼關係呢?我們考慮\textbf{S}_X的SVD表示方式:\textbf{S}_X=\frac{1}{n-1} \textbf{V}\Sigma \textbf{U}^T\textbf{U}\Sigma\textbf{V}^T=\frac{1}{n-1}\textbf{V}\Sigma^2\textbf{V}^T,所以到這裡答案就很明顯了,我們只需要取另一個投影矩陣\textbf{P}=\textbf{V}^T就可以將\textbf{S}_Y對角化,即\textbf{V}的列是principal components。順便,我們得到了一個副產品奇異值和特徵值的關係:\lambda_i=\frac{1}{n-1}s_i^2,其中\lambda_i,s_i\textbf{S}_X\Sigma相應的特徵值和奇異值。因此,我們得到了SVD是PCA的另一種algebraic formulation。而這也提供了另外一種演算法來計算PCA,實際上,平時我就是用SVD定義的這套演算法來做PCA的。因為很方便,計算一次就可以了。

上面為引用,連結:https://www.zhihu.com/question/38319536/answer/131029607Python程式碼如下:

import numpy as np
from sklearn.decomposition import PCA
import sys
#returns choosing how many main factors
def index_lst(lst, component=0, rate=0):
  #component: numbers of main factors
  #rate: rate of sum(main factors)/sum(all factors)
  #rate range suggest: (0.8,1)
  #if you choose rate parameter, return index = 0 or less than len(lst)
  if component and rate:
    print('Component and rate must choose only one!')
    sys.exit(0)
  if not component and not rate:
    print('Invalid parameter for numbers of components!')
    sys.exit(0)
  elif component:
    print('Choosing by component, components are %s......'%component)
    return component
  else:
    print('Choosing by rate, rate is %s ......'%rate)
    for i in range(1, len(lst)):
      if sum(lst[:i])/sum(lst) >= rate:
        return i
    return 0
 
def main():
  # test data
  mat = [[1,2,1,1],[3,3,1,2],[3,5,4,3],[5,4,5,4],[5,6,1,5],[6,5,2,6],[8,7,1,2],[9,8,3,7]]
   
  # simple transform of test data
  Mat = np.array(mat, dtype='float64')
  print('Before PCA transforMation, data is:\n', Mat)
  print('\nMethod 1: PCA by original algorithm:')
  p,n = np.shape(Mat) # shape of Mat 
  t = np.mean(Mat, 0) # mean of each column
   
  # substract the mean of each column
  for i in range(p):
    for j in range(n):
      Mat[i,j] = float(Mat[i,j]-t[j])
       
  # covariance Matrix
  cov_Mat = np.dot(Mat.T, Mat)/(p-1)
   
  # PCA by original algorithm
  # eigvalues and eigenvectors of covariance Matrix with eigvalues descending
  U,V = np.linalg.eigh(cov_Mat) 
  # Rearrange the eigenvectors and eigenvalues
  U = U[::-1]
  for i in range(n):
    V[i,:] = V[i,:][::-1]
  # choose eigenvalue by component or rate, not both of them euqal to 0
  Index = index_lst(U, component=2) # choose how many main factors
  if Index:
    v = V[:,:Index] # subset of Unitary matrix
  else: # improper rate choice may return Index=0
    print('Invalid rate choice.\nPlease adjust the rate.')
    print('Rate distribute follows:')
    print([sum(U[:i])/sum(U) for i in range(1, len(U)+1)])
    sys.exit(0)
  # data transformation
  T1 = np.dot(Mat, v)
  # print the transformed data
  print('We choose %d main factors.'%Index)
  print('After PCA transformation, data becomes:\n',T1)
   
  # PCA by original algorithm using SVD
  print('\nMethod 2: PCA by original algorithm using SVD:')
  # u: Unitary matrix, eigenvectors in columns 
  # d: list of the singular values, sorted in descending order
  u,d,v = np.linalg.svd(cov_Mat)
  Index = index_lst(d, rate=0.95) # choose how many main factors
  T2 = np.dot(Mat, u[:,:Index]) # transformed data
  print('We choose %d main factors.'%Index)
  print('After PCA transformation, data becomes:\n',T2)
   
  # PCA by Scikit-learn
  pca = PCA(n_components=2) # n_components can be integer or float in (0,1)
  pca.fit(mat) # fit the model
  print('\nMethod 3: PCA by Scikit-learn:')
  print('After PCA transformation, data becomes:')
  print(pca.fit_transform(mat)) # transformed data   
main()
執行結果:
Before PCA transforMation, data is:
 [[ 1.  2.  1.  1.]
 [ 3.  3.  1.  2.]
 [ 3.  5.  4.  3.]
 [ 5.  4.  5.  4.]
 [ 5.  6.  1.  5.]
 [ 6.  5.  2.  6.]
 [ 8.  7.  1.  2.]
 [ 9.  8.  3.  7.]]

Method 1: PCA by original algorithm:
Choosing by component, components are 2......
We choose 2 main factors.
After PCA transformation, data becomes:
 [[ 5.79467821  0.60705487]
 [ 3.38863423  0.87952394]
 [ 1.61549833 -1.56652328]
 [ 0.15133075 -2.50507639]
 [-0.99576675  0.56654487]
 [-1.7515016  -0.65460481]
 [-2.21615035  3.13807448]
 [-5.98672282 -0.46499368]]

Method 2: PCA by original algorithm using SVD:
Choosing by rate, rate is 0.95 ......
We choose 3 main factors.
After PCA transformation, data becomes:
 [[ 5.79467821  0.60705487  0.41402357]
 [ 3.38863423  0.87952394  0.40538881]
 [ 1.61549833 -1.56652328 -1.05351894]
 [ 0.15133075 -2.50507639 -1.3156637 ]
 [-0.99576675  0.56654487  1.48593239]
 [-1.7515016  -0.65460481  1.50039959]
 [-2.21615035  3.13807448 -1.68793779]
 [-5.98672282 -0.46499368  0.25137607]]

Method 3: PCA by Scikit-learn:
After PCA transformation, data becomes:
[[-5.79467821  0.60705487]
 [-3.38863423  0.87952394]
 [-1.61549833 -1.56652328]
 [-0.15133075 -2.50507639]
 [ 0.99576675  0.56654487]
 [ 1.7515016  -0.65460481]
 [ 2.21615035  3.13807448]
 [ 5.98672282 -0.46499368]]

可見此結果與在matlab中的模擬相同

五、主成分分析的主要優缺點

優點

  ①可消除評估指標之間的相關影響。因為主成分分析法在對原始資料指標變數進行變換後形成了彼此相互獨立的主成分,而且實踐證明指標間相關程度越高,主成分分析效果越好。

  ②可減少指標選擇的工作量,對於其他評估方法,由於難以消除評估指標間的相關影響,所以選擇指標時要花費不少精力,而主成分分析法由於可以消除這種相關影響,所以在指標選擇上相對容易些。

  ③主成分分析中各主成分是按方差大小依次排列順序的,在分析問題時,可以捨棄一部分主成分,只取前面方差較大的幾個主成分來代表原變數,從而減少了計算工作量。用主成分分析法作綜合評估時,由於選擇的原則是累計貢獻率≥85%,不至於因為節省了工作量卻把關鍵指標漏掉而影響評估結果。

缺點

  ①在主成分分析中,我們首先應保證所提取的前幾個主成分的累計貢獻率達到一個較高的水平(即變數降維後的資訊量須保持在一個較高水平上),其次對這些被提取的主成分必須都能夠給出符合實際背景和意義的解釋(否則主成分將空有資訊量而無實際含義)。

  ②主成分的解釋其含義一般多少帶有點模糊性,不像原始變數的含義那麼清楚、確切,這是變數降維過程中不得不付出的代價。因此,提取的主成分個數m通常應明顯小於原始變數個數p(除非p本身較小),否則維數降低的“利”可能抵不過主成分含義不如原始變數清楚的“弊”。

  ③當主成分的因子負荷的符號有正有負時,綜合評價函式意義就不明確

相關推薦

成分分析PCA原理詳解轉載

增加 信息 什麽 之前 repl 神奇 cto gmail 協方差 一、PCA簡介 1. 相關背景 上完陳恩紅老師的《機器學習與知識發現》和季海波老師的《矩陣代數》兩門課之後,頗有體會。最近在做主成分分析和奇異值分解方面的項目,所以記錄一下心得體會。

[python機器學習及實踐(6)]Sklearn實現成分分析PCA

相關性 hit 變量 gray tran total 空間 mach show 1.PCA原理 主成分分析(Principal Component Analysis,PCA), 是一種統計方法。通過正交變換將一組可能存在相關性的變量轉換為一組線性不相關的變量,轉換後的這組

【原始碼】成分分析PCA與獨立分量分析ICAMATLAB工具箱

本MATLAB工具箱包含PCA和ICA實現的多個函式,並且包括多個演示示例。 在主成分分析中,多維資料被投影到最大奇異值相對應的奇異向量上,該操作有效地將輸入訊號分解成在資料中最大方差方向上的正交分量。因此,PCA常用於維數降低的應用中,通過執行PCA產生資料的低維表示,同時,該低維表

成分分析PCA詳細講解

介紹 主成分分析(Principal Component Analysis,PCA)是一種常用的資料降維演算法,可以將高維度的資料降到低維度,並且保留原始資料中最重要的一些特徵,同時去除噪聲和部分關聯特徵,從而提高資料的處理效率,降低時間成本。 資料降維優點: 低維資

成分分析PCA原理詳解

1. 問題      真實的訓練資料總是存在各種各樣的問題: 1、 比如拿到一個汽車的樣本,裡面既有以“千米/每小時”度量的最大速度特徵,也有“英里/小時”的最大速度特徵,顯然這兩個特徵有一個多餘。 2、 拿到一個數學系的本科生期末考試成績單,裡面有三列,一列是對數學的

成分分析PCA在壓縮影象方面的應用

一、主成分分析的原理主成分分析能夠通過提取資料的主要成分,減少資料的特徵,達到資料降維的目的。具體的原理可參見之前寫的關於PCA原理的一篇文章:二、使用matlab模擬實現%% 利用PCA對影象壓縮 close all clear all clc %% 輸入 In = i

Machine Learning第八講【非監督學習】--成分分析PCA

一、Principal Component Analysis Problem Formulation(主成分分析構思) 首先來看一下PCA的基本原理: PCA會選擇投影誤差最小的一條線,由圖中可以看出,當這條線是我們所求時,投影誤差比較小,而投影誤差比較大時,一定是這條線偏離最優直線。

使用成分分析PCA方法對資料進行降維

我們知道當資料維度太大時,進行分類任務時會花費大量時間,因此需要進行資料降維,其中一種非常流行的降維方法叫主成分分析。 Exploratory Data Analysis 鳶尾花資料集: import numpy as np from skle

機器學習實戰學習筆記5——成分分析PCA

1.PCA演算法概述 1.1 PCA演算法介紹 主成分分析(Principal Component Analysis)是一種用正交變換的方法將一個可能相關變數的觀察值集合轉換成一個線性無關變數值集合的統計過程,被稱為主成分。主成分的數目小於或等於原始

成分分析PCA-理論基礎

要解釋為什麼協方差矩陣的特徵向量可以將原始特徵對映到 k 維理想特徵,我看到的有三個理論:分別是最大方差理論、最小錯誤理論和座標軸相關度理論。這裡簡單探討前兩種,最後一種在討論PCA 意義時簡單概述。 最大方差理論 在訊號處理中認為訊號具有較大的方差

成分分析PCA的線性代數推導過程

【摘自Ian Goodfellow 《DEEP LEANRNING》一書。覺得寫得挺清楚,儲存下來學習參考使用。】 主成分分析(principal components analysis, PCA)是一個簡單的機器學習演算法,可以通過基礎的線性代數知識推導。 假設在n維的R空間中我們有 m

成分分析PCA演算法做人臉識別

詳細資料可以參考https://www.cnblogs.com/xingshansi/p/6445625.html一、概念主成分分析(PCA)是一種統計方法。通過正交變換將一組可能存在相關性的變數轉化為一組線性不相關的變數,轉換後的這組變數叫主成分。二、思想PCA的思想是將n

成分分析pca演算法原理

影象處理中對很多副圖片提取特徵時,由於特徵的維數過高而影響程式的效率,所以用到pca進行特徵降維。 那怎樣才能降低維數呢?它又用到了什麼數學方法呢? 1.協方差矩陣         假設有一個樣本集X,裡面有N個樣本,每個樣本的維度為d。即: 將這些樣本組織成樣本矩陣形

成分分析pca演算法的實現步驟及程式碼

%%%%%%%%%%%%開啟一個30行8列資料的txt檔案%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %第一步:輸入樣本矩陣%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% filename='src.txt'; fid=fopen(filename,'

成分分析PCA與Kernel PCA

本部落格在之前的文章【1】中曾經介紹過PCA在影象壓縮中的應用。其基本思想就是設法提取資料的主成分(或者說是主要資訊),然後摒棄冗餘資訊(或次要資訊),從而達到壓縮的目的。本文將從更深的層次上討論PCA

機器學習十三:CS229ML課程筆記9——因子分析成分分析PCA、獨立成分分析ICA

1.因子分析:高維樣本點實際上是由低維樣本點經過高斯分佈、線性變換、誤差擾動生成的,因子分析是一種資料簡化技術,是一種資料的降維方法,可以從原始高維資料中,挖掘出仍然能表現眾多原始變數主要資訊的低維資料。是基於一種概率模型,使用EM演算法來估計引數。因子分析,是分析屬性們的公

深入學習成分分析PCA演算法原理及其Python實現

一:引入問題   首先看一個表格,下表是某些學生的語文,數學,物理,化學成績統計:   首先,假設這些科目成績不相關,也就是說某一科目考多少分與其他科目沒有關係,那麼如何判斷三個學生的優秀程度呢?首先我們一眼就能看出來,數學,物理,化學這三門課的成績構成了這組資料的主成分(很顯然,數學作為第一主成分,

對KLT,成分分析PCA演算法的理解

1 #include "pcaface.h" 2 #include "ui_pcaface.h" 3 #include <QString> 4 #include <iostream> 5 #include <stdio.h> 6 7 usi

成分分析PCA原理總結

    主成分分析(Principal components analysis,以下簡稱PCA)是最重要的降維方法之一。在資料壓縮消除冗餘和資料噪音消除等領域都有廣泛的應用。一般我們提到降維最容易想到的演算法就是PCA,下面我們就對PCA的原理做一個總結。 1. PCA的思想     PCA顧名思義,就是找出

成分分析PCA

一、PCA簡介主成分分析(Principal Component Analysis,PCA), 是一種統計方法。通過正交變換將一組可能存在相關性的變數轉換為一組線性不相關的變數,轉換後的這組變數叫主成分。二、PCA提出的背景在許多領域的研究與應用中,往往需要對反映事物的多個變