有关Pca的使用:样本数目和降维数目的关系

来源:互联网 发布:软件研发部 职能 编辑:程序博客网 时间:2024/06/06 20:25

先说我的结论:降维后维数一定要小于数据样本数

最近在做扭曲图形的识别,思路是用使用一幅静态图像,建立扭曲方程,生成一系列不同形态的扭曲图像,再做Pca降维,生成10个特征基向量,任何一幅扭曲图像都向基向量投影,产生10个特征系数,根据特征系数做识别,其实就是特征脸的过程。


写这篇文章的主要原因是我在网上搜索Pca,发现有一篇文章很火:PCA降维算法总结以及matlab实现PCA(个人的一点理解),被很多人转载,至于我也搞不清原创到底是谁;但不得不说,经过我的思考,我认为这篇文章中有些内容(即样本数目和降维数目关系)是有问题的,特在此讨论一下,希望得到更多人的意见和看法。


首先还是从Matlab中的Pca函数说起

之前自以为对Pca的原理比较清楚,但使用Matlab自带的pca函数时,有些问题困扰了我。下面先介绍一下matlab中pca函数的基本使用:

简单来说,X是n*p矩阵,每一行对应一个样本,每一列对应一个变量,返回值为特征矩阵。

下面实验一下,首先假设X=1024*190,即有1024个样本,数据维数为190:

eff1 = pca(X);size(eff1)190,190;Xp = X*eff1(:,1:10);size(Xp)1024,10;

上面就是把190维数据降到10维的过程,再来看看当X=190*1024时,按理来说此时得到的eff应该是1024*1024,但是:

eff2 = pca(X');size(eff2)1024,189;

特征向量矩阵竟然只有1024*189大小,这意味着,当再做降维(投影时),原数据的第二维尺寸肯定小于等于189,即降维尺寸要小于数据样本数!此外,不光是Matlab自带的pca函数,国外常用的机器学习工具箱pca函数(如下)也是要求降维后尺寸小于等于样本数的,感兴趣的可以尝试一下。

X还是n*p数据,no_dims代表需要保留维数或者需要保留的数据差异性(0~1);mappedX是降维后数据,mapping为投影矩阵。

function [mappedX, mapping] = pca(X, no_dims)%PCA Perform the PCA algorithm%%   [mappedX, mapping] = pca(X, no_dims)%% The function runs PCA on a set of datapoints X. The variable% no_dims sets the number of dimensions of the feature points in the % embedded feature space (no_dims >= 1, default = 2). % For no_dims, you can also specify a number between 0 and 1, determining % the amount of variance you want to retain in the PCA step.% The function returns the locations of the embedded trainingdata in % mappedX. Furthermore, it returns information on the mapping in mapping.%%% This file is part of the Matlab Toolbox for Dimensionality Reduction.% The toolbox can be obtained from http://homepage.tudelft.nl/19j49% You are free to use, change, or redistribute this code in any way you% want for non-commercial purposes. However, it is appreciated if you % maintain the name of the original author.%% (C) Laurens van der Maaten, Delft University of Technology    if ~exist('no_dims', 'var')        no_dims = 2;    end% Make sure data is zero mean    mapping.mean = mean(X, 1);X = bsxfun(@minus, X, mapping.mean);% Compute covariance matrix    if size(X, 2) < size(X, 1)        C = cov(X);          else        C = (1 / size(X, 1)) * (X * X');        % if N>D, we better use this matrix for the eigendecomposition    end% Perform eigendecomposition of CC(isnan(C)) = 0;C(isinf(C)) = 0;    [M, lambda] = eig(C);        % Sort eigenvectors in descending order    [lambda, ind] = sort(diag(lambda), 'descend');    if no_dims < 1        no_dims = find(cumsum(lambda ./ sum(lambda)) >= no_dims, 1, 'first');        disp(['Embedding into ' num2str(no_dims) ' dimensions.']);    end    if no_dims > size(M, 2)        no_dims = size(M, 2);        warning(['Target dimensionality reduced to ' num2str(no_dims) '.']);    endM = M(:,ind(1:no_dims));    lambda = lambda(1:no_dims);% Apply mapping on the data    if ~(size(X, 2) < size(X, 1))        M = bsxfun(@times, X' * M, (1 ./ sqrt(size(X, 1) .* lambda))');     % normalize in order to get eigenvectors of covariance matrix    end    mappedX = X * M;        % Store information for out-of-sample extension    mapping.M = M;mapping.lambda = lambda;

再来说说那篇被广泛转载的博客中:

在我看来,博主应该是理解错他朋友的话了,这句话的想表达的意思应该是降维后数据维数肯定要小于样本数量,而不是降维之前。

当然我这里绝不是吹毛求疵,也不是批评这位博主,只是这个问题的确困扰了我,所以在此提出,希望得到更多讨论。


最后说说为什么降维后数据特征数一定小于样本数?

简单来说,就是确定一直线至少需要两点,确定一平面至少需要三点,确定n维空间至少需要n点。Pca是将原数据投影到新的空间,因此对于样本数n来说,最多确定n维空间。

其实举一个例子就很直观:

上图就是一个将2维数据降维到1维数据的过程,样本数目大于1(降维后维数),可以找到一条直线使得所有点的投影误差和最小,降维过程是有意义的;但如果样本数目不大于1,即只有一个样本,此时降维的过程就意义不大了,因为任取一个过该点的轴都可以使得投影误差最小,即可确定无数子空间。


如有问题,敬请指正!

0 0