主成分分析 (principal component analysis, PCA) 是投影法的典型代表。投影法是指將高維的數據向低維投影,投影的方向可通過特征值分析等方法來確定。
具體來說,假設我們有一個具有 \(n\) 維特征的數據集,共有 \(m\) 個樣本點,我們希望這 \(m\) 個樣本的特征維度從 \(n\) 降維到 \(n'\) 維,希望這 \(n'\) 維的數據集盡可能地代表原始數據集。
PCA 的幾個注意點:
(1)原始數據中有多少個特征維度(變量),就會提取出多少個主成分。第一主成分包含了原始數據中最多的信息,第二個主成分包含了第二多的信息,依次遞減。主成分之間互相線性無關;
(2)選擇保留多少個主成分,取決於前 n 個主成分的累計方差占比(累計貢獻率)。一般來說,必須保證的前幾個主成分的累積貢獻率在較高水平(\(\ge85\%\));
(3)提取的主成分個數應明顯少於原始特征的個數,否則降維帶來的利可能還抵不過信息量損失的弊。
算法過程
(1)對變量進行 Z-Score 標准化操作,消除變量間量綱不同造成的影響。
(2)計算數據的協方差矩陣。
(3)計算所得協方差矩陣的特征值(即主成分方差)和特征向量。
(4)將所得特征值從大到小排序,並選擇最大的 k 個特征值(即前 k 個主成分)對應的特征向量。具體 k 如何選擇,需要計算前 k 個特征值的累積貢獻率來決定。
(5)將原始數據投影到所選取的 k 個特征向量組成的低維空間中,轉化為新的樣本。通過將原始數據乘以這 k 個特征向量即可得到。
算法的優缺點
優點:
(1)計算方法簡單,易於實現。
(2)可消除原始變量之間的相關影響,因為主成分分析法在對原始數據變量進行變換后形成了彼此獨立的主成分,而且實踐證明變量間相關程度越高,主成分分析效果越好。
缺點:
(1)主成分的解釋器含義一般多少帶有一點模糊性,不像原始變量的含義那么清楚、確切。
(2)方差小的主成分也可能含有對樣本差異的重要信息,丟棄后可能會對后續數據處理有不利影響。
PCA 與線性回歸的區別
主成分分析最小化的是投射誤差(Projected Error),而線性回歸嘗試的是最小化預測誤差。線性回歸的目的是預測結果,而主成分分析不作任何預測。
上圖中,左邊的是線性回歸的誤差(垂直於橫軸投影),右邊則是主成分分析的誤差(垂直於紅線投影)。
PCA 的變種
傳統主成分分析存在一些局限性,如數據必須放在內存中計算,不適合處理非線性數據等,因此也出現了很多 PCA 的變種。
增量主成分分析
傳統主成分分析需要將全部數據放入內存進行計算。對於很大的數據集,這種方法並不現實。我們可以將數據分成若干小分,每次只對其中的一份進行計算。這種方法就是增量主成分分析,除了可以用來處理大數據集,也方便在線處理。
隨機主成分分析
隨機主成分分析采用隨機算法,近似計算主成分。當選取的主成分數遠小於原始特征數時,可以較大程度提高運算速度。
核主成分分析
為了更好地處理非線性數據,我們可以引入非線性映射將原始數據先投射到高維特征空間,再在這個高維特征空間中實施 PCA。
PCA 的應用建議
一個常見錯誤使用主要成分分析的情況是, 將其用於減少過擬合(減少了特征的數量)。這樣做非常不好,不如嘗試正則化處理。原因在於主要成分分析只是近似地丟棄掉一些特征, 它並不考慮任何與結果變量有關的信息, 因此可能會丟失非常重要的特征。然而當我們進行正則化處理時,會考慮到結果變量,不會丟掉重要的數據。
另一個常見的錯誤是, 默認地將主要成分分析作為學習過程中的一部分, 這雖然很多時候有效果,最好還是從所有原始特征開始,只在有必要的時候(算法運行太慢或者占用太多內存)才考慮采用主要成分分析。
Python-sklearn-PCA
PCA類的主要輸入參數有以下幾個:
- n_components:這個參數可以幫我們指定希望PCA降維后的特征維度數目。
- 最常用的做法是直接指定降維到的維度數目,此時n_components是一個大於等於1的整數。
- 也可以指定主成分的方差和所占的最小比例閾值,讓PCA類自己去根據樣本特征方差來決定降維到的維度數,此時n_components是一個(0,1]之間的數。
- 還可以將參數設置為"mle", 此時PCA類會用MLE算法根據特征的方差分布情況自己去選擇一定數量的主成分特征來降維。
- 也可以用默認值,即不輸入n_components,此時n_components=min(樣本數,特征數)。
- whiten :判斷是否進行白化。所謂白化,就是對降維后的數據的每個特征進行歸一化,讓方差都為1。對於PCA降維本身來說,一般不需要白化。如果你PCA降維后有后續的數據處理動作,可以考慮白化。默認值是False,即不進行白化。
- svd_solver:即指定奇異值分解SVD的方法,由於特征分解是奇異值分解SVD的一個特例,一般的PCA庫都是基於SVD實現的。有4個可以選擇的值:{‘auto’, ‘full’, ‘arpack’, ‘randomized’}。
- randomized一般適用於數據量大,數據維度多同時主成分數目比例又較低的PCA降維,它使用了一些加快SVD的隨機算法。
- full則是傳統意義上的SVD,使用了scipy庫對應的實現。
- arpack和randomized的適用場景類似,區別是randomized使用的是scikit-learn自己的SVD實現,而arpack直接使用了scipy庫的sparse SVD實現。
- 默認是auto,即PCA類會自己去在前面講到的三種算法里面去權衡,選擇一個合適的SVD算法來降維。一般來說,使用默認值就夠了。
除了這些輸入參數外,有兩個PCA類的成員值得關注。
第一個是explained_variance_,它代表降維后的各主成分的方差值。方差值越大,則說明越是重要的主成分。
第二個是explained_variance_ratio_,它代表降維后的各主成分的方差值占總方差值的比例,這個比例越大,則越是重要的主成分。
Demo
PCA-Iris
使用 PCA 對 Iris 數據集進行降維。
Jupyter Notebook 鏈接為:PCA-Iris
PCA-MNIST
使用 PCA 對 MNIST 數據集進行圖像壓縮。
Jupyter Notebook 鏈接為:PCA-MNIST
【References】
[1] 裔雋,張懌檬,張目清等.Python機器學習實戰 [M].北京:科學技術文獻出版社,2018
[2] Andrew Ng. Machine Learning [EB/OL]. https://www.coursera.org/learn/machine-learning/home/info,2019-6-29