Principal component analysis(PCA)主成分分析

来源:互联网 发布:ps模板 知乎 海报 编辑:程序博客网 时间:2024/05/21 14:46

PCA是将原始数据X通过数学方法降维,得到产生该形式数据的内在原因。

主要步骤为:

1)求原始数据X的协方差矩阵S

2)求S的最大特征值对应的K个特征向量并构成权重矩阵W

3)将W与X内积得到降维数据Z

注意:协方差矩阵计算的是不同属性之间的交互关系。so,如果数据集有2维属性,那么协方差矩阵就是2x2维;如果有4维属性,则协方差矩阵为4x4维。


本文以Iris数据为例,对其进行主成分分析,原始数据X.T为150x4:

[[ 5.1  3.5  1.4  0.2] [ 4.9  3.   1.4  0.2] [ 4.7  3.2  1.3  0.2] ...,  [ 6.5  3.   5.2  2. ] [ 6.2  3.4  5.4  2.3] [ 5.9  3.   5.1  1.8]]
由于python中numpy.cov()分解协方差矩阵默认以行中存储属性值(而不是列),所以在cov时要对数据进行转置,计算得到的协方差矩阵S为4x4:

[[ 0.68569351 -0.03926846  1.27368233  0.5169038 ] [-0.03926846  0.18800403 -0.32171275 -0.11798121] [ 1.27368233 -0.32171275  3.11317942  1.29638747] [ 0.5169038  -0.11798121  1.29638747  0.58241432]]
对S分解,得到最大两个特征值对应的特征向量构成的eVact为2x4:
[[ 0.36158968 -0.65653988 -0.58099728  0.31725455] [-0.08226889 -0.72971237  0.59641809 -0.32409435]]
将eVact(2x4)与原始数据X(4x150)做内积得到降维数据lowDData为2x150,转置后为:
[[-1.20372752 -2.20339819] [-0.94777551 -1.82208822] [-1.0933017  -2.01121873] ...,  [-2.00596351 -0.27069955] [-2.39807946 -0.51584852] [-2.2282685  -0.21616115]]
对应2维图为:


由2维数据可见,基本已经可分,但是只显示了2类,将得到的数据带入FCM聚类算法,得到的错分率和原始数据带入相同。

PCA代码如下:

# -*- coding: utf-8 -*-"""Created on Sat Oct  7 20:21:05 2017@author: wjw"""import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom FCM.fcm import fcmdef readText(filePath):        lines = open(filePath,'r').readlines()    data = []        for line in lines:        dataList = line.split(',')        data.append([float(dataList[0]),float(dataList[1]),float(dataList[2]),                     float(dataList[3])])            return np.array(data).T #这里要把矩阵转置成行代表属性列,变成4x150的matrixdef pca(data):    k=2    meanVals = np.mean(data,axis=1) #对每一行(每个属性)求平均值,因为协方差的计算中需要减去均值    # axis=0,求每一列的平均值;axis=1,求每一行的平均值     newMeanvals = []    for meanVal in meanVals:        newMeanvals.append([meanVal]) #单独构成list组成的list    meanRemoved = data - newMeanvals # 这样才能对应相减    covMat = np.cov(meanRemoved)    print(covMat)    print(covMat.shape)    eigVals,eigVects = np.linalg.eig(np.mat(covMat))       #linalg中的eig方法,得到特征值和特征向量    eig = list(zip(eigVals,eigVects)) # 将特征值特征向量压入一个eig    dataframe = pd.DataFrame(eig,columns=['eigVals','eigVects'])#变成dataframe    Ksorted = -np.sort(-dataframe.eigVals)[:k] # 降序排列取前k个    index = []    for i in range(dataframe.eigVals.size):        for k in Ksorted:            if dataframe.eigVals.iloc[i]==k: #iloc,iat,loc,at都是dataFrame中用来取值定位的方法,前者用index后者用行列名                index.append(i)    pickedata = dataframe.iloc[index,:] #得到特征值前k大对应的特征向量,并组合    pickedeigVects =pickedata.eigVects    array=[]    for p in pickedeigVects:        array.append(p.tolist()) #将matrix转换成list    array = np.mat(np.array(array)) #list转换成matrix    print(array)    lowDdata = array * np.mat(data)#将原数据转换成维度较低的数据    return lowDdata.Tdef draw(data):    plt.plot(data[:,0],data[:,1],'or')        plt.show()if __name__=="__main__":    filePath = r"E:\data\iris.txt"    data= readText(filePath)    lowDdata = pca(data)    print(lowDdata)    draw(lowDdata)    fmatrix = fcm(np.array(lowDdata),m=2,k=3)


阅读全文
1 0
原创粉丝点击