为DBSCAN(R)选择eps和minpts?

39

我已经寻找这个问题的答案有一段时间了,所以我希望有人能帮助我。我正在使用R中fpc库中的dbscan。例如,我正在查看USArrests数据集,并按如下方式使用dbscan:

library(fpc)
ds <- dbscan(USArrests,eps=20)
在这种情况下,选择eps仅仅是通过试错来完成的。然而,我想知道是否有一种函数或代码可以自动选择最佳的eps/minpts值。我知道一些书籍推荐绘制第k个排序距离到其最近邻居的图表。也就是说,x轴表示“按到第k个最近邻居的距离排序的点”,y轴表示“第k个最近邻居的距离”。
这种类型的图表对于帮助选择适当的eps和minpts值非常有用。我希望我已经提供了足够的信息,以便有人能够帮助我。我想发布一个我所说的图片,但我还是新手,所以现在不能发布图片。
6个回答

29

选择 minPts 没有通用的方法,这取决于您想要找到什么。较低的 minPts 意味着将从噪声中构建更多聚类,因此不要选择太小。

对于 epsilon,有各种方面。它再次归结为选择在 数据集和 minPts 和 距离函数以及 归一化上起作用的内容。您可以尝试做一个 knn 距离直方图,并选择一个“拐点”,但可能没有明显的拐点或者有多个拐点。

OPTICS 是 DBSCAN 的后继者,它不需要 epsilon 参数(除了使用索引支持的性能原因,请参见维基百科)。它很好,但我认为在 R 中实现它会很麻烦,因为它需要高级数据结构(理想情况下,加速使用的数据索引树和优先级队列的可更新堆),而 R 都是关于矩阵操作的。

朴素地说,可以将 OPTICS 想象为同时处理所有 Epsilon 值,并将结果放入聚类层次结构中。

然而,无论您要使用任何聚类算法,首先需要检查的第一件事是确保您具有有用的距离函数和适当的数据归一化。如果您的距离退化,则没有聚类算法能正常工作。


1
如果用R实现比其他编程语言明显更难,我会感到惊讶(“R是全部都关于矩阵操作”的想法很错误--data.frame,可能是R中使用最广泛的数据结构,并不是矩阵而是列表)。出于性能原因,实现时可能会使用Rcpp。 - Ari B. Friedman
哦,抱歉。显然在Matlab中这些事情非常麻烦。对于R来说,“rann”包中存在一些索引。但我相信fpc不使用它,而且由于R没有“数据库查询”API,它无法自动连接模块。 - Has QUIT--Anony-Mousse
1
在我的实验中,fpc DBSCAN 比其他实现方式慢了 10 倍。只有 Weka 更差(慢了另外的 8 倍)。 - Has QUIT--Anony-Mousse
1
R的性能对实现非常敏感。我并不否认算法可能更难,但在实践中,像这样的通用算法往往被编写为库,然后被访问(LINPACK、GEOS等)——这避免了在许多语言中重复优化的工作。R的设计是为应用统计从业者合理,并且可扩展为程序员。其中一部分可扩展性意味着使用其他有帮助的库和语言。 - Ari B. Friedman
我已经自己定义了距离。对于我正在解决的问题类型,它可以很好地工作并提供所需的结果。然而,我不知道是否应该在聚类中使用它,因为它提供了非对称距离矩阵。(就我正在解决的问题而言,这种距离不是自反的是正常的)我怎么知道它是否退化了?还没有找到任何相关信息。 - user974514
显示剩余2条评论

16

MinPts

正如Anony-Mousse所解释的那样,'较低的minPts意味着它将从噪声中构建更多的簇,因此不要选择太小.'

对于最佳的minPts值需要由了解数据的领域专家进行设置。不幸的是,在许多情况下,我们并不了解领域知识,特别是在规范化数据之后。一种启发式方法是使用ln(n),其中n是要聚类的总点数。

Epsilon

确定epsilon有几种方法:

1) k-距离图

在具有minPts = k的聚类中,我们期望核心点和边界点的k-距离在一定范围内,而噪声点可以具有更大的k-距离,因此我们可以在k-距离图中观察到一个拐点。但是,有时可能没有明显的拐点,或者可能有多个拐点,这使得决定变得困难

2) DBSCAN扩展,例如OPTICS

