有關Pca的使用:樣本數目和降維數目的關係

先說我的結論:降維後維數一定要小於數據樣本數

最近在做扭曲圖形的識別,思路是用使用一幅靜態圖像,建立扭曲方程,生成一系列不同形態的扭曲圖像,再做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 C
	C(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) '.']);
    end
	M = 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,即只有一個樣本,此時降維的過程就意義不大了,因爲任取一個過該點的軸都可以使得投影誤差最小,即可確定無數子空間。


如有問題,敬請指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章