2

我有以下脚本 ( optics.py) 来估计具有预先计算距离的聚类:

from sklearn.cluster import OPTICS
import numpy as np

distances = np.load(r'distances.npy')
clust = OPTICS(metric='precomputed', n_jobs=-1)
clust = clust.fit(distances)

查看 htop 结果我可以看到只使用了一个 CPU 内核

在此处输入图像描述

尽管 scikit 在多个进程中运行集群:

在此处输入图像描述

为什么n_jobs=-1没有导致使用所有 CPU 内核?

4

3 回答 3

2

我是 sklearn OPTICS 模块的主要作者。并行是困难的,因为有一个排序循环不能并行运行;也就是说,计算量最大的任务是距离计算,这些可以并行运行。更具体地说,sklearn OPTICS 一次计算一行上三角距离矩阵,从“n”个距离查找开始,然后减少到“n-1,n-2”个查找,总共 n-squared / 2 距离计算。 ..问题是sklearn中的并行性通常由joblib处理,它使用进程(而不是线程),当在循环中使用时,创建和销毁的开销相当高。(即,您在遍历数据集时创建和销毁每行的进程工作者,并且进程的“n”个设置/拆卸具有更多的开销,然后您从 joblib 获得的并行性好处——这就是为什么 njobs 对 OPTICS 被禁用的原因)

在 OPTICS 中“强制”并行性的最佳方法可能是定义一个并行运行的自定义距离度量——参见这篇文章以获得一个很好的例子:

https://medium.com/aspectum/acceleration-for-the-nearest-neighbor-search-on-earths-surface-using-python-513fc75984aa

上述示例之一实际上将距离计算强制到 GPU 上,但仍使用 sklearn 执行算法。

于 2021-02-08T01:50:41.430 回答
1

我也面临这个问题。根据一些论文(例如this,请参阅摘要),OPTICS 因其顺序性而被称为并行执行它具有挑战性。因此,当您使用 n_jobs=-1 时,sklearn 可能会尝试使用所有内核,但没有什么可以在额外的内核上运行。

可能您应该考虑其他对并行性更友好的聚类算法,例如评论中的@paul-brodersen 建议使用 HDBSCAN。但似乎 sklearn 没有这种并行的光学替代方案,因此您需要使用其他包。

于 2020-06-29T08:39:00.860 回答
1

OPTICS 和 HDBSCAN 都缺乏并行化。它们本质上都是顺序的,因此不能像 DBSCAN 那样传递到简单的 joblib.Parallel 上。

如果您希望提高速度,HDBSCAN 的好处之一是能够创建一个推理模型,您可以使用该模型进行预测,而无需再次运行整个集群。这就是我用来避免每次需要对数据进行分类时都运行非常慢的集群操作的方法。

于 2020-08-12T23:54:24.483 回答