聚类算法系列之密度聚类DBSCAN

DBSCAN算法简述:
为什么出现DBSCAN算法?

  当大家一说起聚类算法时候,最先想到的估计就是K-MeansMean-Shift算法了。但是,K-Means和Mean-Shift算法是通过距离聚类的方式来进行判别,需要设定类别参数,同时聚类的结果都是球状的簇。如果是非球状的分布结构,那么K-Means算法效果并不好。非球状结构的分布如下:

聚类算法系列之密度聚类DBSCAN_第1张图片

  像上述这样的分布结构,如果使用K-Means算法的话,聚类效果将会很差。那么这个时候DBSCAN算法就横空出世来解决这些问题。

  简单点说基于密度的聚类算法(Density-Based Spatial Clustering of Applications with Noise,DBSCAN)是一种基于密度的空间策略来进行聚类。通过初始化邻域半径 ϵ ϵ ϵ与最小点集个数 M i n p t s Minpts Minpts设定,来进行条件判断(核心点、边界点、噪音点等)迭代进行聚类。

DBSCAN算法原理:

  1 首先初始化DBSCAN算法的两个参数:邻域半径与最小点集个数的参数设定;

  2 选择一个初始点,判断是否是核心点,对于每一个核心点:选择一个未处理过的核心点,通过密度可达的原理对样本进行聚类生成簇。

  3 迭代重复以上的步骤直达所有的核心点都处理结束。

推荐一个DBSCAN算法动态显示聚类过程网站:传送门。

解释关于DBSCAN算法相关名词定义:
聚类算法系列之密度聚类DBSCAN_第2张图片
Figure 1 核心点与边界点相关解释

ϵ ϵ ϵ邻域与 M i n p t s Minpts Minpts

  我们使用DBSCAN算法时候,需要初始化两个参数: ϵ ϵ ϵ代表判断该点是不是核心点的密度半径, M i n − p t s Min-pts Minpts为在判断该点为中心,半径为 ϵ ϵ ϵ的点集个数判断指标。

核心点:

  如上图所示,将设半径设为 ϵ = 2 ϵ=2 ϵ=2同时 M i n p t s = 3 Minpts=3 Minpts=3时候,那么以上图红色的小方块为例:以它为圆心,半径为3的圆区域发现它的点数( > M i n p t s >Minpts >Minpts)大于3,即红色小方块为核心点

边界点:

  我们发现红色如果以红色小方块邻域的三个蓝色圆心,继续以它们为中心,半径为3的区域内并没有超过三个点,但是它们在红色小方块为核心点的区域内,那么它们属于边界点

噪音点:

  噪音点就是既不是核心点也不是边界点的第三种情况。

下面在解释密度直达、密度可达、密度相连的相关定义,首先看下示意图2如下:

聚类算法系列之密度聚类DBSCAN_第3张图片
Figure 2 密度直达 密度可达 密度相连示意图 图片来自于知乎作者:传送门

  上图2分别展示密度直达、密度可达、密度相连的相关定义,图(a)分别说明 p p p为边缘点, q q q为核心点, r r r为噪音点。

密度直达:

  定义:样本点 p p p是由样本点 q q q对于参数 { ϵ , M i n p t s } \{ϵ,Minpts\} {ϵMinpts}密度直达,满足条件为 q q q是核心点同时 p p p点在以 q q q为核心点的圆区域内。显示示意图(b)

密度可达:

  定义:如果存在一系列样本点 p 1 , p 2 , . . . , p n p_1,p_2,...,p_n p1,p2,...,pn(其中 p 1 = q p_1=q p1=q, p n = p p_n=p pn=p)使得 p i + 1 p_{i+1} pi+1可由样本点 p i p_i pi密度直达,那么样本点 p p p可由样本点 q q q密度可达。示意图(c)

密度相连:

  定义:如果样本点 o o o对于样本点 p p p是密度可达的,同时样本点 o o o对于样本点 q q q也是密度可达的,那么我们称作样本点 p p p与样本点 q q q是密度相连的。示意图(d)

