2010-12-09 76 views
7

Je suis en train de mettre en œuvre la PCA en utilisant la décomposition des valeurs propres pour des données éparses. Je sais que matlab a implémenté PCA, mais cela m'aide à comprendre toutes les technicités quand j'écris du code. J'ai suivi les conseils de here, mais j'obtiens des résultats différents par rapport à la fonction intégrée princomp.Analyse en composantes principales dans MATLAB

Quelqu'un pourrait-il regarder et me diriger dans la bonne direction.

Voici le code:

function [mu, Ev, Val ] = pca(data) 

% mu - mean image 
% Ev - matrix whose columns are the eigenvectors corresponding to the eigen 
% values Val 
% Val - eigenvalues 

if nargin ~= 1 
error ('usage: [mu,E,Values] = pca_q1(data)'); 
end 

mu = mean(data)'; 

nimages = size(data,2); 

for i = 1:nimages 
data(:,i) = data(:,i)-mu(i); 
end 

L = data'*data; 
[Ev, Vals] = eig(L);  
[Ev,Vals] = sort(Ev,Vals); 

% computing eigenvector of the real covariance matrix 
Ev = data * Ev; 

Val = diag(Vals); 
Vals = Vals/(nimages - 1); 

% normalize Ev to unit length 
proper = 0; 
for i = 1:nimages 
Ev(:,i) = Ev(:,1)/norm(Ev(:,i)); 
if Vals(i) < 0.00001 
    Ev(:,i) = zeros(size(Ev,1),1); 
else 
    proper = proper+1; 
end; 
end; 

Ev = Ev(:,1:nimages); 

Répondre

10

Voilà comment je le ferais:

function [V newX D] = myPCA(X) 
    X = bsxfun(@minus, X, mean(X,1));   %# zero-center 
    C = (X'*X)./(size(X,1)-1);     %'# cov(X) 

    [V D] = eig(C); 
    [D order] = sort(diag(D), 'descend');  %# sort cols high to low 
    V = V(:,order); 

    newX = X*V(:,1:end); 
end 

et un exemple pour la comparer à la fonction PRINCOMP de la statistique Boîte à outils:

load fisheriris 

[V newX D] = myPCA(meas); 
[PC newData Var] = princomp(meas); 

Vous pourriez aussi être intéressé par ce poste relatif à l'exécution PCA by SVD.

+0

Je veux demander quelque chose, Est-ce que 'princomp' trie les données de' COEFF' par 'latent' par défaut (réf: http://www.mathworks.com/help/stats/princomp.html)? Quelle est la différence entre votre fonction et 'princomp' –

+0

Je veux utiliser' coeff' et 'latent' où' coeff' est trié avec 'latents'. Puis-je utiliser la fonction intégrée 'princomp' ou votre' myPCA'? –

+0

@AhsanAli: évidemment, comme le montre l'exemple ci-dessus, les deux fonctions produisent la même sortie (jusqu'à une certaine précision); les colonnes de 'COEFF' (composants principaux) sont triées par ordre décroissant en termes de variance de composant' LATENT'. Vérifiez également le dernier lien mentionné ci-dessus sur la réalisation de PCA en utilisant SVD au lieu de EIG .. Notez que ['princomp'] (http://www.mathworks.com/help/stats/princomp.html) est remplacé par [' pca '] (http://www.mathworks.com/help/stats/pca.html) fonctionnent dans les éditions récentes (en fait, vérifiez le code source pour voir que les appels à' princomp' sont routés vers 'pca' en interne). – Amro