3

我有一个数据集,Xm x 2,三个向量存储在一个矩阵C = [c1'; c2'; c3']中,即3 x 2。我正在尝试对我的代码进行矢量化,该代码为 中的每个数据点找到最接近X的向量C(平方距离)。我想从 inC的每个向量(行)中减去每个向量(行)X,从而得到的元素和 的元素之间的差异m x 6或矩阵。我当前的实现一次只做一行:3m x 2XCX

for i = 1:size(X, 1)
    diffs = bsxfun(@minus, X(i,:), C);    % gives a 3 x 2 matrix result
    [~, idx(i)] = min(sumsq(diffs), 2);   % returns the index of the closest vector
                                          % in C to the ith vector in X
end

我想摆脱这个for循环,只是矢量化整个事情,但是bsxfun(@minus, X, C)在 Octave 中给了我一个错误:

错误:bsxfun:尺寸不一致:300x2 和 3x2

有什么想法可以“超级广播”这两个矩阵之间的减法运算吗?

4

2 回答 2

5

这个问题的核心是计算一个D大小的距离矩阵,m x 3其中包含 中的所有数据点X和 中的所有数据点之间的成对距离C。第 i 个向量x_iinX和第 j 个向量c_jin之间的欧几里得距离C可以重写为:

|x_i-c_j|^2 = |x_i|^2 - 2<x_i, c_j> + |c_j|^2

其中 <,> 指的是内积。这个方程的右边可以很容易地向量化,因为所有对的内积X * C'就是 BLAS3 操作。dist2这种计算距离矩阵的方法在 Christopher Bishop 的《模式识别和机器学习》一书中被称为函数。我复制下面的函数并稍作修改。

function D = dist2(X, C)        
    tempx = full(sum(X.^2, 2));
    tempc = full(sum(C.^2, 2).');
    D = -2*(X * C.');
    D = bsxfun(@plus, D, tempx);
    D = bsxfun(@plus, D, tempc);

这里full用于万一X或者C是一个稀疏矩阵。

注意:由于数值舍入误差,以这种方式计算的距离矩阵D可能有微小的负条目。为了防止这种情况,请使用

D = max(D, 0);

C可以从 中检索最近向量的索引D

[~, idx] = min(D, [], 2);
于 2013-06-18T21:13:36.817 回答
0

如果你有统计工具箱,你可以使用pdist2

PDIST2 两组观测值之间的成对距离。D = PDIST2(X,Y) 返回一个矩阵 D,其中包含 MX-by-N 数据矩阵 X 和 MY-by-N 数据矩阵 Y 中每对观测值之间的欧几里得距离。

所以在你的情况下,

[~, which_C] = min(pdist2(X,C), [], 2);

就是你要找的。

或者,您可以使用这种美感:

[~, which_c] = min(sum(bsxfun(@minus, X, permute(C, [3 2 1])).^2, 2), [], 3);

它不会因可读性、健壮性或可管理性而赢得任何奖项,但您将获得一些速度(并且需要工具箱,请注意 :)

于 2013-06-18T21:26:40.560 回答