【火爐煉AI】機器學習053-數(shù)據(jù)降維絕招-PCA和核PCA
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
主成分分析(Principal Component Analysis, PCA)可以說是數(shù)據(jù)降維的絕招巢掺,不僅在人口統(tǒng)計學,數(shù)量地理學逞壁,分子動力學模擬猎莲,數(shù)學建模等領域有著重要的應用绍弟,而且在機器學習領域,PCA也是非常常用的一種數(shù)據(jù)降維方法著洼。
首先來理解什么叫數(shù)據(jù)降維:假設有一個項目樟遣,要從外觀上來判斷某個人是男人還是女人,我們可以提取各種各樣的特征郭脂,比如身高年碘,一般而言澈歉,男人的身高要比女人高展鸡,但也有特例,比如頭發(fā)長度埃难,有無胡須莹弊,臉型,衣服顏色涡尘,身材忍弛,體重,膚色考抄,BMI指標细疚。。川梅。疯兼。等等,如果有需要贫途,你可以為這個項目提取幾百甚至幾千個特征吧彪,假如你一口氣提取了200個特征,每一個特征都反映了一個人的某一個方面的信息丢早,那么姨裸,用機器學習的方法對這200個特征進行建模秧倾,并用訓練集來訓練,則會非常耗時傀缩,而且得到的模型結構龐大那先,故而我們需要減少特征數(shù)量,但是我們不希望減少特征數(shù)量的同時把重要的信息給弄丟了扑毡。將特征數(shù)量從幾百上千降低到幾十的過程就是數(shù)據(jù)降維胃榕。
在上面這個項目中杭措,有很多特征之間是由關聯(lián)的担巩,比如BMI指標就是身高/體重的平方车吹,那么很明顯蜀铲,BMI指標一個特征就包括了身高和體重兩個特征今阳,BMI和這兩個指標之間具有非常強的相關性驮瞧。同理拷况,200個特征之間也可能有很多變量之間具有相關性肌稻,所以這些相關特征之間所反映的信息是一樣的惯驼,PCA的作用就是對所有的這200個特征蹲嚣,去除相關性非常強的特征,建立盡可能少的新特征祟牲,使得這些新特征之間是兩兩不相關隙畜,并且這些新特征在反應項目的信息方面會盡可能保持原有的信息。
關于PCA的理論推導和更深層次的數(shù)學邏輯说贝,請參考博文PCA算法
1. 用PCA對數(shù)據(jù)集降維
為了看到降維效果议惰,此處我們用隨機數(shù)自動生成一個數(shù)據(jù)集,前兩個特征向量都是隨機數(shù)乡恕,后三個特征向量是前兩個特征計算組合而來言询。如下為代碼
# 假如某個項目有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
很多時候运杭,我們要查看數(shù)據(jù)集中各特征向量之間的相關性,如下
# 將這些特征組合成數(shù)據(jù)集
dataset_X=np.c_[f1,f2,f3,f4,f5]
# 計算各特征列之間的相關系數(shù)
df=pd.DataFrame(dataset_X,columns=['f1','f2','f3','f4','f5'])
print(df.corr())
-------------------------------------輸---------出--------------------------------
f1 f2 f3 f4 f5
f1 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
--------------------------------------------完-------------------------------------
可以明顯看出函卒,數(shù)據(jù)集中有很多特征之間具有比較強的相關性辆憔,比如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) # 可以理解成該特征的重要性,后面三個數(shù)字非常小沪蓬,即特征不重要
-------------------------------------輸---------出--------------------------------
[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的表示重要特征跷叉,要保留逸雹,F(xiàn)alse則刪除
-------------------------------------輸---------出--------------------------------
[ True True False False False]
--------------------------------------------完-------------------------------------
一旦我們通過PCA進行了降維营搅,就需要將原來的高維數(shù)據(jù)集轉換為低維數(shù)據(jù)集,然后用低維數(shù)據(jù)集來建模
useful_features_num=np.sum(useful_features) # 計算True的個數(shù)
# 進行PCA降維之后的新數(shù)據(jù)集為:
pca.n_components=useful_features_num # 即設置PCA的新特征數(shù)量為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的優(yōu)點和缺點:
優(yōu)點:1梆砸,對數(shù)據(jù)進行降維處理转质,我們可以對新求出的“主元”向量的重要性進行排序,根據(jù)需要取前面最重要的部分帖世,將后面的維數(shù)省去休蟹,可以達到降維從而簡化模型或是對數(shù)據(jù)進行壓縮的效果。同時最大程度的保持了原有數(shù)據(jù)的信息日矫。
2赂弓,完全無參數(shù)限制,處理結果只與數(shù)據(jù)相關哪轿,而與用戶無關:在PCA的計算過程中完全不需要人為的設定參數(shù)或是根據(jù)任何經(jīng)驗模型對計算進行干預盈魁,最后的結果只與數(shù)據(jù)相關,與用戶是獨立的窃诉。
缺點:1杨耙,PCA以線性方式工作,如果數(shù)據(jù)集不是以線性方式組織的飘痛,那么PCA效果就很差珊膜,此時,我們可以根據(jù)先驗知識對數(shù)據(jù)預先進行非線性轉換宣脉,將非線性數(shù)據(jù)集轉換到相信空間中车柠,這種分析方式叫做Kernel-PCA,也叫核PCA脖旱,它解決了PCA只能處理線性數(shù)據(jù)集的缺點堪遂,又結合一些先驗知識的約束介蛉,是目前比較流行的方法萌庆。
2,有的數(shù)據(jù)集的分布并不滿足高斯分布币旧,在非高斯分布的情況下践险,PCA得到的主要特征可能并不是最優(yōu)的,在尋找主要特征時不能將方差作為衡量重要性的標準吹菱,此時要根據(jù)數(shù)據(jù)的分布情況選擇合適的描述完全分布的變量巍虫,根據(jù)一定的概率分布公式來計算兩個特征數(shù)據(jù)分布的相關性,這種分析方式叫獨立主元分解(ICA)鳍刷。
可以參考博文: 主成分分析(Principal components analysis)-最小平方誤差解釋
2. 用核PCA對數(shù)據(jù)集降維
前面提到占遥,PCA雖好,但也不是放之四海而皆準输瓜,對于非線性方式組織的數(shù)據(jù)集瓦胎,PCA方法可能效果較差芬萍,此時需要用核PCA方法來解決。
我們來看一個典型的非線性方式組織的數(shù)據(jù)集:
# 準備數(shù)據(jù)集
from sklearn.datasets import make_circles
dataset_X,dataset_y=make_circles(n_samples=500,factor=0.2,noise=0.04)
該數(shù)據(jù)集的二維分布圖為:
那么如果我們用普通PCA對這個數(shù)據(jù)集進行降維搔啊,會得到什么樣的結果了柬祠?
# 如果用普通的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降維前后有啥區(qū)別
如果用核PCA來降維,能夠將數(shù)據(jù)集變成線性可分负芋,如下:
# 用核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')
很明顯莽龟,得到的新數(shù)據(jù)集便是線性可分。
話說锨天,怎么經(jīng)過核PCA降維之后轧房,原先的2個特征怎么增加到465個特征?降維還是增維绍绘?呵呵奶镶。
那么從這個核PCA得到的新數(shù)據(jù)集能夠返回到原來的數(shù)據(jù)集了?
# 如何從Kernel PCA得到的數(shù)據(jù)集反向計算出原始的數(shù)據(jù)集
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')
可以看出陪拘,恢復之后的數(shù)據(jù)集的分布情況和原始數(shù)據(jù)集的分布情況相同厂镇。
########################小**********結###############################
1,對數(shù)據(jù)集進行降維可以很好地解決特征數(shù)太多導致的訓練太耗時左刽,模型結構臃腫的問題捺信,降維方法有很多種,其中的PCA降維方式可以解決具有線性方式的數(shù)據(jù)集欠痴,而核PCA方法可以對具有非線性方式組織的數(shù)據(jù)集進行降維迄靠。
#################################################################
注:本部分代碼已經(jīng)全部上傳到(我的github)上,歡迎下載喇辽。
參考資料:
1, Python機器學習經(jīng)典實例掌挚,Prateek Joshi著,陶俊杰菩咨,陳小莉譯