Matlab的主成分分析

  • 主要目的
  • 方法一:
  • 直接调用pac函数
  • 1.PCA函数的输入与输出参数
  • 2.PCA函数的使用方法
  • 方法二:
  • 思路
  • 代码
  • 方法三:
  • 思路
  • 代码
  • 方法四
  • 代码


主要目的


主成分分析(或称主分量分析,principal component analysis)由皮尔逊(Pearson,1901)首先引入,后来被霍特林(Hotelling,1933)发展了。 主成分分析的主要目的是希望用较少的变量去解释原来资料中的大部分变异,将 们手中许多相关性很高的变量转化成彼此相互独立或不相关的变量。通常是选出比原始变量个数少,能解释大部分资料中的变异的几个新变量,即所谓主成分,并用以解释资料的综合性指标。 因此,我们可以知道主成分分析的一般目的是: (1)变量的降维; (2)主成分的解释。

自己结合了一下写的

X=load('11.txt');
z=zscore(X);               %数据标准化
M=cov(z);                  %协方差
[Q,D]=schur(M);            %求出协方差矩阵的特征向量、特征根
d=diag(D);                %取出特征根矩阵列向量(提取出每一主成分的贡献率)
eig1=sort(d,'descend');      %将贡献率按从大到小元素排列
Q=fliplr(Q);                %依照D重新排列特征向量
B=z*Q;  %得到矩阵B;

S=0;
i=0;
while S/sum(eig1)<0.9
    i=i+1;
    S=S+eig1(i);
end                         %求出累积贡献率大于90%的主成分
NEW=z*Q(:,1:i);              %输出产生的新坐标下的数据
W=100*eig1/sum(eig1);      %贡献率
figure(1)
pareto(W);                  %画出主成分贡献率的直方图
R=trace((z*z')*(NEW*NEW'))/(sqrt(trace((z*z')*(z*z'))*trace((NEW*NEW')*(NEW*NEW'))));  %计算原矩阵与排序后得到的矩阵的RV系数

方法一:

直接调用pac函数

1.PCA函数的输入与输出参数

function [coeff, score, latent, tsquared, explained, mu] = pca(x,varargin)

PCA后会有贡献值,是输入者根据自己想要的贡献值进行维数的改变,进而生成数据。

输入参数:

X,数据集,假设样本的个数为N,每个样本的特征个数为P,则 X是N×P的矩阵。
输出参数:
COEFF,系数矩阵。返回N×P数据矩阵X的主成分系数。X的行对应于观测值,列对应于变量。每列系数包含一个主成分的系数。各列按主成分方差(latent)降序排列。默认情况下,PCA将数据居中并使用奇异值分解算法。对于非默认选项,请使用名称/值对参数。
SCORE,返回主成分得分,它是X在主成分空间中的表示(即表示由原数据X转变到主成分空间所得到的数据)。score的行对应观察值,列对应主成分。中心数据可以用SCORE*COEFF’重建。他将这n维数据按贡献率由大到小排列。(即在改变坐标系的情况下,又对n维数据排序)
LATENT,返回每个主成分方差,即X的协方差矩阵的特征值,特征值从大到小进行排序,每一个数据是对应score里相应维的贡献率(是加工后的score的贡献率而不是原始数据的)。由大到小排列(因为score也是按贡献率由大到小排列)。[~,latent,coeff] = svd(v); 其实这里可以用eig函数替代latent = diag(latent);
TSQUARED,返回X中每个观测值的Hotelling T平方统计值。PCA使用所有主分量计算TSQUARED(在整个空间中计算),即使请求的组件较少(请参见下面的“NumComponents”选项)。对于缩小空间中的TSQUARED,使用MAHAL(SCORE,SCORE)。
EXPLAINED,返回一个向量,其中包含每个主成分方差占总方差的百分比。(每个特征值占比,字面上即每个特征值对系统有多少解释,用百分比表示。)*explained=100**latent/sum(latent);
MU,“Centered”设置为true时返回估计的平均值MU;设置为false时返回所有零。

2.PCA函数的使用方法

