PCA算法


PCA原理不说了,真的我也讲不明白…………,但是这篇博客写的真的不错在此记录一下 。传送门在这

但是还有疑惑啊啊啊!!

对于原文中的这句话,“寻找一个矩阵P,满足 是一个对角矩阵,并且对角元素按从大到小依次排列,那么P的前K行就是要寻找的基,用P的前K行组成的矩阵乘以X就使得X从N维降到了K维并满足上述优化条件

不知道为什么要按照对角元素从大到小排列?

对于这个问题我们就要了解特征值和特征向量的意义了,在给个传送门

我们通过特征值分解得到的前N个特征向量,那么就对应了这个矩阵最主要的N个变化方向。我们利用这前N个变化方向,就可以近似这个矩阵(变换)。也就是之前说的:提取这个矩阵最重要的特征。总结一下,特征值分解可以得到特征值与特征向量,特征值表示的是这个特征到底有多重要,而特征向量表示这个特征是什么,可以将每一个特征向量理解为一个线性的子空间,我们可以利用这些线性的子空间干很多的事情。不过,特征值分解也有很多的局限,比如说变换的矩阵必须是方阵。

给出伪代码

设有m条n维数据。

1)将原始数据按列组成n行m列矩阵X

2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值

3)求出协方差矩阵

4)求出协方差矩阵的特征值及对应的特征向量

5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P

6)即为降维到k维后的数据


#encoding:utf-8
from numpy import *
def loadDataSet(filename, delim = '\t'):
    fr = open(filename)
    stringArr = [line.strip().split('\t') for line in fr.readlines()]
    datArr = [map(float, line) for line in stringArr]
    return mat(datArr)
def pca(datMat, topNfeat = 99999):
    meanVals = mean(datMat, axis = 0) #求每一个特征值的均值
    meanRemoved = datMat - meanVals #进行零均值化

#rowvar=0,代表一段数据是一行,行的个数代表样本个数,列代表特征值
#rowvar=1, 代表一段数据是一列,行的个数代表特征的的个数,列的个数代表样本的个数
    covMat = cov(meanRemoved,rowvar = 0)#计算协方差矩阵  注意分母除的是(N-1)样本的数目减一
    eigVals, eigVects = linalg.eig(covMat)#求出特征值,特征向量
    eigValsInd = argsort(eigVals)#返回特征值从小到大的索引
    eigValsInd = eigValsInd[:-(topNfeat+1):-1]
    redEigVects = eigVects[:,eigValsInd]#注意特征向量是列向量
    lowDataMat = meanRemoved*redEigVects#将数据转化到新空间
    recondMat = (lowDataMat*redEigVects.T)+meanVals#将新坐标旋转到跟旧坐标相对的位置
    return lowDataMat,recondMat
def draw(dataMat,recondMat):
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111)
   
    ax.scatter(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0],marker='o',s=20,c='black')
    ax.scatter(recondMat[:,0].flatten().A[0], recondMat[:,1].flatten().A[0],marker='o',s=20,c='red')
    plt.show()
if __name__ == '__main__':
    datMat = loadDataSet('testSet.txt')
    lowData, recordMat = pca(datMat,1)
    draw(datMat,recordMat)


测试



测试数据集传送门

如图列所示,我们将蓝色的点,降维到了一维,也就是红色那个点集


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值