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

python_主成分分析(PCA)降維

主成分分析(principal component analysis)是一種常見的資料降維方法,其目的是在“資訊”損失較小的前提下,將高維的資料轉換到低維,從而減小計算量。

  PCA的本質就是找一些投影方向,使得資料在這些投影方向上的方差最大,而且這些投影方向是相互正交的。這其實就是找新的正交基的過程,計算原始資料在這些正交基上投影的方差,方差越大,就說明在對應正交基上包含了更多的資訊量。後面會證明,原始資料協方差矩陣的特徵值越大,對應的方差越大,在對應的特徵向量上投影的資訊量就越大。反之,如果特徵值較小,則說明資料在這些特徵向量上投影的資訊量很小,可以將小特徵值對應方向的資料刪除,從而達到了降維的目的。

  PCA的全部工作簡單點說,就是對原始的空間中順序地找一組相互正交的座標軸,第一個軸是使得方差最大的,第二個軸是在與第一個軸正交的平面中使得方差最大的,第三個軸是在與第1、2個軸正交的平面中方差最大的,這樣假設在N維空間中,我們可以找到N個這樣的座標軸,我們取前r個去近似這個空間,這樣就從一個N維的空間壓縮到r維的空間了,但是我們選擇的r個座標軸能夠使得空間的壓縮使得資料的損失最小。

  因此,關鍵點就在於:如何找到新的投影方向使得原始資料的“資訊量”損失最少?

1.樣本“資訊量”的衡量

  樣本的“資訊量”指的是樣本在特徵方向上投影的方差方差越大,則樣本在該特徵上的差異就越大,因此該特徵就越重要。

以《機器學習實戰》上的圖說明,在分類問題裡,樣本的方差越大,越容易將不同類別的樣本區分開。

  圖中共有3個類別的資料,很顯然,方差越大,越容易分開不同類別的點。樣本在X軸上的投影方差較大,在Y軸的投影方差較小。方差最大的方向應該是中間斜向上的方向(圖中紅線方向)。如果將樣本按照中間斜向上的方向進行對映,則只要一維的資料就可以對其進行分類,相比二維的原資料,就相當降了一維。

       在原始資料更多維的情況下,先得到一個數據變換後方差最大的方向,然後選擇與第一個方向正交的方向,該方向是方差次大的方向,如此下去,直到變換出與原特徵個數相同的新特徵或者變換出前N個特徵(在這前N個特徵包含了資料的絕大部分資訊),簡而言之,PCA是一個降維的過程,將資料對映到新的特徵,新特徵是原始特徵的線性組合。

2.計算過程因為插入公式比較麻煩,就直接採用截圖的方式

在PCA的實現過程中,對協方差矩陣奇異值分解時,能得到S矩陣(特徵值矩陣)。

實際使用

用sklearn封裝的PCA方法,做PCA的程式碼如下。PCA方法引數n_components,如果設定為整數,則n_components=k。如果將其設定為小數,則說明降維後的資料能保留的資訊。

from sklearn.decomposition import PCA
import numpy as np
from sklearn.preprocessing import StandardScaler

x=np.array([[10001,2,55], [16020,4,11], [12008,6,33], [13131,8,22]])

# feature normalization (feature scaling)
X_scaler = StandardScaler()
x = X_scaler.fit_transform(x)

# PCA
pca = PCA(n_components=0.9)# 保證降維後的資料保持90%的資訊
pca.fit(x)
pca.transform(x)

所以在實際使用PCA時,我們不需要選擇k,而是直接設定n_components為float資料。

總結

PCA主成分數量k的選擇,是一個數據壓縮的問題。通常我們直接將sklearn中PCA方法引數n_components設定為float資料,來間接解決k值選取問題。 
但有的時候我們降維只是為了觀測資料(visualization),這種情況下一般將k選擇為2或3。

引數說明: n_components:  
意義:PCA演算法中所要保留的主成分個數n,也即保留下來的特徵個數n 型別:int 或者 string,預設時預設為None,所有成分被保留。           賦值為int,比如n_components=1,將把原始資料降到一個維度。           賦值為string,比如n_components='mle',將自動選取特徵個數n,使得滿足所要求的方差百分比。

copy:

型別:bool,True或者False,預設時預設為True。

意義:表示是否在執行演算法時,將原始訓練資料複製一份。若為True,則執行PCA演算法後,原始訓練資料的值不            會有任何改變,因為是在原始資料的副本上進行運算;若為False,則執行PCA演算法後,原始訓練資料的              值會改,因為是在原始資料上進行降維計算。

