pca總結,非常詳細


#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) #從結果看到完全一樣.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM