DBScan是一种基于密度的聚类算法,它有一个核心点的概念:如果一个点,在距它Eps的范围内有不少于MinPts个点,则该点就是核心点。核心和它Eps范围内的邻居形成一个簇。

一:基本概念

1.聚类方法:DBSCAN算法:对象O的是与O为中心,聚类方法:DBSCAN算法为半径的空间,参数聚类方法:DBSCAN算法,是用户指定每个对象的领域半径值。

2.MinPts(领域密度阀值):对象的聚类方法:DBSCAN算法的对象数量。

3.核心对象:如果对象O聚类方法:DBSCAN算法的对象数量至少包含MinPts个对象,则该对象是核心对象。

4.直接密度可达:如果对象p在核心对象q的聚类方法:DBSCAN算法内,则p是从q直接密度可达的。

5.密度可达:在DBSCAN中,p是从q(核心对象)密度可达的,如果存在对象链聚类方法:DBSCAN算法,使得聚类方法:DBSCAN算法,聚类方法:DBSCAN算法聚类方法:DBSCAN算法从关于聚类方法:DBSCAN算法和MinPts直接密度可达的,即聚类方法:DBSCAN算法聚类方法:DBSCAN算法

聚类方法:DBSCAN算法内,则聚类方法:DBSCAN算法聚类方法:DBSCAN算法密度可达。

6.密度相连:如果存在对象聚类方法:DBSCAN算法,使得对象聚类方法:DBSCAN算法都是从q关于和MinPts密度可达的,则称聚类方法:DBSCAN算法是关于聚类方法:DBSCAN算法和MinPts密度相连的。

二:密度可达和密度相连

聚类方法:DBSCAN算法

聚类方法:DBSCAN算法

图1基于密度的聚类中的密度可达和密度相连性

由上图可看出m,p,o.r 都是核心对象,因为他们的内都只是包含3个对象。

1.对象q是从m直接密度可达的。对象m从p直接密度可达的。

2.对象q是从p(间接)密度可达的,因为q从m直接密度可达,m从p直接密度可达。

3.r和s是从o密度可达的,而o是从r密度可达的,所有o,r和s都是密度相连的。

 

三:DBSCAN聚类过程

 1.DBSCAN发现簇的过程

       初始,给定数据集D中所有对象都被标记为“unvisited”,DBSCAN随机选择一个未访问的对象p,标记p为“visited”,并检查p的聚类方法:DBSCAN算法是否至少包含MinPts个对象。如果不是,则p被标记为噪声点(或者是不处理,有可能将边界点标记为噪声;除非后面在处理过程中可以将噪声点标志为边界点)。否则为p创建一个新的簇C,并且把p的聚类方法:DBSCAN算法中所有对象都放在候选集合N中。DBSCAN迭代地把N中不属于其他簇的对象添加到C中。在此过程中,对应N中标记为“unvisited”的对象聚类方法:DBSCAN算法,DBSCAN把它标记为“visited”,并且检查它的聚类方法:DBSCAN算法,如果聚类方法:DBSCAN算法聚类方法:DBSCAN算法至少包含MinPts个对象,则聚类方法:DBSCAN算法聚类方法:DBSCAN算法中的对象都被添加到N中。DBSCAN继续添加对象到C,直到C不能扩展,即直到N为空。此时簇C完成生成,输出。

     为了找到下一个簇,DBSCAN从剩下的对象中随机选择一个未访问过的对象。聚类过程继续,直到所有对象都被访问。

2.DBSCAN聚类算法流程

 聚类方法:DBSCAN算法

3.参数设置:DBSCAN共包括3个输入数据:数据集D,给定点在邻域内成为核心对象的最小邻域点数:MinPts,邻域半径:Eps,其中Eps和MinPts需要根据具体应用人为设定。

(1)  Eps的值可以使用绘制k-距离曲线(k-distance graph)方法得当,在k-距离曲线图明显拐点位置为对应较好的参数。若参数设置过小,大部分数据不能聚类;若参数设置过大,多个簇和大部分对象会归并到同一个簇中。

