PCA主成分分析算法(Principal Components Analysis)是一種最常用的降維算法。能夠以較低的信息損失(以樣本間分布方差衡量)減少特徵數量。
PCA算法可以幫助分析樣本中分布差異最大的成分(主成分),有助於數據可視化(降低到2維或3維後可以用散點圖可視化),有時候還可以起到降低樣本中的噪聲的作用(丟失的信息有部分是噪聲)。
公眾號後臺回復關鍵詞:源碼。獲取本文全部代碼和對應插圖。
一,PCA算法的直覺理解從直覺上看,PCA主成分分析類似於依次尋找一群樣本點的各個位置差異最大的方向長軸。
假定把一個人身上的所有細胞看成一個一個的樣本點。這些樣本點可以用3個坐標來表示,從左到右為x方向,從前到後為y方向,從下到上為z方向。
那麼它們的第一個主成分是什麼呢?第一個主成分對應的長軸是沿著人的腳到頭的方向,也就是通常的上下方向,即z方向。這個方向是最主要的長軸。這些樣本點的位置差異基本上70%以上來自於這個方向上的差異。
它們的第二個主成分是什麼呢?第二個主成分對應的方向是沿著人的左臂到右臂的方向,也就通常的左右方向,即y方向。這個方向和第一個主成分長軸垂直,這些樣本點的位置差異大概有20%左右來自這個方向上的差異。
它們的第三個主成分是什麼呢?第三個主成分方向是沿著人的前胸到後背的方向,也就是通常的前後方向,即x方向。這個方向和前兩個主成分長軸垂直,樣本點的位置差異有一般只有不到10%來自這個方向的差異,當然,有些身材比較圓潤的同學除外。
現在,如果要將這些樣本點的坐標減少到用2個來表示,並儘可能多的保留樣本點之間位置差異的信息,那麼,顯然,應該保留第一個主成分坐標和第二個主成分坐標。
現在,假定這個人躺在一個斜的躺椅上,那麼現在這些樣本點的第一主成分顯然不再是從下到上的z方向。我們應該將我們的坐標系作一個旋轉,讓z軸和斜著的躺椅方向一致,這個新的z方向是這些樣本點的第一主成分方向。類似地,也需要旋轉x軸和y軸得到新的第二主成分方向和第三主成分方向。
這個旋轉舊坐標系以找到主成分方向的過程就是PCA主成分分析。
二,PCA算法的數學說明PCA主成分分析(Principal Components Analysis)是一種通過正交線性組合方式,最大化保留樣本間方差的降維方法。
用幾何觀點來看,PCA主成分分析方法可以看成通過正交變換,對坐標系進行旋轉和平移,並保留樣本點投影坐標方差最大的前幾個新的坐標。
這裡有幾個關鍵詞需要說明:
降維:將樣本原來的m維特徵用更少的k個特徵取代。降維算法可以理解成一種數據壓縮方法,它可能會丟失一些信息。
正交線性組合:k個新特徵是通過對m個舊特徵進行線性組合產生的,並且k個線性組合的係數向量為單位向量,且彼此相互正交。
最大化保留樣本間方差:第1個主成分特徵最大化樣本間特徵方差,第2個主成分特徵在滿足與第1個主成分正交約束條件下最大化樣本間特徵方差,……
三,PCA算法的調包範例下面的範例我們調用sklearn中的PCA降維算法接口,對波士頓房價數據集進行降維(13維降到7維)。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets
boston = datasets.load_boston()
dfdata = pd.DataFrame(boston.data,columns = boston.feature_names)
dfdata.head()
# 不同特徵取值範圍相差較大,我們首先進行標準正態歸一化
# 歸一化的結果作為 PCA降維的輸入
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(dfdata.values)
X_input = scaler.transform(dfdata.values)
# 我們的輸入有506個樣本,13維特徵
print(X_input.shape)
輸出如下:
(506, 13)
# 應用PCA進行降維
from sklearn.decomposition import PCA
pca = PCA(n_components=7)
pca.fit(X_input)
X_output = pca.transform(X_input)
# 降維後,只有7維特徵
print(X_output.shape)
輸出如下:
(506, 7)
# 查看各個主成分對應的方差大小和佔全部方差的比例
# 可以看到前7個主成分已經解釋了樣本分布的90%的差異了。
print("explained_variance:")
print(pca.explained_variance_)
print("explained_variance_ratio:")
print(pca.explained_variance_ratio_)
print("total explained variance ratio of first 7 principal components:")
print(sum(pca.explained_variance_ratio_))
輸出如下:
#可視化各個主成分貢獻的方差
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import matplotlib.pyplot as plt
plt.figure()
plt.plot(np.arange(1,8),pca.explained_variance_,linewidth=2)
plt.xlabel('components_n', fontsize=16)
plt.ylabel('explained_variance_', fontsize=16)
plt.show()
# 查看降維對應的正交變換矩陣,即各個投影向量
W = pca.components_
# 驗證正交關係
np.round(np.dot(W,np.transpose(W)),6)
# 對降維後的數據的前兩維進行散點圖可視化
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
plt.scatter(X_output[:,0],X_output[:,1])
plt.xlabel("components_1")
plt.ylabel("components_2")
plt.show()
前方高數提醒。
下面進行PCA算法的數學原理推演,證明第k個主成分投影向量恰好是樣本的協方差矩陣的第k大特徵值對應的特徵向量。
下面的推演會用到高等數學中的一些線性代數知識和微積分知識。
沒有相關數學基礎的同學可以跳過,在實踐中只要掌握PCA算法的直覺概念和調包使用方法,基本就夠用了。
公眾號後臺回復關鍵詞:源碼。獲取本文全部代碼和對應插圖。