【问题标题】:Remove for loop from clustering algorithm in MATLAB从 MATLAB 中的聚类算法中删除 for 循环
【发布时间】:2015-09-25 15:30:39
【问题描述】:

我正在尝试提高 OPTICS 聚类算法的性能。我在开源中找到的实现对每个样本都使用了一个 for 循环,并且可以运行几个小时......

我相信当系统有足够的 RAM 时,使用 repmat() 函数可能有助于提高其性能。 非常欢迎您提出其他改进实施的方法。

代码如下:

x 是数据:一个 [mxn] 数组,其中 m 是样本大小,n 是特征维数,大多数时候显着大于 1。

[m,n] = size(x);

for i = 1:m
    D(i,:) = sum(((repmat(x(i,:),m,1)-x).^2),2).';
end

非常感谢。

【问题讨论】:

  • for 循环可能不是问题所在。您是否尝试过探查器来查看瓶颈在哪里?我建议使用小版本的 x 并将行中的每个函数分开。然后分析器会告诉你哪个部分花费的时间最多。
  • 另外,您正在创建一行全零,然后自平方,然后求和。使用 2 个循环并避免 repmat 有利于对非零行进行操作可能会更快。你也预分配 D 数组吗?
  • 为了获得性能,你真的很想使用索引。尝试 ELKI 版本,启用 k-d-tree 或类似索引,然后使用足够大的 epsilon 运行 OPTICS。您会对性能差异感到惊讶!我只有 Octave 而不是 Matlab,但 ELKI 的速度要快 100 倍到 1000 倍。
  • this posted solution 是否有助于减少运行时间?
  • 请看下面我的回复

标签: algorithm performance matlab cluster-analysis vectorization


【解决方案1】:

有足够的 RAM 可以使用,您可以在这里使用几种方法。

方法 #1: 使用 bsxfunpermute -

D = squeeze(sum(bsxfun(@minus,permute(x,[3 2 1]),x).^2,2))

方法 #2: 使用 pdistsquareform -

D = squareform(pdist(x).^2)

方法 #3 使用 matrix-multiplication based euclidean distance calculations -

xt = x.';  %//'
[m,n] = size(x);
D = [x.^2 ones(size(x)) -2*x ]*[ones(size(xt)) ; xt.^2 ; xt];
D(1:m+1:end) = 0;

对于性能,我的赌注是方法 #3!

【讨论】:

  • 您好,首先感谢您的回复。我已经测试了你所有的方法,它们都给出了相同的结果,但是,它与原始算法获得的结果不同。我会尝试调试它,也许您可​​以尝试相同。我可以证明它们确实明显更快,大约 100% 计算明智。
  • 我 +1d 你的链接 #3 方法发布顺便说一句,因为它提供了丰富的信息。
  • 好吧,又搞砸了。版本 1 给出了完全相同的结果,版本 2 给出了可以忽略的错误。两个版本的运行时间都与我的版本差不多。版本 3 确实是最快的,但仍然会产生错误。我正在进一步研究它。
  • 获得了版本 3 与数据集相比可以忽略不计的差异。错误的原因是我不得不猜测我在描述中没有使用的变量“M”是什么意思(我猜它是“m”,它是“x”)。唯一剩下的问题是第一列会产生小的负数,它应该等于 0。我手动将其归零,但我会更深入地研究并理解你的方法。谢谢。
  • @user2324712 抱歉,M 一定会造成混淆。基本上,这些对角线值与精确零点略有偏差,所以这条线 D(1:m+1:end) = 0; 纠正了它。编辑方法 #3 以纠正令人困惑的 M 部分。请检查一下!
猜你喜欢
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 2021-07-04
  • 2014-08-13
  • 1970-01-01
相关资源
最近更新 更多