概念解释小结:

  密度直达:核心点 q q q邻域内存在边缘点 p p p,那么我们称作样本点 p p p是由样本点 q q q密度直达的。( p p p q q q是相邻的);

  密度可达:样本点 p p p是由一系列核心点传递到核心点 q q q的,那么我们称作样本点 p p p是由样本点 q q q密度可达。( p p p q q q具有传递性);

  密度相连:就是存在样本点 o o o对样本点 p p p密度可达,同时又对样本点 q q q密度可达,那么样本点 p p p与样本点 q q q密度相连。(某一个中间点到 p p p q q q密度可达单方向传递性);

DBSCAN算法优缺点:

优点:

  较其它聚类策略,例如K-Means只能适用于凸数据集,DBSCAN算法可以对任意形状的稠密数据集有效的聚类。

  DBSCAN聚类对异常点抗干扰性强,即对受孤立的点影响很小,即对数据集中的异常点不明感。

缺点:

  如果样本集的密度不均匀,聚类间距相差很大时,聚类质量较差,所以不适合使用DBSCAN算法。

  针对大数据样本集,聚类收敛时间较长(目前改进是通过KD树快速搜索或者对球树规模限制).

  DBSCAN有两个参数是经验设置(调参不是很容易):距离阈值 ϵ ϵ ϵ,邻域样本数阈值 M i n p t s Minpts Minpts,这两个参数设置都会对聚类效果影响很大。参数建议根据数据量和具体应用场景进行调节与设定。

DBSCAN算法Python代码实践:
# -*- coding:utf-8 -*-
import numpy as np

from sklearn.cluster import DBSCAN
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
from sklearn.preprocessing import StandardScaler

# Generate sample data
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(n_samples=750, centers=centers,
                            cluster_std=0.4, random_state=0)

X = StandardScaler().fit_transform(X)

# Compute DBSCAN Algorithm
db = DBSCAN(eps=0.3, min_samples=10).fit(X)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_

# Number of clusters in labels, ignoring noise if present
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
n_noise_ = list(labels).count(-1)

print('Estimanted number of cluster: %d' % n_clusters_)
print('Estimated number of noise points: %d' % n_noise_)
print('Homogeneity: %0.3f' % metrics.homogeneity_score(labels_true, labels))
print('Completeness: %0.3f' % metrics.completeness_score(labels_true, labels))
print('V-measure: 0.3f' % metrics.v_measure_score(labels_true, labels))
print('Adjusted Rand Index: 0.3f'
      % metrics.adjusted_rand_score(labels_true, labels))

print('Adjusted Mutual Information: %0.3f'
      % metrics.adjusted_mutual_info_score(labels_true, labels))

print('Silhouette Coefficient: %0.3f' % metrics.silhouette_score(X, labels))

# plot result
import matplotlib.pyplot as plt

# Black removed and is used for noise instead
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
          for each in np.linspace(0, 1, len(unique_labels))]

for k, col in zip(unique_labels, colors):
    if k == -1:
        # Black used for noise
        col = [0, 0, 0, 1]

    class_member_mask = (labels == k)

    xy = X[class_member_mask & core_samples_mask]

    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=14)

    xy = X[class_member_mask & ~core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=6)

plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
聚类实验结果
聚类算法系列之密度聚类DBSCAN_第4张图片
参考

http://www.aaai.org/Papers/KDD/1996/KDD96-037.pdf

https://scikit-learn.org/stable/auto_examples/cluster/plot_dbscan.html#sphx-glr-auto-examples-cluster-plot-dbscan-py

https://www.researchgate.net/publication/221653977_A_Density-Based_Algorithm_for_Discovering_Clusters_in_Large_Spatial_Databases_with_Noise

https://www.biaodianfu.com/dbscan.html

你可能感兴趣的:(机器学习)