我仍在围绕矢量化,我正在努力解决我所做的以下功能......
for i = 1:size(X, 1)
min_n = inf;
for j=1:K
val = X(i,:)' - centroids(j,:)';
diff = val'*val;
if (diff < min_n)
idx(i) = j;
min_n = diff;
end
end
end
X
是一个(x,y)
坐标数组......
2 5
5 6
...
...
此示例中的 centroids
限制为3行。它也是(x,y)
格式,如上所示。
对于X
中的每一对,我正在计算最接近的centroids
对。然后我将质心的索引存储在idx
。
所以idx(i) = j
表示我将质心的索引j
存储在索引i
,其中i
对应于X
的索引。这意味着与X(i, :)
配对的最近质心位于idx(i)
。
我可以通过矢量化来简化这个吗?我很难对内循环进行矢量化。
答案 0 :(得分:4)
以下是三个选项。但请注意,与双循环相比,向量化的缺点是它一次存储所有差异运算结果,这意味着如果矩阵有很多行,则可能会耗尽内存。另一方面,矢量化方法可能要快得多。
如果您有权访问Statistics and Machine Learning Toolbox,则可以使用函数pdist2
来获取两个矩阵之间的所有成对距离。然后,min
函数为您提供结果每列的最小值。它的第一个返回值是最小值,第二个是索引,这是idx
所需的值:
diff = pdist2(centroids,X);
[~,idx] = min(diff);
如果您无权访问工具箱,则可以使用bsxfun
。这将允许您计算两个矩阵之间的差异运算,即使它们的尺寸不一致。您需要做的就是使用shiftdim
重塑X'
,使其大小为[1,size(X,2),size(X,1)]
,然后reshapedX
和centroids
与其尺寸兼容(请参阅bsxfun
)的文档。这使您可以获取它们的值之间的差异。结果是一个三维数组,您需要沿第二维求和,以获得行之间差异的范数。此时,您可以按照选项1进行操作。
reshapedX = shiftdim(X',-1);
diff = bsxfun(@minus,centroids,reshapedX);
diff = squeeze(sum(diff.^2,2));
[~,idx] = min(diff);
注意:从Matlab版本2016b开始,the bsxfun
is used implicitly并且您不再需要调用它。因此,bsxfun
行可以替换为更简单的行diff = centroids-reshapedX
。
使用功能dsearchn
,它完全符合您的需要:
idx = dsearchn(centroids,X);
答案 1 :(得分:3)
可以使用pdist2
- 两个矩阵的行之间的成对距离来完成:
% random data
X = rand(500,2);
centroids = rand(3,2);
% pairwise distances
D = pdist2(X,centroids);
% closest centroid index for each X coordinates
[~,idx] = min(D,[],2)
% plot
scatter(centroids(:,1),centroids(:,2),300,(1:size(centroids,1))','filled');
hold on;
scatter(X(:,1),X(:,2),30,idx);
legend('Centroids','data');