光学平行度

OPTICS parallelism

我有以下脚本 (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 个内核?

我也遇到了这个问题。根据一些论文(例如 this,见摘要),OPTICS 因其顺序性而被认为很难并行进行。因此,当您使用 n_jobs=-1 时,sklearn 可能会尝试使用所有内核,但是在额外的内核上没有任何东西可以 运行。

可能您应该考虑其他更并行友好的聚类算法,例如@paul-brodersen 在评论中建议使用 HDBSCAN。但是好像sklearn没有optics的并行替代,所以你需要使用其他包。

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

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

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

在 OPTICS 中实现 'force' 并行性的最佳方法可能是定义一个自定义的距离度量 运行s 并行——参见这个 post 的一个很好的例子:

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

上面的一个例子实际上是将距离计算强制到 GPU 上,但仍然使用 sklearn 来执行算法。