PCA:eig,eigs,princomp

  • Post author:
  • Post category:其他





个人觉得

PCA数学原理

这篇文章是学习PCA最好的博文,通俗易懂~~~



本文简单的记录自己学习PCA时候遇到的一些小问题,好记性不如烂笔头~~~~




1. 数据格式问题






2. cov函数的问题








3. eig、eigs、princomp












开始之前,说明一些变量:



X:表示数据集,C:表示协方差矩阵。






**********************************************************************************************************************************






针对以下两种数据存储格式,分别介绍。



(1)

X: n*d

说明:n表示样本数目,d表示每个样本的特征纬度。





即:

每行代表一个样本








X = X -repmat(mean(X,1),size(X,1),1); % 去均值:依然是n*d
C = X'*X./(size(X,1)-1);              % 协方差:变为d*d,因为计算的是每个纬度之间的关系,不是每个样本之间的相关性。这点务必理解。



这两行代码与下面一行代码是等价的:选其中一种就可以了

C = cov(X);







然后我们来看一下eig、eigs两者的问题:



eig:给出矩阵的所有特征向量和特征值

[F1, V] = eig(C);                       % V:每一列是一个特征值,F1:每一列就是与特征值对应的特征向量。
[V1, order] =sort(diag(V),'descend');   % 因为得到的特征值和特征向量没有排序,所以要排序。
F = F1(:,order);




eigs:通过迭代给出


指定数量(默认为6)的


矩阵的特征向量和特征值


[F, V] = eigs(double(C),k);                     % k:指定返回的特征值和特征向量的数量。
而且默认是降序排序,不需要重新sort了。



那么最终降维后的结果就是:


Y = X*F                                 % 维度变化:n*d*d*k=n*k,实现了PCA降维







**********************************************************************************************************************************





(2)

X: d*n

说明:n表示样本数目,d表示每个样本的特征纬度。









即:

每列代表一个样本












X = X -repmat(mean(X,2),1,size(X,2)); % 去均值:依然是d*n
C = X*X'./(size(X,2)-1);              % 协方差:变为d*d,注意与第一种情况的区别。



这两行代码与下面一行代码是等价的:

C = cov(X');                          <span style="font-family: Arial, Helvetica, sans-serif;">%  注意与第一种情况的区别。</span>



然后我们来看一下eig、eigs两者的问题:



eig: 同上

[F1, V] = eig(C);                       % V:每一列是一个特征值,F1:每一列就是与特征值对应的特征向量。
[V1, order] =sort(diag(V),'descend');   % 因为得到的特征值和特征向量没有排序,所以要排序。
F = F1(:,order);




eigs:同上


[F, V] = eigs(double(C),k);                     % k:指定返回的特征值和特征向量的数量。
而且默认是降序排序,不需要重新sort了。



那么最终降维后的结果就是:


Y = F'*X                                % 维度变化:[d*k]'*d*n=k*n,实现了PCA降维






**********************************************************************************************************************************
















matlab自带的PCA函数了:princomp



常用格式:

[coef, score, latent, T2] = princomp(X);
% 注意:X是n*d,即每一行是一个样本
% coef: 特征向量矩阵(投影/映射矩阵),和排序后的eig()/eigs()返回的 F 是一样的,按列存放。 维度:d*d
% score:得分矩阵,就是在新的基空间中的坐标,就是投影后的坐标。                             维度:n*d
% latent:特征向量,默认已经降序排列。                                                       维度:d*1

score = bsxfun(@minus,X,mean(X,1)*coef);

X  = bsxfun(@plus,score*inv(coef),mean(X,1)).



**********************************************************************************************************************************




最关心的部分来啦,三者到底什么关系?





(前提:X:n*d)





(1)参数是X



[coef, score, latent, T2] = princomp(X);




(2)参数是C



C = cov(X);


[F1, V] = eig(C);                       % V:每一列是一个特征值,F1:每一列就是与特征值对应的特征向量。
[V1, order] =sort(diag(V),'descend');   % 因为得到的特征值和特征向量没有排序,所以要排序。
F = F1(:,order);



(3)


参数是C,k




C = cov(X);


[F, V] = eigs(double(C),k);








答案:代码片段1中的coef,代码片段2和3中的F,计算结果是一模一样的啦。



**********************************************************************************************************************************



princomp(zscore(x))是做什么的?







zscore()函数是标注化,目的:使得X均值为0,标准差为1。原理:去均值,再除以标准差。



即:zscore(x) = (x-mean(x))./std(x)



需要注意的是,std(x)有两种:(图片来自互联网,感谢原作者)



zscore(x)=zscore(x,0)   std部分使用的是公式1;


zscore(x,1)                    std部分使用的是公式2.




********************************************************************************************************************************




MATLAB中cov(x)与cov(x,1)的区别?






matlab中计算协方差是首先加了n项,然后除以n或n-1,cov(x)呢是除以n-1,cov(x,1)呢是除以n。

cov(x)是无偏估计,

cov(x,1)是最大似然估计。

cov(x,1)=cov(x)*(n-1)/n;




版权声明:本文为lilai619原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。