集群分配有时在两个 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] <- 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 实现中不同的主要内容,如果未能解决你的问题,请参考以下文章