1. 程式人生 > >python 主成分分析PCA

python 主成分分析PCA

機器學習,PCA, 通過方差的百分比來計算將資料降到多少維是比較合適的.

'''通過方差的百分比來計算將資料降到多少維是比較合適的,
函式傳入的引數是特徵值和百分比percentage,返回需要降到的維度數num'''
def eigValPct(eigVals,percentage):
    # print("特徵值=", eigVals)
    sortArray=sort(eigVals) #使用numpy中的sort()對特徵值按照從小到大排序
    sortArray=sortArray[-1::-1] #特徵值從大到小排序
    # print("特徵值從大到小排序=",sortArray )
    arraySum=sum(sortArray) #資料全部的方差arraySum
    tempSum=0
    tempSum1 = 0
    num=0
    number=[]
    j=0
    tempSumSort=[]
    # fig=plt.figure(1)
    # ax = fig.add_subplot(111)
    for i in sortArray:
        tempSum1+=i
        num+=1
        number.append(num)
        tempSumSort.append(tempSum1/arraySum)
    print("各個成分從大到小的貢獻率=",sortArray/arraySum)
    # plt.axis([0, 10, 0.4, 1])
    # ax.plot(number, tempSumSort, marker='o', mec='r', mfc='w')
    # plt.xlabel(u"number")
    # plt.ylabel(u"percentage")
    # for a, b in zip(number, tempSumSort):
    #     plt.text(a+0.001, b + 0.001, '%.3f' % b, ha='center', va='bottom', fontsize=7)
    # print("各個成分從大到小的累積貢獻率=",tempSumSort)
    # plt.show()
    for i in sortArray:
        tempSum+=i
        j+=1
        if tempSum>=arraySum*percentage:
            #print(j)
            return j


'''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()計算方差
    # print("cov=",covMat)
    eigVals,eigVects=linalg.eig(mat(covMat))  #利用numpy中尋找特徵值和特徵向量的模組linalg中的eig()方法
    # print('各個特徵的特徵值=',eigVals)
    topNfeat=eigValPct(eigVals,percentage) #要達到方差的百分比percentage,需要前k個向量
    eigValInd=argsort(eigVals)  #對特徵值eigVals從小到大排序
    # print('eigvaIId=',sort(eigVals))
    eigValInd=eigValInd[:-(topNfeat+1):-1] #從排好序的特徵值,從後往前取k個,這樣就實現了特徵值的從大到小排列

    redEigVects=eigVects[:,eigValInd]   #返回排序後特徵值對應的特徵向量redEigVects(主成分)
    lowDDataMat=meanRemoved*redEigVects #將原始資料投影到主成分上得到新的低維資料lowDDataMat
    reconMat=(lowDDataMat*redEigVects.T)+meanVals   #得到重構資料reconMat
    pp=eigVals/sum(eigVals)
    return lowDDataMat,pp#返回底維的資料與各個特徵的貢獻率