X=load('111.txt');
[coeff, score, latent, tsquared, explained, mu]=pca(X);
a=cumsum(latent)./sum(latent);   % 计算特征的累计贡献率
% explained和latent均可用来计算降维后取多少维度能够达到自己需要的精度,且效果等价。
% explained=100*latent./sum(latent); 
idx=find(a>0.9);     % 将特征的累计贡献率不小于0.9的维数作为PCA降维后特征的个数
k=idx(1);
Feature=score(:,1:k);   % 取转换后的矩阵score的前k列为PCA降维后特征

转自
另:matlab pca函数的详细参数解析及使用方法 可参考

方法二:

思路

1:用zscore函数对原始数据S进行标准化。

2:用cov函数求出标准化后的数据的协方差。

3:求出此协方差的特征向量与特征根(eig函数)。

4:将产生的特征向量依据特征根大小从大到小进行排列(即将特征向量按列倒序)。

5:依据需求取出倒序后的向量的前几列(一般根据特征根来算贡献率,使得累计贡献率大于85%),组成新的矩阵T

6:做S*T得到分析后的新的数据。

7:依据特征根算贡献率,并绘图。

代码

X=load('shuju.txt')
z=zscore(X)               %数据标准化
M=cov(z)                  %协方差
[V,D]=eig(M);             %求出协方差矩阵的特征向量、特征根
d=diag(D);                %取出特征根矩阵列向量(提取出每一主成分的贡献率)
eig1=sort(d,'descend')      %将贡献率按从大到小元素排列
v=fliplr(V)                %依照D重新排列特征向量
S=0;
i=0;
while S/sum(eig1)<0.85
    i=i+1;
    S=S+eig1(i);
end                         %求出累积贡献率大于85%的主成分
NEW=z*v(:,1:i)              %输出产生的新坐标下的数据
W=100*eig1/sum(eig1)
figure(1)
pareto(W);                  %画出贡献率的直方图

方法三:

思路

1:用zscore函数对原始数据S进行标准化,(同方法二)。

2:利用matlab自带的princomp函数直接求得其特征向量,新坐标下的数据,特征根(并且已经排列好了)。

3:选择恰当的前几项主成分与标准化后的数据相乘。得到在新坐标下的数据。

4:如方法一,利用特征根算贡献率。

代码

X=load('shuju.txt')
x=zscore(X)                       %标准化
[coef,score,eig,t]=princomp(x);   %利用princomp处理矩阵
t                                 %每一组数据在新坐标下到原点的距离
s=0;
i=1;
while s/sum(eig)<0.85
    s=s+eig(i);
    i=i+1;
end                              %获得累计贡献率大于85%几组数据
NEW=x*coef(:,1:i-1)              %输出新的数据
figure
pareto(eig/sum(eig));          %输出贡献率直方图
figure(2)
plot(eig,'r+');
hold on
plot(eig,'b-');

引用自博主: It_BeeCoder 《关于主成分分析matlab代码实现的总结》

方法四

代码

clc,clear
data = load('gd.txt');%将原始数据保存在txt文件中
data=zscore(data);     %数据的标准化
r=corrcoef(data);      %计算相关系数矩阵r
%下面利用相关系数矩阵进行主成分分析,vec1的第一列为r的第一特征向量,即主成分的系数
[vec1,lamda,rate]=pcacov(r);                 %lamda为r的特征值,rate为各个主成分的贡献率
f=repmat(sign(sum(vec1)),size(vec1,1),1);    %构造与vec1同维数的元素为±1的矩阵
vec2=vec1.*f;             %修改特征向量的正负号,使得每个特征向量的分量和为正,即为最终的特征向量
num = max(find(lamda>1)); %num为选取的主成分的个数,这里选取特征值大于1的
df=data*vec2(:,1:num);    %计算各个主成分的得分
tf=df*rate(1:num)/100;    %计算综合得分
[stf,ind]=sort(tf,'descend');  %把得分按照从高到低的次序排列
stf=stf'; ind=ind';            %stf为得分从高到低排序,ind为对应的样本编号