我在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实现
注意我的实现中不同的点标有感叹号(!) 我还上传了不匹配部分的缩放图像:
+
是核心要点
o
是边界点
-
是噪音点
!
突出了不同点
三角形是核心要点 彩色圆圈是边界点 黑圈是噪音点
修改
按照Anony-Mousse的要求
在不同的情况下,有时似乎我的实现已正确地对错配点进行了分类,有时似乎fpc实现已正确地对错配进行了分类。见下文:
fpc :: dbscan(带有三角形图)似乎已正确分类错配点
我的dbscan实现(带有+ plot)实际上似乎已正确地对错配点进行了分类
我是群集分析的新手,因此我有另一个问题:这些差异是否允许?
在我的实现中,我正在从提供的第一个点到最后一个点进行扫描,同样在fpc::dbscan
中以相同的顺序扫描点。在这种情况下,两个实现都应该从同一个集群中心发现不匹配点(由!
标记)。此外,我已经生成了一些fpc::dbscan
将点标记为噪声的情况,但我的实现将其分配给某些集群。在这种情况下,为什么会出现这种差异?
根据要求提供代码段。
答案 0 :(得分:5)
众所周知,DBSCAN依赖于 border 点的顺序。它们将被分配到首次发现它们的集群。如果边界点不是密集的,而是来自不同聚类的两个密集点的密度,则可以将其分配给其中一个。
这就是为什么DBSCAN经常被描述为“与边界点无关的订单”。
尝试改组数据(或反转!),然后重新运行算法。结果应该改变。
由于我假设您和fpc实现都没有索引支持(加速范围查询并使算法在O(n log n)
中运行),我猜其中一个实现是按正向顺序处理点,另一个是向后的顺序。 '''更新:索引不应该发挥很大的作用,因为它们不会跨群集更改顺序,只能在一个群集内'''。
“产生”这种差异的另一个选择是
fbc::dbscan
似乎这样做)这些也会对作为多个集群的边界点的对象生成不同的结果。还有可能将这些点分配给两个cluter,这将产生数据集的非严格分区。通常,进行严格分区的好处比具有完全确定性的结果更重要。
不要误会我的意思:fbc::dbscan
的“覆盖”策略并没有显着改变结果。我甚至可能会以这种方式实现它。
是否有任何非边境点受到影响?