DBSCAN(Density-Based Spatial Clustering of Applications with Noise)简称密度聚类或密度基础聚类,是一种基于密度的聚类算法,也是一种常用的无监督学习算法,特别适用于形状不规则的聚类和含有噪声的数据集。主要用于发现具有任意形状的簇,并能够有效地识别噪声数据点。
核心概念
1、ε邻域:表示以某点为中心,半径为 ε 的圆形范围。邻域内的所有点到该中心点的距离(欧氏距离或其他距离)都不会超过 ε (ε邻域的另一定义:指距离该点不超过 ε 的所有点的集合)
2、MinPts:它是一个给定的数值,表示一个点被认为是核心点所需的最小邻居数量(包括该点本身)。
3、核心点:如果一个点的 ε 邻域内至少有MinPts
个点(包括它自身),则该点是核心点。核心点周围有足够的密度,能够扩展形成一个聚类。
4、边界点:如果一个点的ε邻域内有少于MinPts
个点,但它位于某个核心点的邻域内,那么这个点就是边界点。边界点虽然在核心点的邻域内,但它自身不满足成为核心点的条件(即它的邻域内的点数不足以形成密度聚类)。
5、噪声点:如果一个点既不是核心点,也不在任何核心点的邻域内,那么它被认为是噪声点,通常不属于任何聚类。噪声点是稀疏区域的点,DBSCAN会将这些点从聚类结果中剔除。
6、聚类扩展:DBSCAN的聚类是从核心点开始扩展的。一旦找到一个核心点,它会将该核心点的邻域内的所有点(包括边界点)添加到同一个聚类中。如果一个边界点的邻域内没有足够的点(小于MinPts
),则该点不能成为新的核心点,但它可以作为已有核心点的边界点进行扩展。
7、聚类的形成:
-
DBSCAN通过核心点扩展聚类,聚类可以包含多个核心点及其邻域内的边界点。
-
如果两个核心点的ε邻域有重叠,它们的聚类就会合并成一个更大的聚类。
-
如果核心点之间没有重叠,它们就会形成不同的聚类。
具体步骤
注:记得先对数据进行标准化处理,消除量纲影响。
(一)定义参数
-
(epsilon):一个点被认为是邻居的最大距离。即半径范围内的点。
-
MinPts:一个点被认为是核心点的最小邻居数。
(二)DBSCAN迭代步骤
1、选择一个未访问过的点:
-
从数据集中选取一个未被访问过的点P。
2、计算ε邻域内的点数,判断P是否为核心点:
-
计算点P在ε范围内的所有邻居。如果邻域内的点数大于或等于MinPts,则P是一个核心点。
3、若P为核心点:
-
如果P是核心点,则将P及其所有邻域内的点加入一个簇中。
-
对簇中的每个点进行扩展,检查其邻域。如果邻域内的点数大于MinPts,且该点尚未被处理过,则将其添加到簇中,并进一步检查其邻域。
4、若不是核心点,则处理边界点和噪声点:
-
如果一个点没有足够的邻居(即少于MinPts个点在ε邻域内),且不在任何核心点的邻域内,则该点被标记为噪声点。
-
否则,该点会被归类为边界点,属于某个核心点的簇,但它本身不是一个核心点。
5、重复以上迭代步骤,直到所有点都被访问过
-
对数据集中的所有点进行检查,直到所有点都被分配到簇中或被标记为噪声点。
(四)最终结果
-
DBSCAN算法输出的是簇的集合,其中每个簇由核心点及其邻域中的点组成。
-
噪声点不属于任何簇。
参数调优
1、选择初始参数范围
DBSCAN的待调优参数主要为:
-
ε (程序里为eps):初始范围可以通过数据的距离分布估计。例如,计算数据集中每个点到其最近邻点的距离,然后绘制最近邻距离的分布图。这可以帮助找到一个合理的eps初始值。
-
MinPts(程序里为:min_samples):通常设置为数据的维度+1。例如,2D数据可以设置为3,3D数据可以设置为4。如果数据包含噪声较多,可以适当增大该值
2、尝试不同的min_samples值
选择原则一:根据常用经验法则(默认:min_samples = 数据维度 + 1)
-
对于低维数据(如二维或三维),min_samples 的值通常较小,常见的值是 3 到 5。
-
对于高维数据,由于稀疏性的影响,min_samples 的值需要增大,例如 10 或更多。
选择原则二:簇的密度
-
如果你的簇通常非常密集,min_samples 可以设为较小值(如 3 或 5)
-
如果簇的密度较稀疏(例如某些离散型数据),需要更大的 min_samples 值以防止将稀疏区域的点误判为噪声。
选择原则三:调整策略
-
较小的 min_samples 值:
-
识别更多的核心点,可能产生更多簇。
-
但可能导致过拟合(将一些孤立点误判为簇的一部分)。
-
-
较大的 min_samples 值:
-
识别更少的核心点,可能增加噪声点数量。
-
更适合稀疏数据,或者需要更严格的簇定义时使用。
-
3、利用最近邻距离图
最近邻距离分布图是一种帮助确定参数 eps
的可视化方法。通过分析数据点之间的距离分布,它可以揭示数据的密度分布特性。
过程:
(1) 计算每个点的最近邻距离
-
对于每个点,找到它与数据集中其他点的最近邻点的距离。
-
最近邻的数量(即 k 最近邻)通常设置为
min_samples - 1
,因为 DBSCAN 使用min_samples
来定义核心点,减1是因为代码索引由0开始。
(2) 排序最近邻距离
-
对所有点的最近邻距离按照升序排序。
-
排序的目的是清晰展示数据中从密集区域到稀疏区域的变化。
(3) 绘制分布图
-
横轴:数据点(排序后按索引排列)。
-
纵轴:对应点的 k 最近邻距离。
-
图中的膝点位置(即距离上升最快的拐点)通常标志着密集簇与稀疏区域(或噪声点)之间的分界,这个位置即为参数 ε 的最佳值。如下图中的 ε 的最佳值约为0.0025
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors# 数据示例
data = np.random.rand(5000, 2) # 5000个二维点# 计算最近邻距离
k = 4 # 通常k = min_samples - 1,这里我们假设为 4
nbrs = NearestNeighbors(n_neighbors=k).fit(data)
distances, indices = nbrs.kneighbors(data) # indices为最近邻点的索引数组# 排序并绘图
distances = np.sort(distances[:, k-1])
plt.plot(distances)
plt.ylabel('k-NN Distance')
plt.xlabel('Points')
plt.title('Elbow Method for Determining eps')
plt.show()
4、网格搜索调优
可以结合自动化的网格搜索或随机搜索,系统地尝试多个 eps
和 min_samples
的组合。
DBSCAN模型性能评估
评估的主要方法有:
1. 轮廓系数
-
定义:轮廓系数用于评估样本的聚类效果,衡量样本与其簇内其他样本的相似度与样本到最近簇的相似度的差异。
-
范围:轮廓系数值介于-1到1之间。值越接近1,聚类效果越好,值接近0表示样本位于簇的边界,而值接近-1表示聚类结果很差。
-
适用性:适用于评估DBSCAN模型中簇的紧凑性和分离度,尤其在簇形状复杂时,轮廓系数依然具有较好的效果。
2、DB指数 (Davies-Bouldin)
-
定义:DB指数是簇内样本的紧密度与簇间的分离度之间的比率。DB指数越小,表示聚类的质量越高。
-
适用性:可以用于评估不同密度的簇,尤其在簇的形状复杂时具有较好的效果。
3、可视化评估(主观、直观判断)
-
t-SNE或PCA降维:DBSCAN聚类通常适用于非线性数据结构,通过使用t-SNE或PCA将高维数据降维至二维后,可以更直观地观察聚类效果。
-
聚类结果可视化:通过散点图展示DBSCAN算法输出的簇和噪声点,直观评估簇的紧密程度和分离度。
代码示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import DBSCAN
from sklearn.metrics import silhouette_score, davies_bouldin_score
from sklearn.decomposition import PCA# 生成簇数据
X, _ = make_blobs(n_samples=300, centers=3, cluster_std=0.60, random_state=0)# 加入噪声点
noise = np.random.uniform(low=-6, high=6, size=(20, 2))
X = np.vstack([X, noise])# 进行聚类
db = DBSCAN(eps=0.6, min_samples=10)
y_db = db.fit_predict(X)
print("聚类结果为:\n", y_db) # 噪声点标记为-1# 聚类结果为:
# [ 0 1 0 2 2 2 -1 0 2 2 1 1 1 0 1 2 0 0 2 1 2 0 1 0
# 2 2 0 2 1 1 2 0 0 1 1 2 1 -1 0 1 2 1 0 1 1 2 1 -1
# 2 1 2 1 2 2 1 0 0 2 2 0 1 1 0 2 1 2 0 1 0 1 2 2
# 2 2 1 0 1 2 0 0 2 0 1 0 0 -1 1 2 0 0 2 1 2 0 1 1
# 0 1 2 0 1 2 0 1 0 0 2 0 1 1 0 2 0 0 2 2 0 0 1 1
# 1 2 1 1 1 2 1 1 1 2 2 2 0 2 2 1 2 0 2 2 1 0 1 0
# 2 2 0 2 2 1 0 2 0 1 2 2 1 1 0 1 0 0 1 0 2 0 0 0
# 0 2 1 0 2 1 1 -1 0 1 0 0 1 2 0 0 0 0 1 2 0 2 0 0
# 1 1 2 0 1 2 0 2 1 2 0 2 1 2 0 2 0 1 0 0 2 1 1 1
# 1 0 -1 1 0 1 1 1 0 2 2 0 -1 2 0 1 1 0 1 2 -1 -1 0 0
# 1 2 2 -1 2 1 2 2 0 1 1 0 1 1 2 0 1 2 0 0 2 0 2 2
# 0 2 0 1 1 1 1 0 0 0 0 0 2 2 1 0 0 1 1 -1 2 1 2 2
# 1 1 2 2 2 -1 0 0 2 1 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1
# -1 -1 -1 -1 -1 -1 -1 -1]# 可视化聚类结果
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=y_db, cmap='viridis')
plt.title("DBSCAN ")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()
# 计算轮廓系数,排除噪声点
valid_labels = y_db != -1
sil_score = silhouette_score(X[valid_labels], y_db[valid_labels])
print(f"轮廓系数: {sil_score}")
# 轮廓系数: 0.6712686266136648# 计算DB指数
db_index = davies_bouldin_score(X, y_db)
print(f"Davies-Bouldin指数: {db_index}")
# Davies-Bouldin指数: 1.6233355458859566
# PCA降维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)# 可视化PCA降维后的结果
plt.rcParams['font.family'] = 'Microsoft YaHei' # 设置字体为微软雅黑,防止中文标题乱码
plt.figure(figsize=(8, 6))
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y_db, cmap='viridis')
plt.title("PCA降维后的DBSCAN聚类结果")
plt.xlabel("PCA 1")
plt.ylabel("PCA 2")
plt.show()
DBSCAN的优缺点
优点:
能发现任意形状的簇:DBSCAN能够识别形状不规则的簇(如弯曲的、环形的簇等),不像K-means那样只能发现圆形或球形的簇。适用于复杂的数据结构,特别是当簇的形状是非凸时。
不需要预设簇数:不同于K-means需要指定簇的数量,DBSCAN不需要预先设定簇的数量(k)。它根据数据的密度自动决定簇的数量,这对于不确定簇数的数据集非常有用。
能够识别噪声:DBSCAN能够自动识别噪声点(标记为 -1),并将这些点从聚类中分离出来。这对处理含有噪声或异常值的数据集特别有用。
处理大规模数据集时表现较好:在处理具有密集区域的较大数据集时,DBSCAN的表现较好,因为它只处理密度较高的区域,减少了计算量。
适应性强:对不同密度的簇也有较好的适应性,通过调整
eps
和min_samples
参数,可以适应不同密度的数据。缺点:
对参数敏感:DBSCAN对参数
eps
(邻域半径)和min_samples
(最小样本数)非常敏感。选择不合适的参数值会导致聚类效果不好,例如将簇错误地合并或分裂,或将太多的点标记为噪声。在不同的数据集上,选择合适的参数往往需要实验和调优。计算复杂度较高:DBSCAN在高维空间中的计算复杂度较高,因为它需要计算每对数据点之间的距离。特别是当数据量很大时,这个计算过程可能变得非常慢。
不适用于高维数据:在高维空间中,数据点之间的距离趋于相似(“维度灾难”),DBSCAN的效果可能会受到影响。高维空间中的密度定义变得模糊,因此可能导致聚类效果不理想。
无法处理极端不均匀的分布:如果数据集的分布极不均匀(例如某些簇非常密集而其他簇非常稀疏),DBSCAN可能无法很好地聚类,导致簇的质量下降。
总结:
DBSCAN非常适合密度较高、噪声较多、形状复杂的数据集,尤其在实际应用中对噪声的处理和对簇形状的适应性表现出色。但是,它对参数的选择敏感,计算量大,且在处理高维或不同密度的簇时可能表现不佳。在实际应用时需要谨慎选择参数,并进行适当的调优。
适用场景
噪声和离群点较多的场景
数据簇形状复杂且不规则
需要根据数据密度聚类的场景
低维数据
不确定簇数的场景
数据中存在非均匀密度的场景(非极端)
# 若文章对大噶有帮助的话,希望点个赞支持一下叭!