机器学习:密度聚类-DBSCAN算法简介(附代码实现)

密度聚类假设聚类结构能通过样本分布的紧密程度确定。

DBSCAN(Density-Based Spacial Clustering of Application with Noise)就是一种著名的密度聚类算法,它用一组参数(\epsilon,MinPts)来刻画样本分布的紧密程度。先定义下面的一些概念:

\epsilon-邻域:对,其\epsilon-邻域包含样本集D中与的距离不大于\epsilon的样本,即

核心对象:若\epsilon-邻域至少包含MinPts个样本,即\left | N_{\epsilon }(x_{j}) \right |\geqslant MinPts,则是一个核心对象;

密度直达:若位于x_{i}\epsilon-邻域中,且x_{i}是核心对象,则称x_{i}密度直达;

密度可达:对x_{i},若存在样本序列p_{1},p_{2},...,p_{n},其中p_{1}=x_{i},p_{n}=x_{j}p_{i+1}p_{i}密度直达,则称x_{i}密度可达;

密度相连:对x_{i},若存在x_{k}使得x_{i}均由x_{k}密度可达,则称x_{i}密度相连。

上述概念的直观显示:

DBSCAN将“簇”定义为:由密度可达关系导出的最大的密度相连样本集合,给定参数(\epsilon,MinPts),簇C\subseteqD是满足以下性质的非空样本子集:

  1. 连接性:x_{i}\in C,x_{j}\in C\Rightarrow x_{i},x_{j}密度相连
  2. 最大性:x_{i}\in Cx_{i}密度可达\Rightarrow x_{j}\in C

另外,D中可能存在不属于任何簇的样本,这样的样本被认为是噪声或异常样本。

如何从数据集D中找到满足以上性质的聚类簇呢?不难证明,若x为核心对象,由x密度可达的所有样本组成的集合X = {x'D|x'由x密度可达}就是满足连接性和最大性的簇。

算法描述如下:

python代码实现:

import numpy as np
epsilon = 0.11
minpts = 5
x = np.load("watermalon4.0.npy")
#epsilon邻域统计表
t = [set() for i in range(30)]
#聚类簇
clusters = []
#核心对象集
coreset = set()
for i in range(len(x)):
    t[i].add(i)
    for j in range(i+1,len(x)):
        #欧式距离
        dist = np.linalg.norm(x[i] - x[j])
        if dist <= epsilon:
            #记录epsilon邻域信息
            t[i].add(j)
            t[j].add(i)
for i in range(len(t)):
    if len(t[i]) >= minpts:
        #核心对象集
        coreset.add(i)
allset = {i for i in range(len(x))}
while len(coreset) > 0:
    #浅拷贝(拷贝第一层,这里没影响)
    oldset = allset.copy();
    corepoint = coreset.pop()
    q = [corepoint]
    allset -= {corepoint}
    while len(q) > 0:
        item = q.pop(0)
        if len(t[item]) >= minpts:
            #交集
            delta = t[item] & allset
            q += [i for i in delta]
            allset -= delta
    #新的聚类簇
    newcluster = oldset - allset
    clusters.append(newcluster)
    coreset -= newcluster
print(clusters)

参考资料:周志华《机器学习》

猜你喜欢

转载自blog.csdn.net/weixin_35732969/article/details/81291670