[关闭]
@w460461339 2018-10-13T11:48:31.000000Z 字数 3391 阅读 971

机器学习实战Day12:PCA

MachineLearning


0.参考

这篇说的超赞
http://blog.codinglabs.org/articles/pca-tutorial.html

下面这篇一般般,甚至应该是只讲了从N维降到1维的情况,不过对于理解也有一定帮助。
http://blog.csdn.net/lu597203933/article/details/41544547

1.PCA原理说明

1.1 降维的向量和矩阵表示

当其中一个作为基的向量长度是1时,向量的乘积等于另一个向量在这个向量上的投影;
当其中一个作为基的向量长度不是1时,向量的乘积等于另个一个向量在这向量上投影的放缩。

1.2 降维优化目标

当然,不是随便降维就可以的,我们希望,降维后,原数据的损失尽量的小,或者说,使得降维后的数据,仍能够尽可能的区分样本。

1.3 协方差矩阵与优化
1.4 计算

由上文知道,协方差矩阵C是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:

1)实对称矩阵不同特征值对应的特征向量必然正交。

2)设特征向量λ重数为r,则必然存在r个线性无关的特征向量对应于λ,因此可以将这r个特征向量单位正交化。

由上面两条可知,一个n行n列的实对称矩阵一定可以找到n个单位正交特征向量,设这n个特征向量为e1,e2,⋯,en,我们将其按组成矩阵:
image_1c05s65ms1jr718ilvg28vj1ol8p.png-2.1kB
则对协方差矩阵C有如下结论:
image_1c05s765sbqjip913l21s5m17uu96.png-6.6kB

那么这里特征值就是降维后的方差,我们从大到小选择k个特征值λ,这k个特征值对应的特征向量,就是我们要的基。

到这里,我们发现我们已经找到了需要的矩阵P:

                        P=ET(E矩阵的转置)

P是协方差矩阵的特征向量单位化后按行排列出的矩阵,其中每一行都是C的一个特征向量。如果设P按照ΛΛ中特征值的从大到小,将特征向量从上到下排列,则用P的前K行组成的矩阵乘以原始数据矩阵X,就得到了我们需要的降维后的数据矩阵Y。

2.代码

这里我的代码只是从2维映射到了1维。

  1. from numpy import *
  2. def loadDataSet(fileName,delim='\t'):
  3. fr=open(fileName)
  4. stringArr=[line.strip().split(delim) for line in fr.readlines()]
  5. datArr=[list(map(float,line)) for line in stringArr]
  6. return mat(datArr)
  7. def pca(dataMat,topNfeat=9999999):
  8. # 求每列平均值
  9. meanVals=mean(dataMat,axis=0)
  10. # 每一列去除平均值
  11. meanRemoved=dataMat-meanVals
  12. # 计算协方差矩阵
  13. covMat=cov(meanRemoved,rowvar=0)
  14. # 计算协方差矩阵的特征值和特征向量
  15. eigVals,eigVects=linalg.eig(mat(covMat))
  16. # 特征值排序,从小到大
  17. eigValInd=argsort(eigVals)
  18. #
  19. eigValInd=eigValInd[:-(topNfeat+1):-1]
  20. redEigVects=eigVects[:,eigValInd]
  21. lowDDataMat=meanRemoved*redEigVects
  22. reconMat=(lowDDataMat*redEigVects.T)+meanVals
  23. return lowDDataMat,reconMat
  24. def plotResult(dataMat,reconMat):
  25. import matplotlib.pyplot as plt
  26. fig=plt.figure()
  27. ax=fig.add_subplot(111)
  28. ax.scatter(dataMat[:,0].flatten().A[0],dataMat[:,1].flatten().A[0],marker='^',s=90)
  29. ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0],marker='o',s=90,c='red')
  30. plt.show()
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注