-->

scikit学习DBSCAN内存使用情况(scikit-learn DBSCAN memory us

2019-09-01 23:44发布

更新:最后,解我选择使用聚类我大数据集由以下Anony -摩丝建议之一。 也就是说,使用ELKI的DBSCAN执行力度做我的集群,而不是scikit学习的。 它可以通过命令行,并用正确的索引上运行,进行几个小时之内这个任务。 使用GUI和小样本数据集工作,你要使用,然后去镇上的选项。 值得探讨。 Anywho,我原来问题的描述和一些有趣的讨论阅读。

我有一个约2.5万个样本,每行35个特征(浮点值),我试图以集群的数据集。 我一直在试图与scikit学习的实现DBSCAN要做到这一点,利用曼哈顿距离度量和小量的值从数据得出一些小的随机样本估计。 到现在为止还挺好。 (这里是片段中,以供参考)

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

Answer 1:

这个问题显然是一个低质量的DBSCAN实现scikit

DBSCAN不需要距离矩阵。 该算法是围绕使用可以加速数据库regionQuery功能,以及查询半径内返回邻居有效(空间索引应该支持这种查询在O(log n) )。

在实施scikit然而,很显然,计算全O(n^2)的距离矩阵,这是有代价的两个存储器明智和运行时,明智的。

所以我看到两个选择:

  1. 你可能想尝试在DBSCAN实现ELKI代替,这被R使用时*树索引通常比一个幼稚的做法大大加快。

  2. 否则,你可能要重新实现DBSCAN,如实施scikit显然不是太好。 不要害怕的是:DBSCAN是非常简单的实现自己。 良好的DBSCAN实现的最棘手的部分实际上是regionQuery功能。 如果你能快速得到这个查询,DBSCAN将会很快。 实际上,你可以重复使用此功能等算法,太。

更新:现在,sklearn不再来计算距离矩阵 ,可以,例如,使用KD-tree索引。 然而,因为“矢量”它仍然会预先计算每一个点的邻居,所以sklearn大型小量的内存使用量是O(N²),而我的理解中ELKI版本将只使用O(n)的内存。 所以,如果你耗尽内存,选择较小的ε和/或尝试ELKI 。



Answer 2:

您可以使用scikit学习的与半正矢公吨和球树算法DBSCAN做到这一点。 你不需要预先计算距离矩阵。

这个例子集群超过一百万的GPS经纬度点与DBSCAN /半正矢,避免内存使用问题:

df = pd.read_csv('gps.csv')
coords = df.as_matrix(columns=['lat', 'lon'])
db = DBSCAN(eps=eps, min_samples=ms, algorithm='ball_tree', metric='haversine').fit(np.radians(coords))

请注意,这个专门使用scikit学习v0.15,因为一些较早/以后的版本似乎都需要一个完整的距离矩阵来计算,这打击了你的RAM真正的快。 但是,如果你使用Anaconda,您可以快速设置这个了:

conda install scikit-learn=0.15

或者,创建此集群任务干净的虚拟环境:

conda create -n clusterenv python=3.4 scikit-learn=0.15 matplotlib pandas jupyter
activate clusterenv


Answer 3:

该DBSCAN算法实际上做了计算距离矩阵,因此在这里没有机会。 对于这么多的数据,我会建议使用MiniBatchKMeans。 不能使用曼哈顿指标有现成的,但你可以做你自己的实现。 也许尝试标准实施与欧几里德度量第一。

我不知道有多少聚类算法不执行成对距离。

使用新嵌入备忘单底部中心:虽然运气。



Answer 4:

我面临同样的问题时,我使用上sklearn 0.19.1旧版本,因为复杂性是O(N ^ 2)。

但现在的问题已经在新版本0.20.2和无记忆错误解决了,而变成O(ND),其中d复杂性是邻居的平均数。 这不是偶像的复杂性,但比旧版本要好得多。

检查此版本中的注意事项,以避免高内存使用: https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html



Answer 5:

这与sklearn问题是在这里讨论:

https://github.com/scikit-learn/scikit-learn/issues/5275

有提出有两种选择;

一种是利用光学(这需要sklearn V21 +),这是一种替代但密切相关的算法,以DBSCAN:

https://scikit-learn.org/dev/modules/generated/sklearn.cluster.OPTICS.html

其它的是预先计算邻接矩阵,或使用样本权重。 这些选项的一些细节可以在这里说明中找到:

https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html



文章来源: scikit-learn DBSCAN memory usage