【火炉炼AI】机器学习053-数据降维绝招-PCA和核PCA
【火爐煉AI】機器學習053-數據降維絕招-PCA和核PCA
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
主成分分析(Principal Component Analysis, PCA)可以說是數據降維的絕招,不僅在人口統計學,數量地理學,分子動力學模擬,數學建模等領域有著重要的應用,而且在機器學習領域,PCA也是非常常用的一種數據降維方法。
首先來理解什么叫數據降維:假設有一個項目,要從外觀上來判斷某個人是男人還是女人,我們可以提取各種各樣的特征,比如身高,一般而言,男人的身高要比女人高,但也有特例,比如頭發長度,有無胡須,臉型,衣服顏色,身材,體重,膚色,BMI指標。。。。等等,如果有需要,你可以為這個項目提取幾百甚至幾千個特征,假如你一口氣提取了200個特征,每一個特征都反映了一個人的某一個方面的信息,那么,用機器學習的方法對這200個特征進行建模,并用訓練集來訓練,則會非常耗時,而且得到的模型結構龐大,故而我們需要減少特征數量,但是我們不希望減少特征數量的同時把重要的信息給弄丟了。將特征數量從幾百上千降低到幾十的過程就是數據降維。
在上面這個項目中,有很多特征之間是由關聯的,比如BMI指標就是身高/體重的平方,那么很明顯,BMI指標一個特征就包括了身高和體重兩個特征,BMI和這兩個指標之間具有非常強的相關性。同理,200個特征之間也可能有很多變量之間具有相關性,所以這些相關特征之間所反映的信息是一樣的,PCA的作用就是對所有的這200個特征,去除相關性非常強的特征,建立盡可能少的新特征,使得這些新特征之間是兩兩不相關,并且這些新特征在反應項目的信息方面會盡可能保持原有的信息。
關于PCA的理論推導和更深層次的數學邏輯,請參考博文PCA算法
1. 用PCA對數據集降維
為了看到降維效果,此處我們用隨機數自動生成一個數據集,前兩個特征向量都是隨機數,后三個特征向量是前兩個特征計算組合而來。如下為代碼
# 假如某個項目有5個特征,這五個特征分別為: f1=np.random.normal(size=250) f2=np.random.normal(size=250) # 后面的三個特征是前面兩個特征演變而來,即與前面兩特征具有很強的相關性 f3=2*f1+3*f2 f4=4*f1-f2 f5=f3+2*f4很多時候,我們要查看數據集中各特征向量之間的相關性,如下
# 將這些特征組合成數據集 dataset_X=np.c_[f1,f2,f3,f4,f5] # 計算各特征列之間的相關系數 df=pd.DataFrame(dataset_X,columns=['f1','f2','f3','f4','f5']) print(df.corr())-------------------------------------輸---------出--------------------------------
f1 f2 f3 f4 f5f1 1.000000 -0.002496 0.528931 0.966354 0.994370
f2 -0.002496 1.000000 0.847342 -0.259627 0.103485
f3 0.528931 0.847342 1.000000 0.292844 0.615884
f4 0.966354 -0.259627 0.292844 1.000000 0.933656
f5 0.994370 0.103485 0.615884 0.933656 1.000000
--------------------------------------------完-------------------------------------
可以明顯看出,數據集中有很多特征之間具有比較強的相關性,比如f1-f5,f1-f4等。
所以我們可以用PCA來進行降維:
# 可以看出f1-f5,f1-f4,f2-f3等之間具有強相關性,故而可以用PCA降維 from sklearn import decomposition pca=decomposition.PCA() pca.fit(dataset_X) # 用PCA降維 # 打印降維后的新特征 variances=pca.explained_variance_ print(variances) # 可以理解成該特征的重要性,后面三個數字非常小,即特征不重要-------------------------------------輸---------出--------------------------------
[1.15552796e+02 1.14453854e+01 3.08872295e-31 8.39043564e-32
1.18268234e-32]
--------------------------------------------完-------------------------------------
# 故而可以為重要性設置一個閾值,小于該閾值的認為該特征不重要,可刪除 thresh=0.8 useful_features=variances>thresh print(useful_features) # 標記為True的表示重要特征,要保留,False則刪除-------------------------------------輸---------出--------------------------------
[ True True False False False]
--------------------------------------------完-------------------------------------
一旦我們通過PCA進行了降維,就需要將原來的高維數據集轉換為低維數據集,然后用低維數據集來建模
useful_features_num=np.sum(useful_features) # 計算True的個數# 進行PCA降維之后的新數據集為: pca.n_components=useful_features_num # 即設置PCA的新特征數量為n_components new_dataset_X=pca.fit_transform(dataset_X) print('before PCA, dataset shape: ', dataset_X.shape) print('after PCA, dataset shape: ', new_dataset_X.shape)-------------------------------------輸---------出--------------------------------
before PCA, dataset shape: (250, 5)
after PCA, dataset shape: (250, 2)
--------------------------------------------完-------------------------------------
PCA的優點和缺點:
優點:1,對數據進行降維處理,我們可以對新求出的“主元”向量的重要性進行排序,根據需要取前面最重要的部分,將后面的維數省去,可以達到降維從而簡化模型或是對數據進行壓縮的效果。同時最大程度的保持了原有數據的信息。
2,完全無參數限制,處理結果只與數據相關,而與用戶無關:在PCA的計算過程中完全不需要人為的設定參數或是根據任何經驗模型對計算進行干預,最后的結果只與數據相關,與用戶是獨立的。
缺點:1,PCA以線性方式工作,如果數據集不是以線性方式組織的,那么PCA效果就很差,此時,我們可以根據先驗知識對數據預先進行非線性轉換,將非線性數據集轉換到相信空間中,這種分析方式叫做Kernel-PCA,也叫核PCA,它解決了PCA只能處理線性數據集的缺點,又結合一些先驗知識的約束,是目前比較流行的方法。
2,有的數據集的分布并不滿足高斯分布,在非高斯分布的情況下,PCA得到的主要特征可能并不是最優的,在尋找主要特征時不能將方差作為衡量重要性的標準,此時要根據數據的分布情況選擇合適的描述完全分布的變量,根據一定的概率分布公式來計算兩個特征數據分布的相關性,這種分析方式叫獨立主元分解(ICA)。
可以參考博文: 主成分分析(Principal components analysis)-最小平方誤差解釋
2. 用核PCA對數據集降維
前面提到,PCA雖好,但也不是放之四海而皆準,對于非線性方式組織的數據集,PCA方法可能效果較差,此時需要用核PCA方法來解決。
我們來看一個典型的非線性方式組織的數據集:
# 準備數據集 from sklearn.datasets import make_circles dataset_X,dataset_y=make_circles(n_samples=500,factor=0.2,noise=0.04)該數據集的二維分布圖為:
那么如果我們用普通PCA對這個數據集進行降維,會得到什么樣的結果了?
# 如果用普通的PCA來降維 from sklearn.decomposition import PCA pca = PCA() dataset_X_pca = pca.fit_transform(dataset_X) print(dataset_X_pca.shape) visual_2D_dataset(dataset_X_pca,dataset_y,'PCA transformed dataset') # 從圖中幾乎看不出PCA降維前后有啥區別如果用核PCA來降維,能夠將數據集變成線性可分,如下:
# 用核PCA方法來降維 from sklearn.decomposition import KernelPCA kernel_pca = KernelPCA(kernel="rbf", fit_inverse_transform=True, gamma=10) X_kernel_pca = kernel_pca.fit_transform(dataset_X) print(X_kernel_pca.shape) # 2維特征變成了465維,降維?增維? visual_2D_dataset(X_kernel_pca[:,:2],dataset_y,'Kernel PCA transformed dataset')很明顯,得到的新數據集便是線性可分。
話說,怎么經過核PCA降維之后,原先的2個特征怎么增加到465個特征?降維還是增維?呵呵。
那么從這個核PCA得到的新數據集能夠返回到原來的數據集了?
# 如何從Kernel PCA得到的數據集反向計算出原始的數據集 dataset_X_inverse = kernel_pca.inverse_transform(X_kernel_pca) print(dataset_X_inverse.shape) visual_2D_dataset(dataset_X_inverse,dataset_y,'inversed dataset_X from KernelPCA')可以看出,恢復之后的數據集的分布情況和原始數據集的分布情況相同。
########################小**********結###############################
1,對數據集進行降維可以很好地解決特征數太多導致的訓練太耗時,模型結構臃腫的問題,降維方法有很多種,其中的PCA降維方式可以解決具有線性方式的數據集,而核PCA方法可以對具有非線性方式組織的數據集進行降維。
#################################################################
注:本部分代碼已經全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機器學習經典實例,Prateek Joshi著,陶俊杰,陳小莉譯
總結
以上是生活随笔為你收集整理的【火炉炼AI】机器学习053-数据降维绝招-PCA和核PCA的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机启动时滴滴两声,电脑开机时出现滴滴
- 下一篇: 声明式导航编程式导航