PCA原理参考链接来自:
https://blog.csdn.net/guyuealian/article/details/68487833
原理二
先来原理:
PCA的算法过程,用一句话来说,就是“将所有样本X减去样本均值m,再乘以样本的协方差矩阵C的单位化(也叫标准化)后的特征向量V,即为PCA主成分分析”,其计算过程如下:
[1].将原始数据按行组成m行n列样本矩阵X(每行一个样本,每列为一维特征)
[2].求出样本X的协方差矩阵C和样本均值m;(Matlab可使用cov()函数求样本的协方差矩阵C,均值用mean函数)
[3].求出协方差矩阵的特征值D及对应的特征向量V;(Matlab可使用eigs()函数求矩阵的特征值D和特征向量V)
[4].将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P;(eigs()返回特征值构成的向量本身就是从大到小排序的)
[5].Y=(X-m)×P即为降维到k维后的数据;
上代码:
#-*- encoding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import numpy as np
from numpy import *
def PCA_compute(X,k):
X=matrix(X)
print"-"*20
print "X=",X
print"------------------下面是协方差矩阵-----------------------"
Y=np.cov(X.T)#这里必须转置,理由见下方链接
print Y#计算协方差矩阵
print"-----------下面是特征值和特征向量------------------------------"
#特征值a
#这里总结下:
#numpy计算特征值得到的类型是numpy.ndarray
#numpy计算特征向量得到的类型是numpy.ndarray
eigenvalue,featurevector=np.linalg.eig(Y)
print"-----------下面是特征值-----------------------------"
idx = eigenvalue.argsort()[::-1] #获得特征值排序后的顺序,这个函数适用的前提是numpy.ndarray类型
print"+++++++++++++"
print"type(eigenvalue)=",type(eigenvalue)
print"type(featurevector)=",type(featurevector)
eigenValues = eigenvalue[idx]
print"特征值=\n",eigenValues
FeatureVectors = featurevector[:,idx]
#featurevector是没有排序的
#FeatureVectors是在特征值排序后,根据特征值的排序顺序进行排序的
print"featureVectors=\n",FeatureVectors
print"-----------下面是平均矩阵(原始矩阵的每列的均值)----------------------------"
averageMatrix=np.mean(X, axis=0)#表示沿着y轴取平均
# axis=1
# ---------------->
# col1 col2 col3
# || row1
# axis=0|| row2
# || row3
# \/
print"averageMatrix=",averageMatrix
averageMatrix=averageMatrix.tolist()
averageMatrix=averageMatrix[0]
MeanMatrix=[]
print"len(X[0])=",len(X)
for index in range(len(X)):
MeanMatrix.append(averageMatrix)
MeanMatrix=mat(MeanMatrix)
print"MeanMatrix=\n",MeanMatrix
print"-------------------接下来是主成分--------------------------"
print mat(featurevector)
tempX=mat(X)-mat(MeanMatrix)
print tempX
print"FeatureVectors=",FeatureVectors
Score=(mat(X)-mat(MeanMatrix))*mat(FeatureVectors)
return Score[:,0:k].copy()
if __name__ == '__main__':
X=[ [1,2,1,1],
[3,3,1,2],
[3,5,4,3],
[5,4,5,4],
[5,6,1,5],
[6,5,2,6],
[8,7,1,2],
[9,8,3,7]]
k=2
answer=PCA_compute(X,k)
print answer
实验结果为:
[[-5.79467821 0.60705487]
[-3.38863423 0.87952394]
[-1.61549833 -1.56652328]
[-0.15133075 -2.50507639]
[ 0.99576675 0.56654487]
[ 1.7515016 -0.65460481]
[ 2.21615035 3.13807448]
[ 5.98672282 -0.46499368]]
对比matlab代码的运行结果:
%% 样本矩阵X,有8个样本,每个样本有4个特征,使用PCA降维提取k个主要特征(k<4)
k=2; %将样本降到k维参数设置
X=[1 2 1 1;
3 3 1 2;
3 5 4 3;
5 4 5 4;
5 6 1 5;
6 5 2 6;
8 7 1 2;
9 8 3 7];
[Row Col]=size(X);%注意,matlab中得到的特征向量也是按列来读取的。
covX=cov(X);%求样本的协方差矩阵(散步矩阵除以(n-1)即为协方差矩阵)??
[V D]=eigs(covX)%求协方差矩阵的特征值D和特征向量V6??
meanX=mean(X)%样本均值m??
%所有样本X减去样本均值m,再乘以协方差矩阵(散步矩阵)的特征向量V,即为样本的主成份SCORE??
tempX=repmat(meanX,Row,1)
ans1=X-tempX
SCORE2=(X-tempX)*V%主成份:SCORE??
pcaData2=SCORE2(:,1:k)
可知结果完全一致。
然后我们来测试下其他博客上的数据集,把测试代码中修改如下:
if __name__ == '__main__':
# X=[ [1,2,1,1],
# [3,3,1,2],
# [3,5,4,3],
# [5,4,5,4],
# [5,6,1,5],
# [6,5,2,6],
# [8,7,1,2],
# [9,8,3,7]]
# k=2
X=[[10.2352,11.3220],
[10.1223,11.8110],
[9.1902,8.9049],
[9.3064,9.8474],
[8.3301,8.3404],
[10.1528,10.1235],
[10.4085,10.8220],
[9.0036,10.0392],
[9.5349,10.0970],
[9.4982,10.8254]]
k=1
answer=PCA_compute(X,k)
print answer
运行后可知与连接
https://blog.csdn.net/google19890102/article/details/27969459
的计算结果完全一致。