PCA:eig,eigs,princomp

来源:互联网 发布:日文手写输入在线软件 编辑:程序博客网 时间:2024/06/03 02:25


个人觉得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*dC = 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*nC = 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;

2 0
原创粉丝点击