·统计样本周边的密度,把密度给定一个阈值,不断的把样本添加到最近的簇。例如:人口密度,根据密度,聚类出城市
·解决类似圆形的K-Means聚类的特点;密度聚类缺点:计算复杂度大,空间索引来降低计算时间,降低查找速度。
(DBSCAN算法):
参数:DBSCAN(eps=0.5, min_samples=5, metric=‘euclidean‘, algorithm=‘auto‘, leaf_size=30, p=None, n_jobs=1)
eps:两个样本之间的最大距离,即扫描半径
min_samples :作为核心点的话邻域(即以其为圆心,eps为半径的圆,含圆上的点)中的最小样本数(包括点本身)。
-------------------
metric :度量方式,默认为欧式距离,还有metric=‘precomputed’(稀疏半径邻域图),也可以自己进行定义
algorithm:近邻算法求解方式,有四种:‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’
leaf_size:叶的大小,在使用BallTree or cKDTree近邻算法时候会需要这个参数
n_jobs :使用CPU格式,-1代表全开
-------------------
core_sample_indices_:核心样本指数。
labels_:数据集中每个点的集合标签给,噪声点标签为-1。
components_ :核心样本的副本
运行:
model = sklearn.cluster.DBSCAN(eps_领域大小圆半径,min_samples_领域内,点的个数的阈值)
model.fit(data) 训练模型
model.fit_predict(data) 模型的预测方法
代码如下:
import numpy as npimport matplotlib.pyplot as pltimport sklearn.datasets as dsimport matplotlib.colorsfrom sklearn.cluster import DBSCANfrom sklearn.preprocessing import StandardScaler def expand(a, b): d = (b - a) * 0.1 return a-d, b+d if __name__ == "__main__": N = 1000 centers = [[1, 2], [-1, -1], [1, -1], [-1, 1]] data, y = ds.make_blobs(N, n_features=2, centers=centers, cluster_std=[0.5, 0.25, 0.7, 0.5], random_state=0)#生成4类共1000个点 data = StandardScaler().fit_transform(data)#归一化,先均值归一,再方差归一化 # 数据的超参数:(epsilon, min_sample) 即(R,NUM)每一类的半径与样本阈值num:核心点的高密度区域的最少点个数 params = ((0.2, 5), (0.2, 10), (0.2, 15), (0.3, 5), (0.3, 10), (0.3, 15))#超参数 matplotlib.rcParams[‘font.sans-serif‘] = [u‘SimHei‘] matplotlib.rcParams[‘axes.unicode_minus‘] = False plt.figure(figsize=(12, 8), facecolor=‘w‘) plt.suptitle(u‘DBSCAN聚类‘, fontsize=20) #遍历6组超参数,对聚类结果进行比较 for i in range(6):#i遍历上面设的6组超参数 eps, min_samples = params[i]#超参数赋值 model = DBSCAN(eps=eps, min_samples=min_samples)#建立模型 model.fit(data)#生成结果 y_hat = model.labels_#取出y^,所有点的分类结果。无论核心点还是边界点,只要是同一个簇的都被赋予同样的label,噪声点为-1. core_indices = np.zeros_like(y_hat, dtype=bool) core_indices[model.core_sample_indices_] = True#model.core_sample_indices_:核心点的索引,因为labels_不能区分核心点还是边界点,所以需要用这个索引确定核心点。 y_unique = np.unique(y_hat)#对于一维数组或者列表,unique函数去除其中重复的元素,并按元素由大到小返回一个新的无元素重复的元组或者列表 n_clusters = y_unique.size - (1 if -1 in y_hat else 0)#聚类数目 print(y_unique, ‘聚类簇的个数为:‘, n_clusters) plt.subplot(2, 3, i+1) clrs = plt.cm.Spectral(np.linspace(0, 0.8, y_unique.size))#Spectral:实现的功能是给label为1的点一种颜色,给label为0的点另一种颜色 np.linspace:在指定的间隔内返回均匀间隔的数字 print(clrs) for k, clr in zip(y_unique, clrs):#zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象 cur = (y_hat == k) if k == -1: plt.scatter(data[cur, 0], data[cur, 1], s=20, c=‘k‘) continue plt.scatter(data[cur, 0], data[cur, 1], s=30, c=clr, edgecolors=‘k‘) plt.scatter(data[cur & core_indices][:, 0], data[cur & core_indices][:, 1], s=60, c=clr, marker=‘o‘, edgecolors=‘k‘) x1_min, x2_min = np.min(data, axis=0) x1_max, x2_max = np.max(data, axis=0) x1_min, x1_max = expand(x1_min, x1_max) x2_min, x2_max = expand(x2_min, x2_max) plt.xlim((x1_min, x1_max)) plt.ylim((x2_min, x2_max)) plt.grid(True) plt.title(u‘epsilon = %.1f m = %d,聚类数目:%d‘ % (eps, min_samples, n_clusters), fontsize=16) plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show() plt.savefig(‘密度分类结果.png‘)
原文地址:https://www.cnblogs.com/xiguapipipipi/p/10109789.html