只能做防骑 2020-05-13
聚类本文转载自公众号“读芯术”(ID:AI_Discovery)分析是一种无监督学习法,它将数据点分离成若干个特定的群或组,使得在某种意义上同一组中的数据点具有相似的性质,不同组中的数据点具有不同的性质。
聚类分析包括基于不同距离度量的多种不同方法。例如。K均值(点之间的距离)、Affinity propagation(图之间的距离)、均值漂移(点之间的距离)、DBSCAN(最近点之间的距离)、高斯混合(到中心的马氏距离)、谱聚类(图之间距离)等。
2014年,DBSCAN算法在领先的数据挖掘会议ACM SIGKDD上获得the testof time奖(授予在理论和实践中受到广泛关注的算法)。
所有聚类法都使用相同的方法,即首先计算相似度,然后使用相似度将数据点聚类为组或群。本文将重点介绍具有噪声的基于密度的聚类方法(DBSCAN)。
既然已经有了K均值聚类,为什么还需要DBSCAN这样的基于密度的聚类算法呢?
K均值聚类可以将松散相关的观测聚类在一起。每一个观测最终都成为某个聚类的一部分,即使这些观测在向量空间中分散得很远。由于聚类依赖于聚类元素的均值,因此每个数据点在形成聚类中都起着作用。
数据点的轻微变化可能会影响聚类结果。由于聚类的形成方式,这个问题在DBSCAN中大大减少。这通常不是什么大问题,除非遇到一些具有古怪形状的数据。
使用K均值的另一个困难是需要指定聚类的数量(“k”)以便使用。很多时候不会预先知道什么是合理的k值。
DBSCAN的优点在于,不必指定使用它的聚类数量。需要的只是一个计算值之间距离的函数,以及一些将某些距离界定为“接近”的指令。在各种不同的分布中,DBSCAN也比K均值产生更合理的结果。下图说明了这一事实:
基于密度的聚类算法
基于密度的聚类是无监督学习法,基于数据空间中的聚类是高点密度的连续区域,通过低点密度的连续区域与其他此类聚类分离,来识别数据中独特的组/聚类。
具有噪声的基于密度的聚类方法(DBSCAN)是基于密度聚类的一种基本算法。它可以从大量的数据中发现不同形状和大小的聚类,这些聚类中正包含着噪声和异常值。
DBSCAN算法使用以下两种参数:
如果探究两个称为密度可达性(DensityReachability)和密度连接性(DensityConnectivity)的概念,就可以理解这些参数。
密度方面的可达性(Reachability)建立了一个可以到达另一个点的点,如果该点位于与另一个点的特定距离(eps)内。
连接性(Connectivity)涉及到基于传递性的链接方法,以确定点是否位于特定的聚类中。例如,如果p->r->s->t->q,则p和q可以连接,其中a->b表示b在a的邻域内。
DBSCAN聚类完成后会产生三种类型的点:
DBSCAN聚类算法步骤
参数估计
每个数据挖掘任务都存在参数问题。每个参数都以特定的方式影响算法。DBSCAN需要参数ε和minPts。
然而,对于有噪声的数据集,较大的值通常更好,并将产生更显著的聚类。根据经验,可以使用minPts=2·dim,但对于非常大的数据、噪声数据或包含许多重复项的数据,可能需要选择更大的值。
用sklearn实现DBSCAN python
首先用DBSCAN对球形数据进行聚类。
先生成750个带有相应标签的球形训练数据点。然后对训练数据的特征进行标准化,最后应用sklearn库中的DBSCAN。
聚类球形数据中的DBSCAN
黑色数据点表示上述结果中的异常值。接下来,用DBSCAN对非球形数据进行聚类。
import numpy as np importmatplotlib.pyplot as plt from sklearn import metrics fromsklearn.datasets import make_circles fromsklearn.preprocessing importStandardScaler from sklearn.clusterimportDBSCAN X, y =make_circles(n_samples=750, factor=0.3, noise=0.1) X=StandardScaler().fit_transform(X) y_pred=DBSCAN(eps=0.3, min_samples=10).fit_predict(X) plt.scatter(X[:,0], X[:,1], c=y_pred) print('Number ofclusters: {}'.format(len(set(y_pred[np.where(y_pred !=-1)])))) print('Homogeneity:{}'.format(metrics.homogeneity_score(y, y_pred))) print('Completeness:{}'.format(metrics.completeness_score(y, y_pred))) print("V-measure:%0.3f"% metrics.v_measure_score(labels_true,labels)) print("Adjusted RandIndex: %0.3f" % metrics.adjusted_rand_score(labels_true,labels)) print("AdjustedMutual Information: %0.3f" % metrics.adjusted_mutual_info_score(labels_true,labels)) print("SilhouetteCoefficient: %0.3f" % metrics.silhouette_score(X, labels))
聚类非球形数据中的DBSCAN
这绝对是完美的。如果与K均值进行比较,会给出一个完全不正确的输出,如:
K-均值聚类结果
DBSCAN聚类算法的复杂性
基于密度的聚类算法可以学习任意形状的聚类,而水平集树算法可以在密度差异很大的数据集中学习聚类。