我正在尝试通过dbscan
处理大量数据,并希望使用计算机上可用的所有内核来加快计算速度。我正在使用自定义距离度量,但是距离矩阵未预先计算。
我尝试了许多不同的实现,但是没有取得太大的成功。我在下面列出了它们,以及在终端窗口中使用top
跟踪性能时观察到的结果。
n_jobs
输入:model = DBSCAN(eps=eps, min_samples=min_samps,metric=distance_sphere_and_time, n_jobs=-1)
model.fit(X)
CPU仅达到2%的使用率。看起来计算中仅包括了可能的48个核心中的一个。
n_jobs
一起使用内置的Brute
输入。model = DBSCAN(eps=eps, min_samples=min_samps,metric=distance_sphere_and_time, algorithm=`Brute`, n_jobs=-1)
model.fit(X)
[这里建议dbscan
是并行处理的唯一方法:https://github.com/scikit-learn/scikit-learn/pull/8039,尽管有警告,但Brute
可能会降低它的速度。 CPU使用率达到100%,但并没有提高。
client = Client(processes=False, n_workers=8)
model = DBSCAN(eps=eps, min_samples=min_samps,metric=distance_sphere_and_time)
with parallel_backend('dask'):
model.fit(X)
这里建议了这种实现方式:https://github.com/dask/dask-tutorial/issues/80。但是,CPU利用率仍为2%,表明仅使用了一个内核。
任何建议将不胜感激。
您的问题是python。在其他工具(例如ELKI)中尝试相同的操作(请不要忘记添加例如覆盖树索引),您会看到巨大的速度差异。
原因是您的距离是一个用户函数ufunc。 sklearn用于搜索邻居的球树是Cython,对于每次距离计算,都需要返回解释器。它甚至会在每次距离计算时copy点数据。这些回调可能涉及臭名昭著的Python GIL,因此破坏了任何并行化工作。