DBSCAN

235 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

本篇文章继续讲一下新的聚类方法-DBSCAN(Density-Based Spatial Clustering of Applications with Noise),它说明了一种基于局部密度估计的不同的方法,可以允许算法识别任意形状。

DBSCAN

它会将集群定义为高密度的连续区域,具体的算法工作原理如下:

  • 该算法会对每一个实例计算出在距他距离为ϵ\epsilon内包含了多少个实例,该区域也称为ϵ\epsilon-邻域。

  • 同时如果在ϵ\epsilon-邻域内至少有我们设置的一个阈值(min_sample)的数量,该实例也被称为核心实例。核心实例就是在密集区域内的实例。

  • 核心实例附近的所有实例都是一个集群的,包含所有这个附近的其他核心实例的ϵ\epsilon-邻域内实例。

  • 不在上面的范围内的会被划分成异常实例

该算法会在集群足够密集并且被低密度区域很好的分割的数据集中表现很好。我们还是继续使用Scikit-Learn包下DBSCAN,数据使用make_moons生成:

X, y = make_moons(n_samples=1000, noise=0.05, random_state=42)
dbscan = DBSCAN(eps=0.05, min_samples=5)
dbscan.fit(X)

根据上面的算法工作原理,我们需要注意两eps:如果设置eps过小就可能不能很好的聚类,同时如果太大了,容易添加过多的错误的实例。min_samples的设置也是一样的。

我们可以看一下不同的eps距离下,算法对于数据集的聚类效果:

图1 不同邻域的DBSCAN聚类

左右很明显的效果不一样,左图由于设置过小邻域,导致有些实例不能很好的被聚类,右图则相对完美一些。当然我们如果单纯使用DBSCAN聚类,他是没有对于的预测函数的。因此我们需要将聚类后的参数重新放入新的预测器中。

需要注意dbscan生成的的几个参数

  • dbscan.components_-这个是核心实例本身
  • dbscan.labels_-所有实例的标签
  • dbscan.core_sample_indices_-核心实例的索引
# 使用KNeighborsClassifier来预测新实例
knn = KNeighborsClassifier(n_neighbors=50)
knn.fit(dbscan.components_, dbscan.labels_[dbscan.core_sample_indices_])

# 放入几个新实例看一下效果
X_new = np.array([[-0.5, 0], [0, 0.5], [1, -0.1], [2, 1]])
knn.predict(X_new)# 输出: array([1, 0, 1, 0])

画个图看一下新实例的位置,是不是和上面的预测一样:

图2 新实例和预测图

嗯哼,效果不错。