在 scikit-learn 中,DBSCAN 可以使用稀疏矩阵吗?

Posted

技术标签:

【中文标题】在 scikit-learn 中,DBSCAN 可以使用稀疏矩阵吗?【英文标题】:In scikit-learn, can DBSCAN use sparse matrix? 【发布时间】:2013-04-12 08:02:58 【问题描述】:

我在运行 scikit 的 dbscan 算法时出现内存错误。 我的数据大约是20000*10000,是一个二进制矩阵。

(可能DBSCAN不适合用这样的矩阵,我是机器学习的初学者,只想找一个不需要初始簇号的簇方法)

反正我发现scikit的稀疏矩阵和特征提取。

http://scikit-learn.org/dev/modules/feature_extraction.html http://docs.scipy.org/doc/scipy/reference/sparse.html

但我仍然不知道如何使用它。在 DBSCAN 的规范中,没有关于使用稀疏矩阵的指示。不允许吗?

如果有人知道如何在 DBSCAN 中使用稀疏矩阵,请告诉我。 或者你可以告诉我一个更合适的集群方法。

【问题讨论】:

scikit-learn DBSCAN memory usage的可能重复 【参考方案1】:

Sklearn 的 DBSCAN 算法不采用稀疏数组。但是,KMeans 和Spectral clustering 可以,你可以试试这些。更多关于 sklearns 聚类方法的信息:http://scikit-learn.org/stable/modules/clustering.html

【讨论】:

【参考方案2】:

您可以将距离矩阵传递给DBSCAN,因此假设X 是您的示例矩阵,以下应该可以工作:

from sklearn.metrics.pairwise import euclidean_distances

D = euclidean_distances(X, X)
db = DBSCAN(metric="precomputed").fit(D)

但是,矩阵 D 甚至会比 X 更大:n_samples² 条目。对于稀疏矩阵,k-means 可能是最好的选择。

(DBSCAN 可能看起来很有吸引力,因为它不需要预先确定数量的集群,但它会将其换成您必须调整的 两个 参数。它主要适用于样本设置是空间中的点,你知道你希望这些点在同一个簇中的距离有多近,或者当你有一个 scikit-learn 不支持的黑盒距离度量时。)

【讨论】:

DBSCAN 不需要距离矩阵,这是当前 sklearn 实现的限制,而不是算法的限制。另外,在许多情况下,DBSCAN 的 epsion 和 minpts 参数都可以比k 更容易选择。例如,在使用地理数据时,用户很可能会说“1 公里”的半径是一个很好的 epsilon,并且该半径内应该至少有 10 个事件。 @Anony-Mousse:我知道问题出在实现上,而不是算法上。至于选择 eps 和 minpts,是的,对于一些可能很容易的问题,但对于其他问题,可能需要进行广泛的调整。并非所有问题都存在于欧几里得空间甚至地球表面。【参考方案3】:

不幸的是,DBSCAN 的scikit 实现非常天真。它需要重写以考虑索引(球树等)。

到目前为止,它显然会坚持计算一个完整的距离矩阵,这会浪费大量的内存。

我建议您自己重新实现 DBSCAN。这相当容易,存在很好的伪代码,例如在***和原始出版物中。它应该只有几行,然后您就可以轻松地利用您的数据表示。例如。如果您已经有一个稀疏表示的相似图,那么进行“范围查询”通常相当简单(即仅使用满足您的距离阈值的边)

这是issue in scikit-learn github,他们在其中谈论改进实施。一位用户报告说他使用球树的版本快了 50 倍(这并不让我感到惊讶,我之前已经看到过类似的索引加速 - 当进一步增加数据集大小时,它可能会变得更加明显)。

更新:自编写此答案以来,scikit-learn 中的 DBSCAN 版本已获得实质性改进。

【讨论】:

您可能对 scikit-learn 0.14 感兴趣,其中 DBSCAN 确实被修改为使用球树。 DBSCAN 现在支持 v0.16 中的稀疏输入【参考方案4】:

是的,从 0.16.1 版开始。 这是一个测试提交:

https://github.com/scikit-learn/scikit-learn/commit/494b8e574337e510bcb6fd0c941e390371ef1879

【讨论】:

以上是关于在 scikit-learn 中,DBSCAN 可以使用稀疏矩阵吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 scikit-learn 中缩放输入 DBSCAN

在 scikit-learn 中,DBSCAN 可以使用稀疏矩阵吗?

scikit-learn 中的 DBSCAN(仅使用指标)

Scikit-learn:使用 DBSCAN 进行聚类后,绘制的点比初始数据样本少

rapidminer 和 scikit-learn 中的 DBSCAN 算法

使用 python 和 scikit-learn 的 DBSCAN:make_blobs 返回的整数标签到底是啥?