集群分配有时在两个 DBSCAN 实现中不同

Posted

技术标签:

【中文标题】集群分配有时在两个 DBSCAN 实现中不同【英文标题】:Cluster assignments differ sometimes in two DBSCAN implementations 【发布时间】:2012-06-07 07:31:49 【问题描述】:

我已经在 R 中实现了 DBSCAN 算法,并且我将集群分配与fpc library 的 DBSCAN 实现相匹配。测试是在 fpc 库 dbscan 示例中生成的合成数据上完成的:

n <- 600
x <- cbind(runif(10, 0, 10)+rnorm(n, sd=0.2), runif(10, 0, 10)+rnorm(n, sd=0.3))

使用以下参数进行聚类:

eps = 0.2
MinPts = 5

我正在将 fpc::dbscan 的集群分配与我的 dbscan 实现进行比较。运行的最大值显示每个点都被两种实现进行了相同的分类。

但在某些情况下,我的实现中的 1 或 2 点以及极少数情况下 5 或 6 点被分配给不同的集群,而不是 fpc 实现中的集群。我注意到只有边界点分类不同。在绘制之后,我发现集群成员在实现中不匹配的点处于这样的位置,这样它就可以分配给它周围的任何集群,这取决于它首先是从哪个集群的种子点被发现的。

我正在展示一张有 150 个点的图像(以避免混乱),其中 1 个点的分类不同。请注意,在我的实现中,失配点簇数总是大于 fpc 实现。

聚类图。

顶部插图是 fpc::dbscan,底部插图是我的 dbscan 实现

注意我的实现中的不同点用感叹号(!) 我还上传了不匹配部分的放大图像:


我的 dbscan 实现输出

+是核心点

o 是边界点

- 是噪声点

! 突出不同点


fpc::dbscan 实现输出

三角形是核心点 彩色圆圈是边界点 黑圈是噪声点


另一个例子:

我的 dbscan 实现输出


fpc::dbscan 实现输出


编辑

x-y 等比例缩放示例

根据 Anony-Mousse 的要求

在不同的情况下,有时我的实现似乎正确分类了不匹配点,有时 fpc 实现似乎正确分类了不匹配点。见下文:

fpc::dbscan(带有三角形图)似乎正确分类了不匹配点

我的 dbscan 实现(带有 + 绘图)似乎正确分类了不匹配点

问题

我是聚类分析的新手,因此我还有一个问题:这些类型的差异是否允许?

在我的实现中,我从提供的第一个点扫描到最后一个点,同样在fpc::dbscan 中,这些点也以相同的顺序扫描。在这种情况下,两个实现都应该从同一个集群中心发现失配点(标记为!)。我还产生了一些情况,其中fpc::dbscan 将一个点标记为噪声,但我的实现将它分配给一些集群。在这种情况下,为什么会出现这种差异?

应要求提供代码段。

【问题讨论】:

你能举一个例子,其中 fpc 将一个点标记为不应该的噪声吗?尝试缩放绘图,使 x 和 y 具有相同的比例,这使得距离更直观。 我添加了新读数的相等 xy 缩放图像 在图中青色旁边似乎还有一个黑色簇。所以左边的两个点可能看起来像噪声点,但实际上是黑色簇的边界点(黑色三角形似乎是核心点)。 从顶部开始的图像 6 不明确,因为 fpc 绘图使用黑色来标记集群和噪声。是的,三角形是核心点。在此图像中,请考虑使用正确的图来识别噪声点。 DBSCAN 结果应该与点的噪声/边界/核心状态一致,可能仅在边界点的集群分配中有所不同。你有一个边界点变成噪音的例子吗?至于fpc::dbscan,在我看来它好像覆盖了集群分配,从而保留了最后一个集群中的点?至少我是这样阅读fpc 源代码的,但我不是 R 专家。 cv[reachables] &lt;- cn 对我说“覆盖所有可达点的集群分配”(最终从其他集群中窃取它们)。 【参考方案1】:

DBSCAN 已知与 border 点的顺序相关。它们将被分配到首次发现它们的集群。如果一个边界点不稠密,但在不同簇的两个稠密点附近,则可以分配给其中一个。

这就是为什么 DBSCAN 通常被描述为“顺序无关,边界点除外”。

尝试改组数据(或反转数据!),然后重新运行您的算法。结果应该会改变。

由于我假设您的实现和 fpc 实现都没有索引支持(以加快范围查询并使算法在 O(n log n) 中运行),我猜想其中一种实现是按正序处理点,另一个按倒序排列。 '''更新:索引不应该起太大作用,因为它们不会跨集群改变顺序,只在一个集群内改变'''。

“产生”这种差异的另一种选择是

保留每个点的第一个(非噪声)聚类分配(IIRC 官方 DBSCAN 伪代码) 保留每个点的最后一个集群分配(fbc::dbscan 似乎这样做)

这些也会对不止一次聚类的边界点的对象产生不同的结果。还有可能将这些点分配给两个集群,这将产生数据集的非严格分区。通常,严格划分的好处比完全确定的结果更重要。

不要误会我的意思:fbc::dbscan 的“覆盖”策略不会显着改变结果。我什至可能会自己实现它。

是否有任何非边界点受到影响?

【讨论】:

到目前为止我已经运行了很多次,但没有种子点受到影响,但是一旦我看到噪声点在我的实施中受到影响。我正在按正向处理这些点,并且就我检查了 fpc 代码而言,它也在正向处理。对于 epsilon-neighborhood 查询,我正在使用 RANN 库中的 nn2 函数,并尝试改进处理使其变为 O(n lg n) (但现在不是)你能建议我如何改进 eps-邻里查询 我不使用 R,所以我无法帮助你。我是 ELKI 用户,它有各种索引,当我进行范围或 NN 查询时会自动使用这些索引。将点分配给集群怎么样,您是覆盖分配还是保留除了未分配和噪声之外的任何内容?即使以相同的顺序进行处理,这也可能导致这种差异。因为边界点可以多次分配给集群。 我只分配一次所有中心点和边界点。正在重新分配噪声点。我的实现严格遵循原论文中的逻辑。 fpc 是否使用相同的逻辑?哦,从文档来看,nn2 只是近似值,所以它可能会错过一些邻居? 我在nn2 中使用eps = 0.0 参数,因此它是准确的。我也用我在 R 中的手动 eps-neighborhood 计算运行了这个测试(这非常昂贵),这也导致了。

以上是关于集群分配有时在两个 DBSCAN 实现中不同的主要内容,如果未能解决你的问题,请参考以下文章

基于 DBSCAN 的集群字符串

在 DBSCAN 中找到每个集群中出现最多的位置

dbscan - 设置最大集群跨度限制

使用 DBSCAN 无法正确分割图像

在 scikit DBSCAN 中查找每个集群内的元素?

具有 metric='russellrao' 的 DBSCAN 集群