whiten:

型別:bool,預設時預設為False

意義:白化,使得每個特徵具有相同的方差。關於“白化”,可參考:Ufldl教程

2、PCA物件的屬性

components_ :返回具有最大方差的成分。
explained_variance_ratio_:返回 所保留的n個成分各自的方差百分比。
n_components_:返回所保留的成分個數n。
mean_:
noise_variance_:

3、PCA物件的方法

  • fit(X,y=None)
fit()可以說是scikit-learn中通用的方法,每個需要訓練的演算法都會有fit()方法,它其實就是演算法中的“訓練”這一步驟。因為PCA是無監督學習演算法,此處y自然等於None。 fit(X),表示用資料X來訓練PCA模型。 函式返回值:呼叫fit方法的物件本身。比如pca.fit(X),表示用X對pca這個物件進行訓練。
  • fit_transform(X)
用X來訓練PCA模型,同時返回降維後的資料。 newX=pca.fit_transform(X),newX就是降維後的資料。
  • inverse_transform()
將降維後的資料轉換成原始資料,X=pca.inverse_transform(newX)
  • transform(X)
將資料X轉換成降維後的資料。當模型訓練好後,對於新輸入的資料,都可以用transform方法來降維。 此外,還有get_covariance()、get_precision()、get_params(deep=True)、score(X, y=None)等方法,以後用到再補充吧。

3.python實現

 下面介紹Sklearn中PCA降維的方法。
        匯入方法:

  1. from sklearn.decomposition import PCA  
        呼叫函式如下,其中n_components=2表示降低為2維。
  1. pca = PCA(n_components=2)  
        例如下面程式碼進行PCA降維操作:
  1. import numpy as np  
  2. from sklearn.decomposition import PCA  
  3. X = np.array([[-1, -1], [-2, -1], [-3, -2], [11], [21], [32]])  
  4. pca = PCA(n_components=2)  
  5. print pca  
  6. pca.fit(X)  
  7. print(pca.explained_variance_ratio_)   
        輸出結果如下所示:
  1. PCA(copy=True, n_components=2, whiten=False)  
  2. 0.992442910.00755711]  
        再如載入boston資料集,總共10個特徵,降維成兩個特徵:
  1. #載入資料集
  2. from sklearn.datasets import load_boston  
  3. d = load_boston()  
  4. x = d.data  
  5. y = d.target  
  6. print x[:10]  
  7. print u'形狀:', x.shape  
  8. #降維
  9. import numpy as np  
  10. from sklearn.decomposition import PCA  
  11. pca = PCA(n_components=2)  
  12. newData = pca.fit_transform(x)  
  13. print u'降維後資料:'
  14. print newData[:4]  
  15. print u'形狀:', newData.shape  
        輸出結果如下所示,降低為2維資料。
  1. [[  6.32000000e-031.80000000e+012.31000000e+000.00000000e+00
  2.     5.38000000e-016.57500000e+006.52000000e+014.09000000e+00
  3.     1.00000000e+002.96000000e+021.53000000e+013.96900000e+02
  4.     4.98000000e+00]  
  5.  [  2.73100000e-020.00000000e+007.07000000e+000.00000000e+00
  6.     4.69000000e-016.42100000e+007.89000000e+014.96710000e+00
  7.     2.00000000e+002.42000000e+021.78000000e+013.96900000e+02
  8.     9.14000000e+00]  
  9.  [  2.72900000e-020.00000000e+007.07000000e+000.00000000e+00
  10.     4.69000000e-017.18500000e+006.11000000e+014.96710000e+00
  11.     2.00000000e+002.42000000e+021.78000000e+013.92830000e+02
  12.     4.03000000e+00]  
  13.  [  3.23700000e-020.00000000e+002.18000000e+000.00000000e+00
  14.     4.58000000e-016.99800000e+004.58000000e+016.06220000e+00
  15.     3.00000000e+002.22000000e+021.87000000e+013.94630000e+02
  16.     2.94000000e+00]]  
  17. 形狀: (506L13L)  
  18. 降維後資料:  
  19. [[-119.818212835.56072403]  
  20.  [-168.88993091  -10.11419701]  
  21.  [-169.31150637  -14.07855395]  
  22.  [-190.2305986   -18.29993274]]  
  23. 形狀: (506L2L)