主成分分析(pca)算法的实现步骤及代码

来源:互联网 发布:matlab求解最优化模型 编辑:程序博客网 时间:2024/04/29 03:42

上一篇文章主要写了主成分分析的原理,现在就用matlab来实现其功能。

主成分分析的实现步骤如下:

1.输入样本矩阵

       假设样本x1,x2,...,xN,共N个样本,每个样本以列向量的形式表示,每个样本有M维。

X=[xx... xN]MxN。

2.计算样本中每一维的均值,然后计算观察值与均值之间的偏差,再计算协方差矩阵

    根据协方差函数

首先要求出每一维的均值,然后再计算观察值与均值之间的偏差,再计算协方差矩阵

3.计算协方差矩阵的特征值和特征向量矩阵

    根据协方差矩阵就可以求出特征值和特征向量,然后给特征值进行降序排序,相应的

特征向量也要按照特征值的排序做出相应的调整,这样主要是为下一步的提取少量的特征

值做准备。

4.计算总能量,并选取贡献率最大的特征值

      总能量的计算就是全部的特征值之和,而贡献率就是用前p个特征值去除以全部特征值

之和,如果前p个特征值之和占全部特征值之和的90%以上,就提取前p个特征值和前p个特

征值所对应的特征向量,这样就减少了维数。

5.计算前p个特征值所对应的的特征向量组成的矩阵,计算降维后的样本矩阵

   根据上一步得到的新的特征向量,用原始的协方差矩阵去乘以此新的特征向量组成的新矩阵,

就可以得到降维后的样本矩阵

%%%%%%%%%%%%打开一个30行8列数据的txt文件%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%第一步:输入样本矩阵%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
filename='src.txt';
fid=fopen(filename,'r');
vector=fscanf(fid,'%g',[30,8]);%输入一个矩阵,此矩阵有8个维度30个样本
%现对其进行pca降维
%%
%第二步:计算样本中每一维的均值,然后计算观察值与均值之间的偏差,再计算协方差矩阵
s=sum(vector,1);%计算每一列的均值
[nSmp,nFea] = size(vector);
vector=vector-repmat(mean(vector),nSmp,1);%把每一维的均值复制成nSmp*nFea矩阵,然后计算偏差
W=zeros(nFea,nFea);%建立一个nFea*nFea的零矩阵
W=W+vector'*vector;
W=W/(nSmp-1);%根据协方差公式计算协方差,得到协方差矩阵W
%%
%第三步:计算协方差矩阵的特征值和特征向量矩阵
fprintf(1,'Calculating generalized eigenvectors and eigenvalues...\n');
[eigvectors, eigvalues] = eig(W);%eigvectors为特征向量组成的矩阵,eigvalues特征值组成的对角矩阵
fprintf(1,'Sorting eigenvectors according to eigenvalues...\n');
d1=diag(eigvalues);%返回对角矩阵上的值
[d2 index]=sort(d1); %以升序排序,d2为排列后的值,index为索引值
cols=size(eigvectors,2);% 特征向量矩阵的列数
for i=1:cols
vsort(:,i) = eigvectors(:, index(cols-i+1) ); % vsort 是一个M*col(注:col一般等于M)阶矩阵,保存的是按降序排列的特征向量,每一列构成一个特征向量
dsort(i) = d1( index(cols-i+1) ); % dsort 保存的是按降序排列的特征值,是一维行向量
end %完成降序排列
%%
%第四步:计算总能量,并选取贡献率最大的特征值
dsum = sum(dsort);%对所有的特征值求和
dsum_extract = 0;%求前几个特征值之和,当前几个特征值之和大于90%时,可以认为这几个特征值可以表征当前矩阵
p = 0;
while( dsum_extract/dsum < 0.9)
p = p + 1;
dsum_extract = sum(dsort(1:p));
end
%当p=5时,贡献率为0.9095,所以就可以选取5个特征值代表当前矩阵
%%
%第五步:计算前p个特征值所对应的的特征向量组成的矩阵,计算降维后的样本矩阵
vsort = vsort(:,1:p);%提取前p个特征生成8*p矩阵
fprintf(1,'Feature extraction and calculating newData...\n');
newvector=vector*vsort;%生成nSmp行p列的矩阵,达到降维的效果


原创粉丝点击