K-距离:K距离的定义在DBSCAN算法原文中给出了详细解说,给定K邻域参数k,对于数据中的每个点,计算对应的第k个最近邻域距离,并将数据集所有点对应的最近邻域距离按照降序方式排序,称这幅图为排序的k距离图,选择该图中第一个谷值点位置对应的k距离值设定为Eps。一般将k值设为4。原文如下[2]:

聚类方法:DBSCAN算法

聚类方法:DBSCAN算法

 

(2)  MinPts的选取有一个指导性的原则(a rule of thumb),MinPts≥dim+1,其中dim表示待聚类数据的维度。MinPts设置为1是不合理的,因为设置为1,则每个独立点都是一个簇,MinPts≤2时,与层次距离最近邻域结果相同,因此,MinPts必须选择大于等于3的值。若该值选取过小,则稀疏簇中结果由于密度小于MinPts,从而被认为是边界点儿不被用于在类的进一步扩展;若该值过大,则密度较大的两个邻近簇可能被合并为同一簇。因此,该值是否设置适当会对聚类结果造成较大影响。

 

四、实例

import numpy as np
import sklearn.cluster as skc
from sklearn import metrics
import matplotlib.pyplot as plt

data=[
    [-2.68420713,1.469732895],[-2.71539062,-0.763005825],[-2.88981954,-0.618055245],[-2.7464372,-1.40005944],[-2.72859298,1.50266052],
    [-2.27989736,3.365022195],[-2.82089068,-0.369470295],[-2.62648199,0.766824075],[-2.88795857,-2.568591135],[-2.67384469,-0.48011265],
    [-2.50652679,2.933707545],[-2.61314272,0.096842835],[-2.78743398,-1.024830855],[-3.22520045,-2.264759595],[-2.64354322,5.33787705],
    [-2.38386932,6.05139453],[-2.6225262,3.681403515],[-2.64832273,1.436115015],[-2.19907796,3.956598405],[-2.58734619,2.34213138],
    [1.28479459,3.084476355],[0.93241075,1.436391405],[1.46406132,2.268854235],[0.18096721,-3.71521773],[1.08713449,0.339256755],
    [0.64043675,-1.87795566],[1.09522371,1.277510445],[-0.75146714,-4.504983795],[1.04329778,1.030306095],[-0.01019007,-3.242586915],
    [-0.5110862,-5.681213775],[0.51109806,-0.460278495],[0.26233576,-2.46551985],[0.98404455,-0.55962189],[-0.174864,-1.133170065],
    [0.92757294,2.107062945],[0.65959279,-1.583893305],[0.23454059,-1.493648235],[0.94236171,-2.43820017],[0.0432464,-2.616702525],
    [4.53172698,-0.05329008],[3.41407223,-2.58716277],[4.61648461,1.538708805],[3.97081495,-0.815065605],[4.34975798,-0.188471475],
    [5.39687992,2.462256225],[2.51938325,-5.361082605],[4.9320051,1.585696545],[4.31967279,-1.104966765],[4.91813423,3.511712835],
    [3.66193495,1.0891728],[3.80234045,-0.972695745],[4.16537886,0.96876126],[3.34459422,-3.493869435],[3.5852673,-2.426881725],
    [3.90474358,0.534685455],[3.94924878,0.18328617],[5.48876538,5.27195043],[5.79468686,1.139695065],[3.29832982,-3.42456273]
]
X = np.array(data)

db = skc.DBSCAN(eps=1.5, min_samples=3).fit(X)
labels = db.labels_

print('ffff:')
print(labels)

raito = len(labels[labels[:] == -1]) / len(labels)
print('eeee:', format(raito, '.2%'))

n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)

print('ddddd: %d' % n_clusters_)
print("vvvv: %0.3f" % metrics.silhouette_score(X, labels))

x0 = X[labels == 0]
x1 = X[labels == 1]
x2 = X[labels == 2]
xb = X[labels == -1]
plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')
plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')
plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker='+', label='label2')
plt.scatter(xb[:, 0], xb[:, 1], c="black", marker='x', label='black')
plt.xlabel('petal length')
plt.ylabel('petal width')
plt.legend(loc=2 )
plt.show()

 

相关文章: