通俗易懂讲透 DBSCAN 聚类算法|本科生/研究生都能看懂
本文用大白话+生活比喻+公式拆解+完整代码+可视化,把 DBSCAN 从原理、流程、参数、优缺点到实战讲得明明白白,适合机器学习入门、面试复习、课程笔记。
一、先搞懂:DBSCAN 到底是什么?
一句话定义:
DBSCAN = 基于密度的聚类算法,自动找密集团、自动识别噪声,不用提前设聚类数量。
和 K-Means 最大区别:
- K-Means:只能分球形簇,必须先告诉 K 是几
- DBSCAN:任意形状都能分,自动找簇、自动剔异常点
二、最形象比喻:人群扎堆
把数据点看作一群人:
- 核心点:周围人很多,是人群中心
- 边界点:在人群边上,不算中心但属于这一堆
- 噪声点:孤零零一个人,不属于任何群体
DBSCAN 就是:
找到所有密集人群 → 连成一簇 → 把落单的标为噪声。
三、两个必须懂的超参数
DBSCAN 只需要设两个参数,非常简单:
1. ε(eps)
- 半径:以一个点为中心,画圆的半径
- 含义:多大范围内的点才算“邻居”
2. MinPts(min_samples)
- 半径内至少要有多少个点,才算“密集”
- 包括自己
四、3 种点的定义(面试必考)
-
核心点 Core
半径 ε 内点数量 ≥ MinPts -
边界点 Border
不是核心点,但落在某个核心点的 ε 范围内 -
噪声点 Noise
既不是核心,也不在任何核心点范围内(标为 -1)
五、DBSCAN 算法流程(4 步背会)
- 随便选一个没访问过的点
- 看它是不是核心点
- 如果是,把它密度可达的所有点连成一个簇
- 继续遍历,直到所有点处理完,剩下的就是噪声
六、代码实战:月牙形数据聚类(最强演示)
直接复制可运行,包含:
- 月牙数据生成
- 标准化
- DBSCAN 聚类
- K 距离图选 ε
- 聚类结果可视化
- 轮廓系数评估
- 网格搜索调参
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_moons
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN
from sklearn.metrics import silhouette_score
from sklearn.neighbors import NearestNeighbors
from sklearn.model_selection import ParameterGrid
# ===================== 1. 生成月牙数据 =====================
X, _ = make_moons(n_samples=3000, noise=0.1, random_state=42)
# 标准化(非常重要!)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# ===================== 2. K-距离图选择最优 eps =====================
min_samples = 5
neighbors = NearestNeighbors(n_neighbors=min_samples)
neighbors_fit = neighbors.fit(X_scaled)
distances, _ = neighbors_fit.kneighbors(X_scaled)
distances = np.sort(distances[:, -1])
plt.figure(figsize=(10,4))
plt.plot(distances)
plt.title('K-distance Graph(拐点即为最佳eps)')
plt.xlabel('点排序')
plt.ylabel('第k个近邻距离')
plt.grid()
plt.show()
# ===================== 3. DBSCAN 聚类 =====================
eps = 0.3
db = DBSCAN(eps=eps, min_samples=min_samples)
labels = db.fit_predict(X_scaled)
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = list(labels).count(-1)
print(f"聚类数量:{n_clusters}")
print(f"噪声点数:{n_noise}")
# ===================== 4. 可视化结果 =====================
plt.figure(figsize=(10,6))
sns.scatterplot(x=X_scaled[:,0], y=X_scaled[:,1], hue=labels, palette='viridis', s=30)
plt.title(f'DBSCAN 聚类结果 | eps={eps}, min_samples={min_samples}')
plt.show()
# ===================== 5. 轮廓系数评估 =====================
if len(set(labels)) > 1:
score = silhouette_score(X_scaled, labels)
print(f"轮廓系数:{score:.3f}")
# ===================== 6. 网格搜索自动调参 =====================
param_grid = {'eps': [0.2, 0.25, 0.3, 0.35, 0.4], 'min_samples': [3,5,7,10]}
best_score = -1
best_param = None
for params in ParameterGrid(param_grid):
labels = DBSCAN(**params).fit_predict(X_scaled)
if len(set(labels)) > 1:
score = silhouette_score(X_scaled, labels)
if score > best_score:
best_score = score
best_param = params
print("最优参数:", best_param)
print("最优轮廓系数:", best_score)
七、DBSCAN 优点(面试必背)
- 不用指定聚类数量
- 能识别噪声点,对异常值鲁棒
- 能聚类任意形状(月牙、螺旋、环形都行)
- 对初始值不敏感
- 簇的大小形状不限
八、DBSCAN 缺点(必须知道)
- 对 eps 和 min_samples 非常敏感
- 高维数据距离失效,效果变差
- 密度不均匀的数据很难调好参数
- 大数据集速度较慢
九、DBSCAN vs K-Means(速记表)
| 特点 | K-Means | DBSCAN |
|---|---|---|
| 聚类形状 | 球形 | 任意形状 |
| 是否指定簇数 | 必须 | 不用 |
| 噪声处理 | 差 | 强 |
| 离群点敏感 | 敏感 | 不敏感 |
| 速度 | 快 | 较慢 |
| 高维 | 一般 | 差 |
十、什么时候用 DBSCAN?
✅ 适合
- 数据簇形状不规则
- 有噪声、异常点
- 不知道聚几类
- 数据分布复杂(月牙、环形、螺旋)
❌ 不适合
- 高维数据
- 密度差异很大
- 超大规模数据
十一、一句话总结
DBSCAN 是基于密度的聚类神器,自动找簇、自动剔噪,专治各种不规则形状数据,是机器学习必须掌握的聚类算法。
1万+

被折叠的 条评论
为什么被折叠?



