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)
距离矩阵,这在内存和运行时都付出了代价。
所以我看到两个选择:
-
您可能想尝试在ELKI中尝试DBSCAN实现,当与R * -tree索引一起使用时,它通常比朴素的实现快得多。
-
否则,您可能要 重新实现DBSCAN ,因为中的实现
scikit
显然不太好。不必担心:DBSCAN真的很容易实现。好的DBSCAN实现中最棘手的部分实际上是regionQuery
功能。如果您可以快速获得此查询,则DBSCAN将很快。实际上,您也可以将此功能重用于其他算法。
更新: 现在,sklearn不再计算距离 矩阵, 并且可以使用例如kd-tree索引。但是,由于“矢量化”,它 仍然会
预先计算每个点的邻居,因此sklearn在大型epsilon上的内存使用量为O(n²),而据我所知,ELKI中的版本将仅使用O(n)内存。因此,如果内存不足,请
选择较小的epsilon 和/或尝试使用ELKI。