目录

  • 理论部分
  • 1.1 提出背景
  • 1.2 常见算法
  • 1.3 DBSCAN算法
  • 1.3.1 基本概念
  • 1.3.2 算法流程
  • 1.3.3 参数设置
  • 1.3.3 优点
  • 1.3.4 缺点
  • 1.3.5 可视化结果展示
  • 1.4 评估指标
  • 代码部分
  • 2.1 不使用sklearn实现
  • 2.2 使用sklearn实现


理论部分

1.1 提出背景

与K-means算法基于距离聚类不同,DBSCAN算法是基于样本点密度进行聚类。基于距离的聚类方法只适用于凸型数据尤其是球状分布的数据,而难以处理非凸数据,而密度聚类法可以很好地解决这个问题,密度聚类法的基本思想是只要一个区域中的点的密度大过某个阀值,就把它加到与之相近的聚类中去。

1.2 常见算法

基于密度的聚类算法有很多,例如DBSCAN算法、OPTICS算法、DENCLUE算法、基于密度峰值的聚类方法等。本篇我们着重讲解DBSCAN。

1.3 DBSCAN算法
1.3.1 基本概念

密度聚类算法有哪些 密度聚类应用场景_数据为样本集,密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02表示领域半径,密度聚类算法有哪些 密度聚类应用场景_数据_03表示密度阈值,则有:

·密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02领域
密度聚类算法有哪些 密度聚类应用场景_聚类算法_05
即表示以密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06为中心,密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02为半径的圆内样本点的集合(包括自身)。

·密度聚类算法有哪些 密度聚类应用场景_聚类_08密度

密度聚类算法有哪些 密度聚类应用场景_数据_09
密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06的密度定义为密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02领域内的样本点个数。

·核心点

密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_13,若密度聚类算法有哪些 密度聚类应用场景_数据_14,则称密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_16的核心点,记密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_16中所有核心点构成的集合为密度聚类算法有哪些 密度聚类应用场景_聚类算法_18,所有非核心点构成的集合为密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_19

PS:简单来说,核心点即为满足在密度聚类算法有哪些 密度聚类应用场景_聚类_20领域内至少有密度阈值个样本点的点。

·边界点

密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_21(即密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06为非核心点),且 密度聚类算法有哪些 密度聚类应用场景_聚类_23,满足:
密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_24
则称密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06为边界点,令样本点中所有边界点构成的集合为密度聚类算法有哪些 密度聚类应用场景_聚类_26

PS:边界点可以理解为指那些落入核心点密度聚类算法有哪些 密度聚类应用场景_聚类_20领域内的但不是核心点的样本点。

·噪声点

若样本点密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06同时有:
密度聚类算法有哪些 密度聚类应用场景_聚类_29
则称密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06为噪声点。

PS:噪声点可以理解为既不是核心点也不是边界点的样本点。即若某个样本点在其密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02领域内不具有至少密度阈值个样本点,同时该样本点也不落在任何核心点的密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02领域内,则称该样本点为噪声点。

密度聚类算法有哪些 密度聚类应用场景_常见算法_33


如上图,蓝色样本点即为核心点,黑色样本为边界点,白色样本为噪声点。

·密度直达

对于样本点密度聚类算法有哪些 密度聚类应用场景_常见算法_34,若有:
密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_35
密度聚类算法有哪些 密度聚类应用场景_数据_36
则称密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06是由密度聚类算法有哪些 密度聚类应用场景_聚类_38关于参数密度聚类算法有哪些 密度聚类应用场景_数据_39密度直达。

PS:密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06是由密度聚类算法有哪些 密度聚类应用场景_聚类_38密度直达的等效为以下说法:密度聚类算法有哪些 密度聚类应用场景_聚类_38是核心点且密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06处在密度聚类算法有哪些 密度聚类应用场景_聚类_38密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02领域内。

密度聚类算法有哪些 密度聚类应用场景_数据_46

·密度可达

对于样本点密度聚类算法有哪些 密度聚类应用场景_常见算法_34,如果存在一系列样本点密度聚类算法有哪些 密度聚类应用场景_数据_48,若密度聚类算法有哪些 密度聚类应用场景_常见算法_49能够由密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_50密度直达密度聚类算法有哪些 密度聚类应用场景_聚类算法_51,则称密度聚类算法有哪些 密度聚类应用场景_聚类_38 可由密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06密度可达。

密度聚类算法有哪些 密度聚类应用场景_聚类_54

·密度相连

如果存在一个样本点密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_55,使得密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06 密度聚类算法有哪些 密度聚类应用场景_聚类_38均可由密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_55密度可达,则称密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_06 密度聚类算法有哪些 密度聚类应用场景_聚类_38是密度相连的。

密度聚类算法有哪些 密度聚类应用场景_聚类算法_61

1.3.2 算法流程

密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_62


该算法流程可大致描述如下:首先确定所有的核心点从而构成核心点集合(并将这些核心点标注为已访问)。而后每次选取一个核心点,如果其密度直达范围中存在另一个核心点,则将该核心点和可到达的那个核心点以及两者的密度直达范围中的样本点全部归属为一类。否则,第一类完成,开始第二类聚类,以此类推

1.3.3 参数设置

密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02或者密度聚类算法有哪些 密度聚类应用场景_数据_03设置得非常小,则意味着没有点是核心样本,可能会导致所有点被标记为噪声
密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02或者密度聚类算法有哪些 密度聚类应用场景_数据_03设置得非常大,可能会导致所有点形成单个簇。

