scikit学习DBSCAN内存使用情况


问题内容

更新: 最后,我选择用于对大型数据集进行聚类的解决方案是下面的Anony-
Mousse建议的一种。也就是说,使用ELKI的DBSCAN隐式方法进行集群,而不是scikit-
learn。它可以从命令行运行,并带有适当的索引编制,可以在几个小时内执行此任务。使用GUI和小型样本数据集找出您要使用的选项,然后前往城镇。值得一看。任何人,请继续阅读以获取对我的原始问题的描述和一些有趣的讨论。

我有一个约250万个样本的数据集,每个样本都具有我要聚类的35个特征(浮点值)。我一直在尝试使用scikit-
learn的DBSCAN实现,使用曼哈顿距离度量和从数据中抽取的一些小型随机样本估算的epsilon值。到现在为止还挺好。(以下是代码段,仅供参考)

db = DBSCAN(eps=40, min_samples=10, metric='cityblock').fit(mydata)

目前,我的问题是我很容易耗尽内存。(我目前正在使用具有16 GB RAM的计算机)

我的问题是,DBSCAN是否正在运行时实时计算成对距离矩阵,这就是我的记忆不足吗?(250万^ 2)*
8个字节显然是非常大的,我会理解的。我不应该使用该fit()方法吗?更一般而言,是否有解决此问题的方法,还是我通常在这里吠叫错误的树?

如果答案很明显很抱歉。我已经为此困惑了几天。谢谢!

附录:此外,如果任何人都可以解释之间的差异fit(X)fit_predict(X)对我来说更明确地我也很感激-我怕我只是不太明白这一点。

附录2:可以肯定的是,我只是在具有约550 GB
RAM的计算机上尝试了此方法,但它仍然被炸毁,所以我觉得DBSCAN可能试图建立成对的距离矩阵或我显然不想要的东西去做。我想现在最大的问题是如何停止这种行为,或者找到其他更适合我需要的方法。感谢您在这里与我保持联系。

附录#3(!):我忘记附加回溯了,就在这里,

Traceback (most recent call last):
  File "tDBSCAN.py", line 34, in <module>
    db = DBSCAN(eps=float(sys.argv[2]), min_samples=10, metric='cityblock').fit(mydata)
  File "/home/jtownsend/.local/lib/python2.6/site-packages/sklearn/base.py", line 329, in fit_predict
    self.fit(X)
  File "/home/jtownsend/.local/lib/python2.6/site-packages/sklearn/cluster/dbscan_.py", line 186, in fit
    **self.get_params())
  File "/home/jtownsend/.local/lib/python2.6/site-packages/sklearn/cluster/dbscan_.py", line 69, in dbscan
    D = pairwise_distances(X, metric=metric)
  File "/home/jtownsend/.local/lib/python2.6/site-packages/sklearn/metrics/pairwise.py", line 651, in pairwise_distances
    return func(X, Y, **kwds)
  File "/home/jtownsend/.local/lib/python2.6/site-packages/sklearn/metrics/pairwise.py", line 237, in manhattan_distances
    D = np.abs(X[:, np.newaxis, :] - Y[np.newaxis, :, :])
MemoryError

问题答案:

问题显然是的非标准DBSCAN实现scikit-learn

DBSCAN不需要距离矩阵。该算法是围绕使用数据库进行设计的,该数据库可以加速regionQuery功能,并有效地返回查询半径内的邻居(空间索引应支持中的此类查询O(log n))。

scikit然而,该实现显然计算了全O(n^2)距离矩阵,这在内存和运行时都付出了代价。

所以我看到两个选择:

  1. 您可能想尝试在ELKI中尝试DBSCAN实现,当与R * -tree索引一起使用时,它通常比朴素的实现快得多。

  2. 否则,您可能要 重新实现DBSCAN ,因为中的实现scikit显然不太好。不必担心:DBSCAN真的很容易实现。好的DBSCAN实现中最棘手的部分实际上是regionQuery功能。如果您可以快速获得此查询,则DBSCAN将很快。实际上,您也可以将此功能重用于其他算法。

更新: 现在,sklearn不再计算距离 矩阵, 并且可以使用例如kd-tree索引。但是,由于“矢量化”,它 仍然会
预先计算每个点的邻居,因此sklearn在大型epsilon上的内存使用量为O(n²),而据我所知,ELKI中的版本将仅使用O(n)内存。因此,如果内存不足,请
选择较小的epsilon 和/或尝试使用ELKI