#coding=utf-8 from numpy import * '''通過方差的百分比來計算將數據降到多少維是比較合適的, 函數傳入的參數是特征值和百分比percentage,返回需要降到的維度數num''' def eigValPct(eigVals,percentage): sortArray=sort(eigVals) #使用numpy中的sort()對特征值按照從小到大排序 sortArray=sortArray[::-1] #特征值從大到小排序 arraySum=sum(sortArray) #數據全部的方差arraySum #percentage 表示的是降為到所有方差和的多少.也就是保留數據的多少波動性.越大保留越多 #比如percentage寫0.99那么就是num返回2 ,如果寫0.7就返回1 tempSum=0 num=0 for i in sortArray: tempSum+=i num+=1 if tempSum>=arraySum*percentage: return num '''pca函數有兩個參數,其中dataMat是已經轉換成矩陣matrix形式的數據集,列表示特征; 其中的percentage表示取前多少個特征需要達到的方差占比,默認為0.9''' def pca(dataMat,percentage=0.9): meanVals=mean(dataMat,axis=0) #對每一列求平均值,因為協方差的計算中需要減去均值 meanRemoved=dataMat-meanVals covMat=cov(meanRemoved,rowvar=0) #cov()計算方差 #是一個4*4的矩陣 即feature_size*feature_size eigVals,eigVects=linalg.eig(mat(covMat)) #利用numpy中尋找特征值和特征向量的模塊linalg中的eig()方法 k=eigValPct(eigVals,percentage) #要達到方差的百分比percentage,需要前k個向量 eigValInd=argsort(eigVals) #對特征值eigVals從小到大排序 eigValInd=eigValInd[:-(k+1):-1] #從排好序的特征值,從后往前取k個,這樣就實現了特征值的從大到小排列 redEigVects=eigVects[:,eigValInd] #返回排序后特征值對應的特征向量redEigVects(主成分) #投影就是直接矩陣乘法,兩個向量做內機就是做投影,歸結到矩陣就是矩陣乘法. #其實不是投影,而是一個忽略了特征向量摸長的投影,所以這個做完了得到的是一個投影之后在主方向上再伸縮一下. #這里周志華樹里面給的特征向量組成的這個矩陣是u矩陣的. #重要性質:一個n行n列的實對稱矩陣一定可以找到n個單位正交特征向量,證明顯然. #但是問題是直接通過numpy里面的eig得到的是正交的向量嗎?只需要看下面的這個是不是除了對角線上全都是0 #經過實驗還真不是.numpy給的是隨便給的一個. ## print (redEigVects*redEigVects.T) lowDDataMat=meanRemoved*redEigVects #將原始數據投影到主成分上得到新的低維數據lowDDataMat ## print (redEigVects*redEigVects.T) #特征向量矩陣不是u矩陣 reconMat=(lowDDataMat*redEigVects.T)+meanVals #得到重構數據reconMat?沒懂怎么重構的 #據我分析這里面乘以專職也就是一個近似的逆,然后得到后也是忽略方向的伸縮 #貌似這里面的專職就能達到乘以逆的效果,需要證明一下.這個證明也是顯然的. #總結一下就是直接做*redEigVects*redEigVects.T就達到了降為然后再你回去的效果.確實很方便. return lowDDataMat,reconMat a=pca(array([[9,43,4343,-88],[9,4324,43,-8],[4,5,6,70],[1,2,300,4000],[1,2,300,46],[4,5,60,70]])) print (a[1])#這個輸出的就是pca之后再變回去的數據 a=array([[9,43,4343,-88],[9,4324,43,-8],[4,5,6,70],[1,2,300,4000],[1,2,300,46],[4,5,60,70]]) #下面是用庫包來實現的,更少代碼~~~~~~~~~~~~~~~~~~~~~~~~~ import numpy as np from sklearn import decomposition from sklearn import datasets meanVals=mean(a,axis=0) pca = decomposition.PCA(n_components=3) pca.fit(a) a = pca.transform(a) a = np.matrix(a) b = np.matrix(pca.components_) c = a * b c+=meanVals print (c) #從結果看到完全一樣.
