壹般步驟來實現PCA算法
(1)零均值化
假如原始數據集為矩陣dataMat,dataMat中每壹行代表壹個樣本,每壹列代表同壹個特征。零均值化就是求每壹列的平均值,然後該列上的所有數都減去這個均值。也就是說,這裏零均值化是對每壹個特征而言的,零均值化都,每個特征的均值變成0。實現代碼如下:
[python]?view plain?copy
def?zeroMean(dataMat):
meanVal=np.mean(dataMat,axis=0)?#按列求均值,即求各個特征的均值?
newData=dataMat-meanVal?
return?newData,meanVal?
函數中用numpy中的mean方法來求均值,axis=0表示按列求均值。
該函數返回兩個變量,newData是零均值化後的數據,meanVal是每個特征的均值,是給後面重構數據用的。
(2)求協方差矩陣
[python]?view plain?copy
newData,meanVal=zeroMean(dataMat)?
covMat=np.cov(newData,rowvar=0)?
numpy中的cov函數用於求協方差矩陣,參數rowvar很重要!若rowvar=0,說明傳入的數據壹行代表壹個樣本,若非0,說明傳入的數據壹列代表壹個樣本。因為newData每壹行代表壹個樣本,所以將rowvar設置為0。
covMat即所求的協方差矩陣。
(3)求特征值、特征矩陣
調用numpy中的線性代數模塊linalg中的eig函數,可以直接由covMat求得特征值和特征向量:
[python]?view plain?copy
eigVals,eigVects=np.linalg.eig(np.mat(covMat))?
eigVals存放特征值,行向量。
eigVects存放特征向量,每壹列帶別壹個特征向量。
特征值和特征向量是壹壹對應的
(4)保留主要的成分[即保留值比較大的前n個特征]
第三步得到了特征值向量eigVals,假設裏面有m個特征值,我們可以對其排序,排在前面的n個特征值所對應的特征向量就是我們要保留的,它們組成了新的特征空間的壹組基n_eigVect。將零均值化後的數據乘以n_eigVect就可以得到降維後的數據。代碼如下:
[python]?view plain?copy
eigValIndice=np.argsort(eigVals)#對特征值從小到大排序?
n_eigValIndice=eigValIndice[-1:-(n+1):-1]#最大的n個特征值的下標?
n_eigVect=eigVects[:,n_eigValIndice]#最大的n個特征值對應的特征向量?
lowDDataMat=newData*n_eigVect#低維特征空間的數據?
reconMat=(lowDDataMat*n_eigVect.T)+meanVal?#重構數據?
return?lowDDataMat,reconMat?
代碼中有幾點要說明壹下,首先argsort對特征值是從小到大排序的,那麽最大的n個特征值就排在後面,所以eigValIndice[-1:-(n+1):-1]就取出這個n個特征值對應的下標。python裏面,list[a:b:c]代表從下標a開始到b,步長為c。