DBSCAN聚类算法

基本概念:基于密度的带有噪声点的聚类算法(Desity-Based Spatial Clustering of Applications with Noise),简称DBSCAN,又叫密度聚类。

核心对象:若某个点得密度达到算法设定的阈值,则这个点称为核心对象(即r邻域内点的数量不小于minPts)

邻域的距离阈值:设定的半径r

直接密度可达:若某点p在点q的r邻域内,且q是核心点,则p-q密度可达

密度可达:若有一个点的序列q0、q1、...qK,对任意qi-qi是直接密度可达的,则称从q0到qK密度可达,这实际上是直接密度可达的“传播”。

密度相连:若从某核心点p出发,点q和点k都是密度可达的,则称点q和点k使密度相连的

边界点:属于某一个类的非核心点,不能发展下线了

噪声点:不属于任何一个类簇的点,从任何一个核心点出发都是密度不可达的(所以DBSCAN聚类算法常用于异常值或者离群点得检测)

DBSCAN聚类算法的实现过程如下图:

对于奇葩的簇,K-Means是无法正常聚类的,而DBSCAN完全没有问题

优点:

1、与K-Means相比,不需要手动确定簇的个数K,但需要确定邻域r和密度阈值minPts

2、能发现任意形状的簇

3、能有效处理噪声点(邻域r和密度阈值minPts参数的设置可以影响噪声点)

缺点:

1、当数据量大时,处理速度慢,消耗大

2、当空间聚类的密度不均匀、聚类间距差相差很大时参数密度阈值minPts和邻域r参数选取困难

3、对于高维数据,容易产生“维数灾难”(聚类算法基于欧式距离的通病)

sklearn中的DBSCAN

import numpy as np

from sklearn.cluster import DBSCAN

from sklearn import metrics

from sklearn.datasets.samples_generator import make_blobs

from sklearn.preprocessing import StandardScaler

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)

# StandardScaler 标准化处理。且是针对每一个特征维度来做的,而不是针对样本。

# 调用密度聚类 DBSCAN

db = DBSCAN(eps=0.3, min_samples=10).fit(X)

# print(db.labels_) # db.labels_为所有样本的聚类索引,没有聚类索引为-1

# print(db.core_sample_indices_) # 所有核心样本的索引

core_samples_mask = np.zeros_like(db.labels_, dtype=bool) # 设置一个样本个数长度的全false向量

core_samples_mask[db.core_sample_indices_] = True #将核心样本部分设置为true

labels = db.labels_

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

# 获取聚类个数。(聚类结果中-1表示没有聚类为离散点)

# 模型评估

print('估计的聚类个数为:%d' % n_clusters_)

print("同质性:%0.3f" % metrics.homogeneity_score(labels_true, labels)) # 每个群集只包含单个类的成员。

print("完整性:%0.3f" % metrics.completeness_score(labels_true, labels)) # 给定类的所有成员都分配给同一个群集。

print("V-measure:%0.3f" % metrics.v_measure_score(labels_true, labels)) # 同质性和完整性的调和平均

print("调整兰德指数:%0.3f" % metrics.adjusted_rand_score(labels_true, labels))

print("调整互信息:%0.3f" % metrics.adjusted_mutual_info_score(labels_true, labels))

print("轮廓系数:%0.3f" % metrics.silhouette_score(X, labels))估计的聚类个数为: 3

同质性: 0.953

完整性: 0.883

V-measure: 0.917

调整兰德指数: 0.952

调整互信息: 0.883

轮廓系数: 0.626

# Plot result

import matplotlib.pyplot as plt

import seaborn as sns

%matplotlib inline

sns.set(font='SimHei',style='ticks')

unique_labels = set(labels)

colors = [plt.cm.Spectral(each) for each in np.linspace(0, 1, len(unique_labels))]

plt.figure(figsize=(10,6))

for k, col in zip(unique_labels, colors):

if k == -1: # 聚类结果为-1的样本为离散点

# 使用黑色绘制离散点

col = [0, 0, 0, 1]

class_member_mask = (labels == k) # 将所有属于该聚类的样本位置置为true

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_)

sns.despine()

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