2009-10-08 18 views
4

J'essaie de réduire un ensemble de données de grande dimension en 2D. Cependant, je n'ai pas accès à l'intégralité du jeu de données à l'avance. Donc, je voudrais générer une fonction qui prend un vecteur N-dimensionnel et renvoie un vecteur bidimensionnel, de sorte que si je le donne à des vecteurs proches dans l'espace N-dimensionnel, les résultats sont proches en 2 dimensions espace. Je pensais que SVD était la réponse dont j'avais besoin, mais je ne peux pas le faire fonctionner. Pour simplifier, laissez N = 3 et supposons que j'ai 15 points de données. Si j'ai toutes les données à l'avance dans une matrice X 15x3, alors:Réduction des dimensions

[U, S, V] = svd(X); 
s = S; %s is a the reduced version of S, since matlab is case-sensitive. 
s(3:end,3:end)=0; 
Y=U*s; 
Y=Y(1:2,:); 

fait ce que je veux. Mais supposons que j'obtiens un nouveau point de donnée, A, un vecteur 1x3. Existe-t-il un moyen d'utiliser U, S ou V pour transformer A en le vecteur 1x2 approprié?

Si la SVD est une cause perdue, quelqu'un peut-il me dire ce que je devrais faire à la place?

Note: Ceci est du code Matlab, mais peu m'importe si la réponse est C, Java, ou juste mathématique. Si vous ne pouvez pas lire Matlab, demandez et je vais clarifier.

+2

Ugh, s vs S trompe vraiment l'oeil. ;) –

Répondre

3

SVD est une approche fine (probablement). LSA (Latent Semantic Analysis) est basé autour d'elle, et a fondamentalement la même approche de dimensionnalité. J'ai parlé de cela (en longueur) à: lsa-latent-semantic-analysis-how-to-code-it-in-php ou consultez l'étiquette LSA ici sur SO. Je sais que c'est une réponse incomplète. Holler si vous voulez plus d'aide!

+0

Merci, c'était utile. Pour transformer U en U ', est-ce que je tronque tout simplement après la deuxième colonne, ou est-ce plus fantaisiste que ça? – PlexLuthor

+0

Je suis assez sûr que c'est aussi simple que ça (en supposant que matlab ordonne les colonnes de telle sorte que les cols et les vecteurs propres correspondent) –

+0

Ok. Je me suis contenté de jouer comme je le pensais, mais je ne peux toujours pas prendre de nouvelles données 3D et obtenir la projection 2D sans recalculer l'ensemble UxSxV. Ai-je raté quelque chose dans LSA? C'est-à-dire que j'ai X (15x3), U, S, V, U ', S', V ', et maintenant je reçois A (1x3). Que dois-je faire pour obtenir une version 1x2 de A? – PlexLuthor

2
% generate some random data (each row is a d-dimensional datapoint) 
%data = rand(200, 4); 
load fisheriris 
data = meas;  % 150 instances of 4-dim 

% center data 
X = bsxfun(@minus, data, mean(data)); 

% SVD 
[U S V] = svd(X, 'econ');  % X = U*S*V'' 

% lets keep k-components so that 95% of the data variance is explained 
variances = diag(S).^2/(size(X,1)-1); 
varExplained = 100 * variances./sum(variances); 
index = 1+sum(~(cumsum(varExplained)>95)); 

% projected data = X*V = U*S 
newX = X * V(:,1:index); 
biplot(V(:,1:index), 'scores',newX, 'varlabels',{'d1' 'd2' 'd3' 'd4'}); 

% mapping function (x is a row vector, or a matrix with multiple rows vectors) 
mapFunc = @(x) x * V(:,1:index); 
mapFunc([1 2 3 4]) 
0

Je ne pense pas qu'il existe un moyen intégré de mettre à jour un SVD existant dans Matlab. Je google'd pour "mise à jour SVD" et trouvé this paper parmi les nombreux résultats.