我有一个距离矩阵,其尺寸为1000x1000,沿对角线对称为0。我想通过同时重新排序矩阵的行和列来形成距离(簇)的分组。这就像在使用热图可视化其聚类之前重新排序矩阵一样。我觉得这应该是一个简单的问题,但我没有太多运气找到在线进行排列的代码。有人可以帮忙吗?
答案 0 :(得分:18)
这是一种想到的方法:
我将使用Octave(我正在做的一切也应该在Matlab中工作)因为它内置了反向Cuthill-McKee(RCM)实现。
首先,我们需要生成距离矩阵。此函数创建一组随机点及其距离矩阵:
function [x, y, A] = make_rand_dist_matrix(n)
x = rand(n, 1);
y = rand(n, 1);
A = sqrt((repmat(x, 1, n) - repmat(x', n, 1)).^2 +
(repmat(y, 1, n) - repmat(y', n, 1)).^2);
end
让我们使用它来生成和可视化100点示例。
[x, y, A] = make_rand_dist_matrix(100);
surf(A);
从上面查看表面图得到下面的图像(当然,你的图像会不同)。
暖色代表比冷色更远的距离。矩阵中的行(或列,如果您愿意)i
包含点i
与所有点之间的距离。点i
和点j
之间的距离位于条目A(i, j)
中。我们的目标是重新排序矩阵,使与点i
对应的行靠近与i
相距很近的点的行。
稀疏化A
的一种简单方法是使所有条目都大于某个阈值零,这就是下面所做的,尽管更复杂的方法可能会更有效。
B = A < 0.2; % sparsify A -- only values less than 0.2 are nonzeros in B
p = symrcm(B); % compute reordering by Reverse Cuthill-McKee
surf(A(p, p)); % visualize reordered distance matrix
现在,矩阵的排序方式使矩阵中的附近点更加接近。当然,这个结果并不是最佳的。使用启发式算法计算稀疏矩阵带宽压缩,并且RCM是一种非常简单的方法。如上所述,生成稀疏矩阵的更复杂方法可能会产生更好的结果,不同的算法也可能会产生更好的结果。
另一种看待发生的事情的方法是绘制点并连接一对点,如果它们在矩阵中的相应行是相邻的。你的目标是让线条连接彼此靠近的点对。为了获得更具戏剧性的效果,我们使用比上述更多的点。
[x, y, A] = make_rand_dist_matrix(2000);
plot(x, y); % plot the points in their initial, random order
显然,连接遍布整个地方,并且发生在各种各样的距离上。
B = A < 0.2; % sparsify A
p = symrcm(B);
plot(x(p), y(p)) % plot the reordered points
重新排序后,连接的距离会更小,而且更有序。
答案 1 :(得分:2)