pca算法python实现
⑴ python pca怎么得到主成份
一般步骤来实现PCA算法
(1)零均值化
假如原始数据集为矩阵dataMat,dataMat中每一行代表一个样本,每一列代表同一个特征。零均值化就是求每一列的平均值,然后该列上的所有数都减去这个均值。也就是说,这里零均值化是对每一个特征而言的,零均值化都,每个特征的均值变成0。实现代码如下:
[python]view plain
defzeroMean(dataMat):
meanVal=np.mean(dataMat,axis=0)#按列求均值,即求各个特征的均值
newData=dataMat-meanVal
returnnewData,meanVal
newData,meanVal=zeroMean(dataMat)
covMat=np.cov(newData,rowvar=0)
eigVals,eigVects=np.linalg.eig(np.mat(covMat))
eigValIndice=np.argsort(eigVals)#对特征值从小到大排序
n_eigValIndice=eigValIndice[-1:-(n+1):-1]#最大的n个特征值的下标
n_eigVect=eigVects[:,n_eigValIndice]#最大的n个特征值对应的特征向量
lowDDataMat=newData*n_eigVect#低维特征空间的数据
reconMat=(lowDDataMat*n_eigVect.T)+meanVal#重构数据
returnlowDDataMat,reconMat
函数中用numpy中的mean方法来求均值,axis=0表示按列求均值。
该函数返回两个变量,newData是零均值化后的数据,meanVal是每个特征的均值,是给后面重构数据用的。
(2)求协方差矩阵
[python]view plain
numpy中的cov函数用于求协方差矩阵,参数rowvar很重要!若rowvar=0,说明传入的数据一行代表一个样本,若非0,说明传入的数据一列代表一个样本。因为newData每一行代表一个样本,所以将rowvar设置为0。
covMat即所求的协方差矩阵。
(3)求特征值、特征矩阵
调用numpy中的线性代数模块linalg中的eig函数,可以直接由covMat求得特征值和特征向量:
[python]view plain
eigVals存放特征值,行向量。
eigVects存放特征向量,每一列带别一个特征向量。
特征值和特征向量是一一对应的
(4)保留主要的成分[即保留值比较大的前n个特征]
第三步得到了特征值向量eigVals,假设里面有m个特征值,我们可以对其排序,排在前面的n个特征值所对应的特征向量就是我们要保留的,它们组成了新的特征空间的一组基n_eigVect。将零均值化后的数据乘以n_eigVect就可以得到降维后的数据。代码如下:
[python]view plain
代码中有几点要说明一下,首先argsort对特征值是从小到大排序的,那么最大的n个特征值就排在后面,所以eigValIndice[-1:-(n+1):-1]就取出这个n个特征值对应的下标。【python里面,list[a:b:c]代表从下标a开始到b,步长为c。】
⑵ PCA(主成分分析)python实现
回顾了下PCA的步骤,并用python实现。深刻的发现当年学的特征值、特征向量好强大。
PCA是一种无监督的学习方式,是一种很常用的降维方法。在数据信息损失最小的情况下,将数据的特征数量由n,通过映射到另一个空间的方式,变为k(k<n)。
这里用一个2维的数据来说明PCA,选择2维的数据是因为2维的比较容易画图。
这是数据:
画个图看看分布情况:
协方差的定义为:
假设n为数据的特征数,那么协方差矩阵M, 为一个n n的矩阵,其中Mij为第i和第j个特征的协方差,对角线是各个特征的方差。
在我们的数据中,n=2,所以协方差矩阵是2 2的,
通过numpy我们可以很方便的得到:
得到cov的结果为:
array([[ 0.61655556, 0.61544444],
[ 0.61544444, 0.71655556]])
由于我们之前已经做过normalization,因此对于我们来说,
这个矩阵就是 data*data的转置矩阵。
得到结果:
matrix([[ 5.549, 5.539],
[ 5.539, 6.449]])
我们发现,其实协方差矩阵和散度矩阵关系密切,散度矩阵 就是协方差矩阵乘以(总数据量-1)。因此他们的 特征根 和 特征向量 是一样的。这里值得注意的一点就是,散度矩阵是 SVD奇异值分解 的一步,因此PCA和SVD是有很大联系的,他们的关系这里就不详细谈了,以后有机会再写下。
用numpy计算特征根和特征向量很简单,
但是他们代表的意义非常有意思,让我们将特征向量加到我们原来的图里:
其中红线就是特征向量。有几点值得注意:
蓝色的三角形就是经过坐标变换后得到的新点,其实他就是红色原点投影到红线、蓝线形成的。
得到特征值和特征向量之后,我们可以根据 特征值 的大小,从大到小的选择K个特征值对应的特征向量。
这个用python的实现也很简单:
从eig_pairs选取前k个特征向量就行。这里,我们只有两个特征向量,选一个最大的。
主要将原来的数据乘以经过筛选的特征向量组成的特征矩阵之后,就可以得到新的数据了。
output:
数据果然变成了一维的数据。
最后我们通过画图来理解下数据经过PCA到底发生了什么。
绿色的五角星是PCA处理过后得到的一维数据,为了能跟以前的图对比,将他们的高度定位1.2,其实就是红色圆点投影到蓝色线之后形成的点。这就是PCA,通过选择特征根向量,形成新的坐标系,然后数据投影到这个新的坐标系,在尽可能少的丢失信息的基础上实现降维。
通过上述几步的处理,我们简单的实现了PCA第一个2维数据的处理,但是原理就是这样,我们可以很轻易的就依此实现多维的。
用sklearn的PCA与我们的pca做个比较:
得到结果:
用我们的pca试试
得到结果:
完全一致,完美~
值得一提的是,sklearn中PCA的实现,用了部分SVD的结果,果然他们因缘匪浅。
⑶ PCA闄岖淮绠楁硶钬斺斿师鐞嗕笌瀹炵幇
链哄櫒瀛︿範锘虹绠楁硶python浠g爜瀹炵幇鍙鍙傝冿细machine_learning_algorithms銆
1銆佺亩浠
PCA锛圥rincipal Component Analysis锛夋槸涓绉嶅父鐢ㄧ殑鏁版嵁鍒嗘瀽鏂规硶銆侾CA阃氲繃绾挎у彉鎹㈠皢铡熷嬫暟鎹鍙樻崲涓轰竴缁勫悇缁村害绾挎ф棤鍏崇殑琛ㄧず锛屽彲鐢ㄤ簬鎻愬彇鏁版嵁镄勪富瑕佺壒寰佸垎閲忥纴甯哥敤浜庨珮缁存暟鎹镄勯檷缁淬
4涓浜涘笔CA镄勮ょ煡
PCA链璐ㄤ笂鏄灏嗘柟宸链澶х殑鏂瑰悜浣滀负涓昏佺壒寰侊纴骞朵笖鍦ㄥ悇涓姝d氦鏂瑰悜涓婂皢鏁版嵁钬灭荤浉鍏斥濓纴涔熷氨鏄璁╁畠浠鍦ㄤ笉钖屾d氦鏂瑰悜涓婃病链夌浉鍏虫с
锲犳わ纴PCA涔熷瓨鍦ㄤ竴浜涢檺鍒讹纴渚嫔傚畠鍙浠ュ緢濂界殑瑙i櫎绾挎х浉鍏筹纴浣嗘槸瀵逛簬楂橀桩鐩稿叧镐у氨娌℃湁锷炴硶浜嗭纴瀵逛簬瀛桦湪楂橀桩鐩稿叧镐х殑鏁版嵁锛屽彲浠ヨ冭槛Kernel PCA锛岄氲繃Kernel鍑芥暟灏嗛潪绾挎х浉鍏宠浆涓虹嚎镐х浉鍏炽鍙﹀栵纴PCA锅囱炬暟鎹钖勪富鐗瑰緛鏄鍒嗗竷鍦ㄦd氦鏂瑰悜涓婏纴濡傛灉鍦ㄩ潪姝d氦鏂瑰悜涓婂瓨鍦ㄥ嚑涓鏂瑰樊杈冨ぇ镄勬柟钖戯纴PCA镄勬晥鏋滃氨澶ф墦鎶樻墸浜嗐
链钖庨渶瑕佽存槑镄勬槸锛孭CA鏄涓绉嶆棤鍙傛暟鎶链锛屼篃灏辨槸璇撮溃瀵瑰悓镙风殑鏁版嵁锛屽傛灉涓嶈冭槛娓呮礂锛岃皝𨱒ュ仛缁撴灉閮戒竴镙凤纴娌℃湁涓昏傚弬鏁扮殑浠嫔叆锛屾墍浠PCA渚夸簬阃氱敤瀹炵幇锛屼絾鏄链韬镞犳硶涓镐у寲镄勪紭鍖栥