14.8 基于密度的聚类¶
小率用 K-Means 给活动数据分群,结果有些离群同学被硬塞进某个组,月牙形兴趣群也被切开。均哥提醒他:如果簇不是圆形,或者有明显噪声点,可以试试基于密度的办法。
DBSCAN(Density-Based Spatial Clustering of Applications with Noise) 不要求提前给出簇数。它把“点很密的地方”看成簇,把稀疏孤立点标成噪声。
它可以不指定有几组,还能识别离群点?
对。DBSCAN 关心的不是中心,而是哪里足够密。
14.8.1 两个参数定义密度¶
DBSCAN 有两个核心参数:
- \(\varepsilon\):邻域半径。
min_samples:半径内至少要有多少点,才算密。
根据邻域点数,样本分为三类:
| 点类型 | 含义 |
|---|---|
| 核心点 | \(\varepsilon\) 邻域内点数不少于 min_samples |
| 边界点 | 不够核心,但落在某个核心点邻域内 |
| 噪声点 | 不属于任何密集区域 |
核心点连成片,就形成簇。
14.8.2 DBSCAN 能找非圆形簇¶
DBSCAN 的优势是能处理不规则形状,并天然识别噪声点。它特别适合“密集区域有意义,孤立点也重要”的任务,比如异常行为、空间热点、局部兴趣群。
但它也有困难:
- 不同簇密度差异很大时,一组参数很难兼顾。
- 高维空间里距离变差,密度也难定义。
- \(\varepsilon\) 对结果非常敏感。
如果一个兴趣群很密,另一个很稀,DBSCAN 会不会顾此失彼?
会。这时可以考虑 HDBSCAN 或先重新设计特征空间。
14.8.3 用 k 距离图找 eps¶
一个常见做法是:计算每个点到第 min_samples 个近邻的距离,把这些距离排序。曲线出现明显拐点的位置,可以作为 \(\varepsilon\) 的候选。
这不是严格定理,而是调参线索。最终仍要看聚类结果是否稳定、可解释。
先降维再密度聚类
高维数据直接跑 DBSCAN 往往不稳。可先做 PCA、UMAP 或特征筛选,再在较低维空间里聚类。
14.8.4 用 Python 跑 DBSCAN¶
from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
from collections import Counter
X, _ = make_moons(n_samples=400, noise=0.08, random_state=2026)
X = StandardScaler().fit_transform(X)
model = DBSCAN(eps=0.25, min_samples=8)
labels = model.fit_predict(X)
print(Counter(labels))
print("标签 -1 表示噪声点")
DBSCAN 不是万能聚类器
它擅长不规则形状和噪声,但对参数、尺度和密度差异敏感。聚类前仍要标准化,并检查结果是否符合场景。
小率的笔记本
DBSCAN 用密度定义簇,不用提前指定簇数,能识别噪声点。核心参数是 \(\varepsilon\) 和 min_samples;高维或多密度数据要谨慎。
