Density-Based Spatial Clustering of Applications with Noise(DBSCAN密度聚类)

来源:互联网 发布:什么商品淘宝禁止出售 编辑:程序博客网 时间:2024/06/10 22:29

DBSCAN原理:
基于密度的聚类(density-based clustering) 与之前的基于距离的K-means和GMM不同,此类算法意在通过样本分布的紧密程度确定聚类结构。通常情况下它是基于一组“邻域”(neighborhood)参数来刻画样本分布的紧密程度,通过考虑样本之间的可连接性,并介此不断扩展得到结果。

这里写图片描述

参数(ϵ, MinPts)用来描述邻域的样本分布紧密程度。其中,ϵ描述了某一样本的邻域距离阈值,MinPts描述了某一样本的距离为ϵ的邻域中样本个数的阈值。对给定的样本集是D=(x1,x2,…,xm),则DBSCAN的一些概念为:
ϵ-领域:某样本点半径为ϵ内的区域(欧式距离进行度量)
核心对象(core object):样本点ϵ-领域内的样本数大于等于MinPts
直接密度可达(directly density-reachable):如果样本点xjxi的ϵ-领域内,并且xi为核心对象,那么xjxi直接密度可达。
密度可达(density-reachable):给定一串样本点p1,p2….pn,p= p1,q= pn,假如对象pipi1直接密度可达,那么对象q从对象p密度可达。
密度相连(density-connected):对于样本集合D中的任意一点O,如果存在对象p到对象O密度可达,并且对象q到对象O密度可达,那么对象q到对象p密度相连。

列起来很麻烦,实际上思想并不难,先任意选择一个没有类别的核心对象作为“种子”,然后扫描整个数据集,找到所有这个核心对象能够密度可达的样本集合,即为一个聚类簇。遍历该核心点的ϵ-邻域内的所有核心对象,寻找样本集合到没有可再遍历的核心对象。再重新扫描数据集(不包括之前寻找到的簇中的任何数据点),寻找没有被聚类的核心对象,再重复上面的步骤。

怎么还有点没有被聚类?
这情况的出现是因为它不在任何一个核心对象在周围,将会默认为噪声点。

那抗噪音性岂不是很强?
它本身对噪声不敏感,如果是簇内的噪声它完全没有办法。

空间形状的影响
DBSCAN不需要知道k的值,而且对输入顺序不敏,它还可以发现任意形状的空间聚类。不过当空间聚类的密度不均匀、聚类间距差相差很大时,聚类质量不佳。

DBSCAN应用:
DBSCAN参数说明:
DBSCAN(algorithm=’auto’, eps=0.3, leaf_size=30, metric=’euclidean’, min_samples=10, n_jobs=1, p=None)

algorithm:最近搜索算法eps:领域的距离阈值leaf_size:最近搜索算法的参数,树的叶子阈值metric:距离度量min_samples:成为核心对象的最低阈值n_jobs=1:并行工作数p=None:距离度量参数

用sklearn:

import numpy as npfrom sklearn.cluster import DBSCANfrom sklearn import metricsfrom sklearn.datasets.samples_generator import make_blobs#满足高斯分布的点from sklearn.preprocessing import StandardScaler#3个数据集中心点centers = [[1, 1], [-1, -1], [1, -1]]X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4,                            random_state=0)X = StandardScaler().fit_transform(X)#标准化数据db = DBSCAN(eps=0.3, min_samples=10).fit(X)core_samples_mask = np.zeros_like(db.labels_, dtype=bool)core_samples_mask[db.core_sample_indices_] = Truelabels = db.labels_#聚类数k,忽略未被聚类的噪音点n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)#输出各种度量信息print('Estimated number of clusters: %d' % n_clusters_)print("Homogeneity: %0.3f" % metrics.homogeneity_score(labels_true, labels))#聚出簇的同类精度print("Completeness: %0.3f" % metrics.completeness_score(labels_true, labels))#同类簇被聚精度print("V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels))#上面两者的居中度量(相乘除以和)print("Adjusted Rand Index: %0.3f"      % metrics.adjusted_rand_score(labels_true, labels))#调整兰德系数print("Adjusted Mutual Information: %0.3f"      % metrics.adjusted_mutual_info_score(labels_true, labels))#调整互信息print("Silhouette Coefficient: %0.3f"      % metrics.silhouette_score(X, labels))#判别度量值import matplotlib.pyplot as pltunique_labels = set(labels)colors = [plt.cm.Spectral(each)          for each in np.linspace(0, 1, len(unique_labels))]for k, col in zip(unique_labels, colors):    if k == -1:        #未聚类点为黑色        col = [0, 0, 0, 1]    class_member_mask = (labels == k)    xy = X[class_member_mask & core_samples_mask]    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),             markeredgecolor='k', markersize=14)    xy = X[class_member_mask & ~core_samples_mask]    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),             markeredgecolor='k', markersize=6)plt.title('Estimated number of clusters: %d' % n_clusters_)plt.show()

这里写图片描述

阅读全文
0 0
原创粉丝点击