2009-10-08 153 views
4

我试图将高维数据集减少到2-D。但是,我无法预先访问整个数据集。所以,我想生成一个函数,它需要一个N维向量并返回一个二维向量,这样,如果我给它在N维空间中靠近的向量,结果在二维空间。减少尺寸

我以为SVD是我需要的答案,但我无法让它工作。

为简单起见,设N = 3并假设我有15个数据点。如果我在15x3矩阵X中预先获得所有数据,则:

[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,:); 

做我想要的。但是,假设我得到一个新的数据点A,一个1x3向量。有没有办法使用U,S或V来将A转换为合适的1x2向量?

如果SVD是一个失败的原因,有人可以告诉我应该做什么吗?

注意:这是Matlab代码,但我不在乎答案是C,Java还是数学。如果你不能阅读Matlab,请问,我会澄清。

+2

呃,s和s真的会欺骗眼睛。 ;) – 2009-10-08 17:02:47

回答

3

SVD是一种很好的方法(可能)。 LSA(潜在语义分析)是基于它的,基本上具有相同的维度方法。我已经在这里详细讨论过了(最后): lsa-latent-semantic-analysis-how-to-code-it-in-php或者查看SO上的LSA标签。

我意识到这是一个不完整的答案。霍勒,如果你想更多的帮助!

+0

谢谢,这是有帮助的。为了将U变成U',我是否简单地截断了第二列之后的所有内容,还是比这更有趣? – PlexLuthor 2009-10-08 15:57:53

+0

我很确定它就是这么简单(假设matlab命令栏中的列和特征值对应) – 2009-10-08 16:07:43

+0

好的。我只是以我认为你说的方式工作,但我仍然无法获取新的三维数据,并且无需重新计算整个UxSxV集合即可得到二维投影。我错过了LSA的一些东西吗?也就是说,我有X(15x3),U,S,V,U',S',V',现在我得到A(1x3)。我应该做些什么来获得1x2版本的A? – PlexLuthor 2009-10-08 16:40:17

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

我不认为有一种内置的方式来更新Matlab内现有的SVD。我google'd为“SVD更新”,并找到了许多结果中的this paper