我一直在寻找这个问题的答案,所以我希望有人可以帮助我。我在R中的fpc库中使用dbscan。例如,我正在查看USArrests数据集,并在其上使用dbscan,如下所示:
library(fpc)
ds <- dbscan(USArrests,eps=20)
在这种情况下,选择eps仅仅是通过反复试验。但是,我想知道是否有可用于自动选择最佳eps / minpts的功能或代码。我知道有些书建议制作一个与最近邻居的第k个分类距离的图。也就是说,x轴表示“根据到第k个最近邻居的距离排序的点”,并且y轴表示“第k个最近邻居距离”。
此类图表有助于为eps和minpts选择合适的值。我希望我已经为某人提供了足够的信息来帮助我。我想张贴一张我的意思,但我仍然是新手,所以暂不发布图片。
答案 0 :(得分:23)
没有选择minPts的一般方法。这取决于你想要找到的内容。低minPts意味着它将从噪声中构建更多的簇,因此不要选择它太小。
对于epsilon,有各个方面。它再次归结为选择此数据集上的任何内容以及此 minPts和此距离函数以及此规范化。你可以尝试做一个knn距离直方图并在那里选择一个“膝盖”,但可能没有可见的或多个。
OPTICS是DBSCAN的继承者,不需要epsilon参数(除了索引支持的性能原因,请参阅Wikipedia)。它更好,但我相信在R中实现它很痛苦,因为它需要高级数据结构(理想情况下,加速的数据索引树和优先级队列的可更新堆)和R就是矩阵运算。
天真地,人们可以想象OPTICS同时执行Epsilon的所有值,并将结果放在集群层次结构中。
然而,您需要检查的第一件事 - 几乎与您将要使用的任何聚类算法无关 - 是确保您具有有用的距离函数和适当的数据规范化。如果您的距离退化,没有聚类算法将起作用。
答案 1 :(得分:14)
管理DBSCAN的epsilon参数的一种常见且流行的方法是计算数据集的k距离图。基本上,您为每个数据点计算k-最近邻居(k-NN),以了解不同k的数据密度分布。 KNN很方便,因为它是一种非参数方法。选择minPTS(强烈依赖于您的数据)后,将k固定为该值。然后使用与距离较低的k距离图(对于固定k)的区域相对应的k距离作为epsilon。
答案 2 :(得分:9)
<强> MinPts 强>
正如Anony-Mousse所解释的那样,'低minPts意味着它将根据噪声构建更多的集群,所以不要选择它太小。'。
minPts最好由熟悉数据的域专家设置。不幸的是,很多情况下我们不了解领域知识,特别是在数据规范化之后。一种启发式方法是使用 ln(n),其中 n 是要聚类的点的总数。
<强>小量强>
有几种方法可以确定它:
1)k距离图
在minPts = k的聚类中,我们期望核心点和边界点的k距离在一定范围内,而噪点可以具有更大的k距离,因此我们可以观察到膝盖< / strong>指向k距离图。然而,有时可能没有明显的膝盖,或者可能有多个膝盖,这使得很难做出决定
2)像OPTICS
这样的DBSCAN扩展OPTICS生成分层集群,我们可以通过目视检查从层次集群中提取重要的平面集群,OPTICS实现可以在Python模块pyclustering中找到。 DBSCAN和OPTICS的原作者之一也提出了一种自动提取扁平簇的方法,无需人为干预,更多信息可以阅读this paper。
3)敏感性分析
基本上我们想要选择能够聚集更多真正规则点(与其他点相似的点)的半径,同时检测出更多噪声(离群点)。我们可以绘制百分比的常规点(点属于一个集群)VS. epsilon 分析,我们将不同的epsilon值设置为x轴,将相应的常规点百分比设置为y轴,希望我们能够发现一个段,其中常规点的百分比值更多对epsilon值敏感,我们选择上限epsilon值作为我们的最佳参数。
答案 3 :(得分:0)
它提供了有关如何找到epsilon的详细说明。 MinPts ......不是那么多。
答案 4 :(得分:0)
有关选择参数的详细信息,请参见第p.37页的以下论文。 11:
Schubert,E.,Sander,J.,Ester,M.,Kriegel,H.P.,&Xu,X.(2017年)。重新审视DBSCAN:为什么以及如何(仍然)使用DBSCAN。 《数据库系统上的ACM事务处理》(TODS),42(3),19。
- 对于二维数据:使用默认值minPts = 4(Ester等,1996)
- 对于2个以上维度:minPts = 2 * dim(Sander等,1998)
一旦知道选择哪种MinPts,就可以确定Epsilon:
- 用k = minPts绘制k距离(Ester等,1996)
- 找到图中的“肘部”-> k距离值就是您的Epsilon值。
答案 5 :(得分:0)
如果您有足够的资源,您还可以测试一堆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"))
})