1.3.3 优点

1.不必提前设置聚类数。
2.对非凸型数据处理能力较强,可以对任意类内稠密,类间系数的样本集进行聚类。
3.对异常点敏感性较低,可以较为有效地排除异常点的干扰。
4.可优化性强,部分步骤可由数据结构中的相关算法进行优化。

1.3.4 缺点

1.需要设置密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02密度聚类算法有哪些 密度聚类应用场景_数据_03,而这往往是依靠人的直觉和经验的。
2.在大规模数据集上效率较低。

密度聚类算法有哪些 密度聚类应用场景_聚类_69


属于簇的点是实心,噪声点则显示为空心,核心样本点显示为较大的标记,而边界点则显示为较小的标记,上图即验证了密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02密度聚类算法有哪些 密度聚类应用场景_数据_03取值大小对结果的影响。

1.3.5 可视化结果展示

密度聚类算法有哪些 密度聚类应用场景_数据_72


上图为DBSCAN算法对于非球形分布数据的聚类过程。

密度聚类算法有哪些 密度聚类应用场景_聚类_73


上图为DBSCAN聚类结果(左图)和K-means聚类结果(右图)的对比

不同的密度聚类算法有哪些 密度聚类应用场景_密度聚类算法有哪些_02密度聚类算法有哪些 密度聚类应用场景_数据_03设置也会导致不同的结果:

密度聚类算法有哪些 密度聚类应用场景_数据_76

1.4 评估指标

这里仍然可以采用轮廓系数进行评估,关于轮廓系数的介绍可以见

代码部分

2.1 不使用sklearn实现
import matplotlib.pyplot as plt
import random
import numpy as np
import math
from sklearn import datasets
 
list_1 = []
list_2 = []
def loadDataSet(fileName, splitChar='\t'):
    dataSet = []
    with open(fileName) as fr:
        for line in fr.readlines():
            curline = line.strip().split(splitChar)
            fltline = list(map(float, curline))
            dataSet.append(fltline)
    return dataSet
 
# 计算两个点之间的欧式距离,参数为两个元组
def dist(t1, t2):
    dis = math.sqrt((np.power((t1[0]-t2[0]),2) + np.power((t1[1]-t2[1]),2)))
    # print("两点之间的距离为:"+str(dis))
    return dis
 
# DBSCAN算法,参数为数据集,Eps为指定半径参数,MinPts为制定邻域密度阈值
def dbscan(Data, Eps, MinPts):
    num = len(Data)  # 点的个数
    # print("点的个数:"+str(num))
    unvisited = [i for i in range(num)]  # 没有访问到的点的列表
    # print(unvisited)
    visited = []  # 已经访问的点的列表
    C = [-1 for i in range(num)]
    # C为输出结果,默认是一个长度为num的值全为-1的列表
    # 用k来标记不同的簇,k = -1表示噪声点
    k = -1
    # 如果还有没访问的点
    while len(unvisited) > 0:
        # 随机选择一个unvisited对象
        p = random.choice(unvisited)
        unvisited.remove(p)
        visited.append(p)
        # N为p的epsilon邻域中的对象的集合
        N = []
        for i in range(num):
            if (dist(Data[i], Data[p]) <= Eps):# and (i!=p):
                N.append(i)
        # 如果p的epsilon邻域中的对象数大于指定阈值,说明p是一个核心对象
        if len(N) >= MinPts:
            k = k+1
            # print(k)
            C[p] = k
            # 对于p的epsilon邻域中的每个对象pi
            for pi in N:
                if pi in unvisited:
                    unvisited.remove(pi)
                    visited.append(pi)
                    # 找到pi的邻域中的核心对象,将这些对象放入N中
                    # M是位于pi的邻域中的点的列表
                    M = []
                    for j in range(num):
                        if (dist(Data[j], Data[pi])<=Eps): #and (j!=pi):
                            M.append(j)
                    if len(M)>=MinPts:
                        for t in M:
                            if t not in N:
                                N.append(t)
                # 若pi不属于任何簇,C[pi] == -1说明C中第pi个值没有改动
                if C[pi] == -1:
                    C[pi] = k
        # 剩余点既不是核心点也不是边界点
        else:
            C[p] = -1
 
    return C
 
dataSet = loadDataSet(r'D:\Deeplearning\788points.txt', splitChar=',')
C = dbscan(dataSet, 2, 14)
print(C)
x = []
y = []
for data in dataSet:
    x.append(data[0])
    y.append(data[1])
plt.figure(figsize=(8, 6), dpi=80)
plt.scatter(x,y, c=C, marker='o')
plt.show()

结果如下:

密度聚类算法有哪些 密度聚类应用场景_聚类算法_77

2.2 使用sklearn实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
%matplotlib inline
X1, y1=datasets.make_circles(n_samples=5000, factor=.6,
                                      noise=.05)
X2, y2 = datasets.make_blobs(n_samples=1000, n_features=2, centers=[[1.2,1.2]], cluster_std=[[.1]],
               random_state=9)

X = np.concatenate((X1, X2))
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show()
y_pred = DBSCAN(eps = 0.1, min_samples = 10).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()

结果如下:

密度聚类算法有哪些 密度聚类应用场景_聚类_78