機器學習實戰之PCA
一,引言
降維是對數據高維度特征的一種預處理方法。降維是將高維度的數據保留下最重要的一些特征,去除噪聲和不重要的特征,從而實現提升數據處理速度的目的。在實際的生產和應用中,降維在一定的信息損失範圍內,可以為我們節省大量的時間和成本。降維也成為了應用非常廣泛的數據預處理方法。
降維具有如下一些優點:
(1)使得數據集更易使用
(2)降低算法的計算開銷
(3)去除噪聲
(4)使得結果容易理解
PCA(principal Component Analysis),即主成分分析方法,是一種使用最廣泛的數據壓縮算法。在PCA中,數據從原來的坐標系轉換到新的坐標系,由數據本身決定。轉換坐標系時,以方差最大的方向作為坐標軸方向,因為數據的最大方差給出了數據的最重要的信息。第一個新坐標軸選擇的是原始數據中方差最大的方法,第二個新坐標軸選擇的是與第一個新坐標軸正交且方差次大的方向。重復該過程,重復次數為原始數據的特征維數。
通過這種方式獲得的新的坐標系,我們發現,大部分方差都包含在前面幾個坐標軸中,後面的坐標軸所含的方差幾乎為0,。於是,我們可以忽略余下的坐標軸,只保留前面的幾個含有絕不部分方差的坐標軸。事實上,這樣也就相當於只保留包含絕大部分方差的維度特征,而忽略包含方差幾乎為0的特征維度,也就實現了對數據特征的降維處理。
那麽,我們如何得到這些包含最大差異性的主成分方向呢?事實上,通過計算數據矩陣的協方差矩陣,然後得到協方差矩陣的特征值及特征向量,選擇特征值最大(也即包含方差最大)的N個特征所對應的特征向量組成的矩陣,我們就可以將數據矩陣轉換到新的空間當中,實現數據特征的降維(N維)。
既然,說到了協方差矩陣,那麽這裏就簡單說一下方差和協方差之間的關系,首先看一下均值,方差和協方差的計算公式:
由上面的公式,我們可以得到一下兩點區別:
(1)方差的計算公式,我們知道方差的計算是針對一維特征,即針對同一特征不同樣本的取值來進行計算得到;而協方差則必須要求至少滿足二維特征。可以說方差就是協方差的特殊情況。
(2)方差和協方差的除數是n-1,這樣是為了得到方差和協方差的無偏估計。具體推導過程可以參見博文:http://blog.csdn.net/maoersong/article/details/21823397
二,PCA算法實現
將數據轉換為只保留前N個主成分的特征空間的偽代碼如下所示:
去除平均值 計算協方差矩陣 計算協方差矩陣的特征值和特征向量 將特征值排序 保留前N個最大的特征值對應的特征向量 將數據轉換到上面得到的N個特征向量構建的新空間中(實現了特征壓縮)
具體的代碼為:
#導入numpy庫 from numpy import * #解析文本數據函數 #@filename 文件名txt #@delim 每一行不同特征數據之間的分隔方式,默認是tab鍵‘\t‘ def loadDataSet(filename,delim=‘\t‘) #打開文本文件 fr=open(filename) #對文本中每一行的特征分隔開來,存入列表中,作為列表的某一行 #行中的每一列對應各個分隔開的特征 stringArr=[line.strip().split(delim) for line in fr.readlines()] #利用map()函數,將列表中每一行的數據值映射為float型 datArr=[map(float.line)for line in stringArr] #將float型數據值的列表轉化為矩陣返回 return mat(datArr) #pca特征維度壓縮函數 #@dataMat 數據集矩陣 #@topNfeat 需要保留的特征維度,即要壓縮成的維度數,默認4096 def pca(dataMat,topNfeat=4096): #求數據矩陣每一列的均值 meanVals=mean(dataMat,axis=0) #數據矩陣每一列特征減去該列的特征均值 meanRemoved=dataMat-meanVals #計算協方差矩陣,除數n-1是為了得到協方差的無偏估計 #cov(X,0) = cov(X) 除數是n-1(n為樣本個數) #cov(X,1) 除數是n covMat=cov(meanRemoved,rowvar=0) #計算協方差矩陣的特征值及對應的特征向量 #均保存在相應的矩陣中 eigVals,eigVects=linalg.eig(mat(conMat)) #sort():對特征值矩陣排序(由小到大) #argsort():對特征值矩陣進行由小到大排序,返回對應排序後的索引 eigValInd=argsort(eigVals) #從排序後的矩陣最後一個開始自下而上選取最大的N個特征值,返回其對應的索引 eigValInd=eigValInd[:-(topNfeat+1):-1] #將特征值最大的N個特征值對應索引的特征向量提取出來,組成壓縮矩陣 redEigVects=eigVects[:,eigValInd] #將去除均值後的數據矩陣*壓縮矩陣,轉換到新的空間,使維度降低為N lowDDataMat=meanRemoved*redEigVects #利用降維後的矩陣反構出原數據矩陣(用作測試,可跟未壓縮的原矩陣比對) reconMat=(lowDDataMat*redEigVects.T)+meanVals #返回壓縮後的數據矩陣即該矩陣反構出原始數據矩陣 return lowDDataMat,reconMat
上述降維過程,首先根據數據矩陣的協方差的特征值和特征向量,得到最大的N個特征值對應的特征向量組成的矩陣,可以稱之為壓縮矩陣;得到了壓縮矩陣之後,將去均值的數據矩陣乘以壓縮矩陣,就實現了將原始數據特征轉化為新的空間特征,進而使數據特征得到了壓縮處理。
當然,我們也可以根據壓縮矩陣和特征均值,反構得到原始數據矩陣,通過這樣的方式可以用於調試和驗證。
下圖是通過matplotlib將原始數據點(三角形點)和第一主成分點(圓形點)繪制出來的結果。顯然,第一主成分點占據著數據最重要的信息。
import matplotlib import matplotlib.pyplot as plt fig=plt.figure() ax=fig.add_subplot(lll) #三角形表示原始數據點 ax.scatter(dataMat[:,0].flatten().A[0],dataMat[:,1].flatten().A[0], marker=‘^‘,s=90) #圓形點表示第一主成分點,點顏色為紅色 ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0]\, marker=‘o‘,s=90,c=‘red‘)
三,示例:PCA對半導體數據進行降維
我們知道,像集成電路這樣的半導體,成本非常昂貴。如果能在制造過程中盡早和盡快地檢測出是否出現瑕疵,將可能為企業節省大量的成本和時間。那麽,我們在面對大規模和高維度數據集時,顯然計算損耗會很大,無疑會非常耗時。所以,如果利用PCA等降維技術將高維的數據特征進行降維處理,保留那些最重要的數據特征,舍棄那些可以忽略的特征,將大大加快我們的數據處理速度和計算損耗,為企業節省不小的時間和成本。
1 數據缺失值的問題
顯然,數據集中可能會包含很多缺失值,這些缺失值是以NaN進行標識的。那麽如何對待這些缺失值呢?如果存在大量的樣本存在缺失值,顯然選擇將這些有缺失值得樣本丟棄不可取;此外,由於並不知道這些值的意義,選擇將缺失值替換為0也不是一個很好的決定。所以,這裏我們選擇將數據集中的特征缺失值,用數據集中該維度所有非NaN特征的均值進行替換。相比之下,采用均值替換的方法在這裏是一個相對較好的選擇。
#缺失值處理函數 def replaceNaNWithMean(): #解析數據 datMat=loadDataSet(‘secom.data‘,‘ ‘) #獲取特征維度 numFeat=shape(datMat)[1] #遍歷數據集每一個維度 for i in range(numFeat): #利用該維度所有非NaN特征求取均值 meanVal=mean(datMat[nonzero(~isnan(datMat[:,i].A))[0],i]) #將該維度中所有NaN特征全部用均值替換 datMat[nonzero(isnan(datMat[:,i].A))[0],i]=meanVal return datMat
這樣,我們就去除了所有NaN特征,接下來就可以對數據集利用PCA算法進行降維處理了。
2 PCA降維
那麽我們如果確定需要保留哪些重要特征呢?PCA函數可以給出數據所包含的信息量,然後通過定量的計算數據中所包含的信息決定出保留特征的比例。下面是具體代碼:
dataMat=pca.replaceNanWithMean() meanVals=mean(dataMat,axis=0) meanRemoved=dataMat-meanVals conMat=cov(meanRemoved,rowvar=0) eigVals,eigVects=linalg.eig(mat(covMat))
從上面的特征值結果,我們可以看到如下幾個重要信息:
(1)裏面有很多值都是0,這意味著這些特征都是其他特征的副本,都可以通過其他特征來表示,其本身沒有提供額外的信息。
(2)可以看到最前面的15個特征值得數量級都大於105,而後面的特征值都變得非常小。這表明,所有特征中只有部分特征是重要特征。
下圖示出了數據集前20個主成分占總方差的百分比:
可以看出,數據的絕大部分方差都包含在前面的幾個主成分中,舍棄後面的主成分並不會損失太多的信息。如果只保留前面幾個最重要的主成分,那麽在保留了絕大部分信息的基礎上,可以將數據集特征壓縮到一個非常低的程度,顯然大大提高了計算效率。
下表是數據集前20個主成分所占的總方差百分比,以及累計方差百分比:
由上表可以看出,前六個主成分覆蓋了數據96.8%的方差,前二十個主成分覆蓋了99.3%的方差。這表明,通過特征值分析,我們可以確定出需要保留的主成分及其個數,在數據集整體信息(總方差)損失很小的情況下,我們可以實現數據的大幅度降維。
一旦,通過特征值分析知道了需要保留的主成分個數,那麽我們就可以通過pca函數,設定合適的N值,使得函數最終將數據特征降低到最佳的維度。
四,總結
(1)降維是一種數據集預處理技術,往往在數據應用在其他算法之前使用,它可以去除掉數據的一些冗余信息和噪聲,使數據變得更加簡單高效,提高其他機器學習任務的計算效率。
(2)pca可以從數據中識別主要特征,通過將數據坐標軸旋轉到數據角度上那些最重要的方向(方差最大);然後通過特征值分析,確定出需要保留的主成分個數,舍棄其他主成分,從而實現數據的降維。
機器學習實戰之PCA