主成分分析PCA算法部分代码(python)
代码用于完成老师布置的作业。
问题:
三个样本:A(-1,-2,-3,1,2,3,1),B(-1,-1,-2,1,1,2,2,C),C(1,4,-2,1,2,1,4)
计算它们的协方差,特征值,特征向量,以及前两项的协方差所占的比例
其中,对于协方差的处理参考了毛球的技术日志,去除了冗余的部分,简化了代码,因为直接使用了numpy的函数。
改进代码
import numpy as ny
a1=([-1,-2,-3,1,2,3,1])
a2=([-1,-1,-2,1,1,2,2])
a3=([1,4,-2,1,2,1,4])
#创建矩阵
data=ny.array([a1,a2,a3])
data=ny.mat(data)
#计算矩阵的协方差
covmetric=ny.cov(data,rowvar=1)
#计算协方差矩阵的特征值,特征向量
eigvalues,eigvectors=ny.linalg.eig(covmetric)
print("before order:\neigvalues:\n",eigvalues,"\n"
"eigvectors:\n",eigvectors)
#按照降序排列,获取降序排列的下标,argsort方法同向可取得下标
#sort by descending order
sortindex=sorted(range(len(eigvalues)), key=lambda k: eigvalues[k],reverse = True)
#计算前两项的协方差所占的比例
# calculate the proportion of total population covariance of first 2 component
eigvalues=eigvalues[sortindex]
proportion=ny.sum(eigvalues[:2])/ny.sum(eigvalues)
#输出
print("after order:\neigvalues:\n",eigvalues,"\n"
"eigvectors:\n",eigvectors[:,sortindex],"\n"
"proportion:\n",proportion)
原始代码
最初写的代码如下,是根据老师的ppt的解释进行一步一步的书写的,其中在协方差计算之前,对数据进行了扣除平均数的处理
import numpy as ny
#计算平均值,如果是矩阵,计算每列的平均值,ny.mean(data,axis=1),axis=1代表按列,0代表按行
def _calavg_(seq):
return ny.mean(seq)
#计算调整后的平均值,原值-平均值
def _dataadj_(seq,avg):
for i in range(len(seq)):
seq[i]=seq[i]-avg
return seq
#计算协方差
def _calcov_(seq1,seq2):
numerator=0.0
for i in range(len(seq1)):
numerator=numerator+seq1[i]*seq2[i]
return numerator/(len(seq1)-1)
#构建协方差矩阵
def _covmetric_(seq1,seq2,seq3):
eigv=ny.array([[_calcov_(seq1,seq1),_calcov_(seq1,seq2),_calcov_(seq1,seq3)],
[_calcov_(seq2,seq1),_calcov_(seq2,seq2),_calcov_(seq2,seq3)],
[_calcov_(seq3,seq1),_calcov_(seq3,seq2),_calcov_(adj3,seq3)]])
return ny.mat(eigv)
#计算特征值,特征向量
def _caleigvalue_(x):
a,b=ny.linalg.eig(x)
return a,b
a1=([-1,-2,-3,1,2,3,1])
a2=([-1,-1,-2,1,1,2,2])
a3=([1,4,-2,1,2,1,4])
avg1=_calavg_(a1)
adj1=_dataadj_(a1,avg1)
avg2=_calavg_(a2)
adj2=_dataadj_(a2,avg2)
avg3=_calavg_(a3)
adj3=_dataadj_(a3,avg3)
covmetric=_covmetric_(adj1,adj2,adj3)
print ("covmetric=\n",covmetric)
print("特征值为:\n",eigVals,"\n"
"特征向量为:\n",eigVects)
- 之后还会对PCA算法进行较为完整的整理