机器学习之经典算法(十五)DBSCAN算法

   一、DBSCAN算法简介:

     DBSCAN(Density-Based SpatialClustering of Application with Noise),是一种基于密度的聚类算法。与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类。其目标是寻找被低密度区域分离的高密度区域,通俗点说就是把扎堆的点(高密度)找出来,而点很少很稀疏的地方(低密度)就作为分割区域。

    (1)  基本原理:

    ① DBSCAN通过检查数据集中每点的Eps邻域来搜索簇,如果点p的Eps邻域包含的点多于MinPts个,则创建一个以p为核心对象的簇;

    ②  然后,DBSCAN迭代地聚集从这些核心对象直接密度可达的对象,这个过程可能涉及一些密度可达簇的合并;

    ③ 当没有新的点添加到任何簇时,该过程结束。

    优点:

    ①  与K-means方法相比,DBSCAN不需要事先知道要形成的簇类的数量。

    ②  与K-means方法相比,DBSCAN可以发现任意形状的簇类。同时,DBSCAN能够识别出噪声点。

    ③  DBSCAN对于数据库中样本的顺序不敏感,即Pattern的输入顺序对结果的影响不大。

    缺点:

    ①  DBScan不能很好反映高维数据。

    ②  DBScan不能很好反映数据集以变化的密度。对于处于簇类之间边界样本,可能会根据哪个簇类优先被探测到而其归属有所摆动。

 

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

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

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

(3)几个相关概念:

    ① Eps邻域:给定对象半径Eps内的邻域称为该对象的Eps邻域;

    ② 核心点(core point):如果对象的Eps邻域至少包含最小数目MinPts的对象,则称该对象为核心对象;

    ③ 边界点(edge point):边界点不是核心点,但落在某个核心点的邻域内;

    ④ 噪音点(outlier point):既不是核心点,也不是边界点的任何点;

    ⑤ 直接密度可达(directly density-reachable):给定一个对象集合D,如果p在q的Eps邻域内,而q是一个核心对象,则称对象p从对象q出发时是直接密度可达的;

   ⑥ 密度可达(density-reachable):如果存在一个对象链  p1, …,pi,.., pn,满足p1 = p 和pn = q,pi是从pi+1关于Eps和MinPts直接密度可达的,则对象p是从对象q关于Eps和MinPts密度可达的;

    ⑦ 密度相连(density-connected):如果存在对象O∈D,使对象p和q都是从O关于Eps和MinPts密度可达的,那么对象p到q是关于Eps和MinPts密度相连的。

(4)具体算法描述如下: 

    ①  检测数据库中尚未检查过的对象p,如果p未被处理(归为某个簇或者标记为噪声),则检查其邻域,若包含的对象数不小于MinPts ,建立新簇C,将其中的所有点加入候选集N; 

    ②  对候选集N 中所有尚未被处理的对象q,检查其邻域,若至少包含MinPts个对象,则将这些对象加入N;如果q 未归入任何一个簇,则将q 加入C; 

    ③  重复第2步,继续检查N 中未处理的对象,当前候选集N为空;

    ④  重复步骤第1步~第3步,直到所有对象都归入了某个簇或标记为噪声。 

(二)、Sklearn中DBSCAN的应用实例:

__author__= 'jcy'

importnumpy as np

importmatplotlib.pyplot as plt

fromsklearn import datasets

plt.figure()

plt.subplot(2,3,1)

X1,y1=datasets.make_circles(n_samples=2000, factor=.6,noise=.05)

X2, y2 =datasets.make_blobs(n_samples=500, n_features=2, centers=[[1,1]],cluster_std=[[.1]],random_state=9)

X =np.concatenate((X1, X2))

plt.scatter(X[:,0], X[:, 1], marker='o')

plt.title('Datasample')

plt.subplot(2,3,2)

fromsklearn.cluster import KMeans

y_pred =KMeans(n_clusters=3, random_state=9).fit_predict(X)

plt.scatter(X[:,0], X[:, 1], c=y_pred)

plt.title('K-Means')

plt.subplot(2,3,3)

fromsklearn.cluster import DBSCAN

y_pred =DBSCAN().fit_predict(X)

plt.scatter(X[:,0], X[:, 1], c=y_pred)

plt.title('default')

plt.subplot(2,3,4)

y_pred =DBSCAN(eps = 0.1).fit_predict(X)

plt.scatter(X[:,0], X[:, 1], c=y_pred)

plt.title('eps=0.1')

plt.subplot(2,3,5)

y_pred =DBSCAN(eps = 0.1, min_samples = 10).fit_predict(X)

plt.scatter(X[:,0], X[:, 1], c=y_pred)

plt.title('eps=0.1,min_samples=5')

plt.show()

        我们看一下代码执行效果:


猜你喜欢

转载自blog.csdn.net/weixin_42039090/article/details/80710661