主成分分析(PCA)的使用
PCA 是一種通過分解特征矩陣來降維的方法。主要適用的應(yīng)用場景如下:
非監(jiān)督式類型的數(shù)據(jù)集。它是一種非監(jiān)督式的降維方法,因此適用于不帶有標(biāo)簽的數(shù)據(jù)集;而對于帶有標(biāo)簽的數(shù)據(jù)集則可以采用 LDA;
根據(jù)方差自主控制特征數(shù)量。最大的主成分的數(shù)量≤特征的數(shù)量,這意味著,PCA 也可以輸出數(shù)量完全相同的特征,具體取決于選擇特征中解釋的方差比例;
數(shù)據(jù)量較大的數(shù)據(jù)集。數(shù)據(jù)量大包括數(shù)據(jù)記錄多和數(shù)據(jù)維度多兩種情況,PCA 對大型數(shù)據(jù)集的處理效率較高。
PCA 的實現(xiàn)流程:
按照數(shù)據(jù)集的 n 維特征矩陣,輸入原數(shù)據(jù),結(jié)構(gòu)維(m,n),找出原本 n 個特征向量構(gòu)成的 n 維空間 V;
決定降維后的特征數(shù)量 k;
通過找一組相互正交的坐標(biāo)軸,找出 n 個新的特征向量,以及他們構(gòu)成的新 n 維空間 V;
找出原始數(shù)據(jù)在新特征空間 V 中的 n 個新特征向量上對應(yīng)的值,即“將數(shù)據(jù)映射到新空間中”;
選取前 k 個信息量最大的特征,刪掉沒有被選中的特征,成功將 n 維空間降為 k 維。
流程中的關(guān)鍵是需要決定降維的特征數(shù)量 k,以及找到一組相互正交的坐標(biāo)軸。這里涉及的數(shù)理知識有部分細(xì)節(jié)我還不太理解透徹。數(shù)理推導(dǎo)建議可以看這部分《如何理解主元分析(PCA)?》
從方差過濾中知道,如果一個特征的方差很小,則意味著這個 特征上很可能有大量取值都相同(比如 90% 都是 1,只有 10% 是 0,甚至 100% 是 1),那這一個特征的取值對樣本來說就沒有區(qū)分度,這種特征就不帶有有效信息。也就是說方差越大,特征上帶有的信息量越大。因此,在降維中,PCA 使用的信息量衡量指標(biāo),就是樣本方差。計算公式為:
Var 表示一個特征的方差,n 代表樣本量,Xi 代表一個特征中的每個樣本取值,Xhat 代表這一列樣本的均值。
PCA Python演示
#?PCA參數(shù)
class?sklearn.decomposition.PCA(n_components=None,?copy=True,?whiten=False,?svd_solver='auto',?tol=0.0,?iterated_power='auto',?random_state=None)
主要說下 n_components 參數(shù)。這個參數(shù)可以指定 PCA 降維后期望的特征維度數(shù)目。常規(guī)來說,要想先看看數(shù)據(jù)的散點圖分布,可以 n_components=2,之前《使用 PCA 降維可視化,了解數(shù)據(jù)特征分布》有演示。
這里有 2 種方式,第 1 種是指定主成分的方差和所占的最小比例閾值,讓 PCA 類根據(jù)樣本特征方差來決定降維到的維度數(shù),此時n_components 是一個(0,1]之間的數(shù);并且讓參數(shù)svd_solver =='full'。比如說,如果我們希望保留 97% 的信息量,就可以輸入n_components = 0.97,PCA會自動選出能夠讓保留的信息量超過97%的特征數(shù)量。第 2 種就是文章開始說的方差衡量指標(biāo)pca_line.explained_variance_ratio_?,用來查看降維后每個新特征向量所占信息量占原始數(shù)據(jù)總信息量的百分比。又叫做可解釋方差貢獻率。
代碼演示:
#導(dǎo)入相關(guān)庫
import?matplotlib.pyplot?as?plt
from?sklearn.datasets?import?load_iris?
from?sklearn.decomposition?import?PCA
plt.rcParams['font.family']?=?['Arial?Unicode?MS']
#獲取skearn庫鳶尾花數(shù)據(jù)集,鳶尾花四維數(shù)組
iris?=?load_iris()
y?=?iris.target
X?=?iris.data?
X[0:5]
array([[5.1,?3.5,?1.4,?0.2],
???????[4.9,?3.?,?1.4,?0.2],
???????[4.7,?3.2,?1.3,?0.2],
???????[4.6,?3.1,?1.5,?0.2],
???????[5.?,?3.6,?1.4,?0.2]])
#調(diào)用PCA
pca?=?PCA(n_components=2)?
pca?=?pca.fit(X)
X_dr?=?pca.transform(X)
X_dr[0:5]
array([[-2.68412563,??0.31939725],
???????[-2.71414169,?-0.17700123],
???????[-2.88899057,?-0.14494943],
???????[-2.74534286,?-0.31829898],
???????[-2.72871654,??0.32675451]])
import?numpy?as?np
pca_line?=?PCA().fit(X)?
plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))?
plt.xticks([1,2,3,4])?
plt.xlabel("降維后特征數(shù)量")?
plt.ylabel("可解釋方差貢獻率")
plt.show()

累積可解釋方差貢獻率曲線是一條以降維后保留的特征個數(shù)為橫坐標(biāo),降維后新特征矩陣捕捉到的可解釋方差貢獻率為縱坐標(biāo)的曲線。圖中表示 4 個特征是 100%,2 個特征大概在 98%。
#?保留97%信息量,PCA會自動選出能夠讓保留的信息量超過97%的特征數(shù)量。
pca_f?=?PCA(n_components=0.97,svd_solver="full")
pca_f?=?pca_f.fit(X)
X_f?=?pca_f.transform(X)
pca_f.explained_variance_ratio_
array([0.92461872,?0.05306648])