OPTICS生成分层聚类,我们可以通过视觉检查从分层聚类中提取显着的平坦聚类,Python模块pyclustering中提供了OPTICS实现。 DBSCAN和OPTICS的一个原始作者还提出了一种自动提取平坦聚类的方法,不需要人为干预,有关更多信息可以阅读这篇论文

3) 敏感性分析

基本上,我们希望选择一个半径,它能够更真实地聚类更加规则的点(与其他点相似的点),同时检测出更多的噪声(离群点)。我们可以绘制一个正常点百分比(属于一个聚类的点) VS. epsilon分析图,其中我们设置不同的epsilon值作为x轴,它们对应的百分之正常点数作为y轴,希望我们能发现一个段落,其中正常点百分比值对epsilon值更敏感,我们将选择上限epsilon值作为我们的最佳参数。


2
一种启发式方法是使用ln(n),其中n是要聚类的总点数。您有这方面的引用吗? - Mark White
4
@MarkWhite,这句话出自ST-DBSCAN: An algorithm for clustering spatial-temporal data第4.1节 - Shawn TIAN
2
原始的DBSCAN论文建议将minpts基于数据维度2*dim而不是数据集大小n。 - Has QUIT--Anony-Mousse
第一篇 OPTICS 论文中已经有自动聚类提取。此外还有其他功能。 - Has QUIT--Anony-Mousse
1
@NAGA 我认为这样做没有任何问题,即使没有领域知识也不是使用DBSCAN的强制要求,但基于领域知识设置minPts几乎总是有益的。在没有领域知识的情况下,我们可以依靠一些其他启发式方法,就像原始论文中所描述的那样。 - Shawn TIAN
显示剩余4条评论

15

关于选择参数的详细信息,请参见下面第11页的论文:

Schubert, E., Sander, J., Ester, M., Kriegel, H. P., & Xu, X. (2017). DBSCAN revisited, revisited: why and how you should (still) use DBSCAN. ACM Transactions on Database Systems (TODS), 42(3), 19.

  • 对于二维数据:使用默认值minPts=4(Ester等人,1996年)
  • 对于多于2个维度的数据:minPts=2*dim(Sander等人,1998年)

一旦您知道选择哪个MinPts,就可以确定Epsilon:

  • 以k=minPts绘制k距离图(Ester等人,1996年)
  • 找到图中的“拐点”--> k距离值即为您的Epsilon值。

15

管理DBSCAN的epsilon参数的一种常见且流行的方法是计算数据集的k距离图。基本上,您计算每个数据点的k个最近邻(k-NN),以了解不同k下数据的密度分布情况。 KNN 很方便,因为它是一种非参数方法。一旦选择了minPTS(这强烈取决于您的数据),则将k固定为该值。然后使用k距离图的面积(对于固定的 k 值)具有低斜率的 k 距离作为 epsilon。


这实际上只是原始DBCAN论文中讨论的方法。这就是OP所说的他已经听说过但想要替代建议的内容。 - Lan
我没有看到他说他不想要它。实际上,他似乎说的是相反的。 - marcorossi
2
R包dbscan有一个名为kNNdistplot的函数,可以生成这种类型的图形。 - Michael Hahsler

1
如果你有足够的资源,也可以测试一堆epsilon和minPts值,看看哪个有效。我使用expand.grid和mapply来完成这个任务。
# Establish search parameters.
k <- c(25, 50, 100, 200, 500, 1000)
eps <- c(0.001, 0.01, 0.02, 0.05, 0.1, 0.2)

# Perform grid search.
grid <- expand.grid(k = k, eps = eps)

results <- mapply(grid$k, grid$eps, FUN = function(k, eps) {
  cluster <- dbscan(data, minPts = k, eps = eps)$cluster
  sum <- table(cluster)
  cat(c("k =", k, "; eps =", eps, ";", sum, "\n"))
})

0

我尝试了这种方法来找到“拐点”,但是当我给定k=5并绘制我的数据时,它看起来并没有“拐点”。我尝试增加k的值(从5增加到1000),但是图形看起来基本相同。此外,文档没有说明为什么拐点对应于最佳epsilon。 - Duy Bui
抱歉,在之前的评论中应该附上截图链接。内联链接 - Duy Bui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接