降维

4
我正在尝试将一个高维数据集减少为二维。但是,我无法提前访问整个数据集。因此,我想生成一个函数,该函数接受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向量?

如果奇异值分解方法行不通,有人能告诉我应该做些什么吗?

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


2
啊,s和S真的很容易让人眼花。 ;) - Alex Feinman
3个回答

3
SVD可能是一种不错的方法。LSA(潜在语义分析)基于此,并且基本上具有相同的维度方法。我已经详细讨论了这个问题: 在这里,或者在SO上查看LSA标签。
我意识到这是一个不完整的答案。如果需要更多帮助,请告诉我!

谢谢,这很有帮助。为了将U转化为U',我只需要截取第二列后面的所有内容吗?还是需要更高级的操作? - PlexLuthor
我非常确定它就是这么简单的(假设Matlab按照列的顺序排列,使得列和特征值对应)。 - Gregg Lind
好的。我按照我认为你说的方式进行了尝试,但是我仍然无法在不重新计算整个UxSxV集合的情况下获取新的3D数据并得到2D投影。我在LSA中错过了什么吗?也就是说,我有X(15x3),U,S,V,U',S',V',现在我得到了A(1x3)。我应该怎么做才能得到A的1x2版本? - PlexLuthor
嗯,除以V*就是我要找的。我不知道为什么之前错过了它。 - PlexLuthor
听起来你已经掌握得很好了 :) 我总是记不住确切的公式,所以我只是胡乱尝试,直到我得到正确大小的矩阵,就像你一样! - Gregg Lind

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。我谷歌搜索了“SVD update”,在众多结果中找到了this paper


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接