跳转至

14.8   基于密度的聚类

小率用 K-Means 给活动数据分群,结果有些离群同学被硬塞进某个组,月牙形兴趣群也被切开。均哥提醒他:如果簇不是圆形,或者有明显噪声点,可以试试基于密度的办法。

DBSCAN(Density-Based Spatial Clustering of Applications with Noise) 不要求提前给出簇数。它把“点很密的地方”看成簇,把稀疏孤立点标成噪声。

图 14.8.0 在公园活动里识别密集人群和孤立点

它可以不指定有几组,还能识别离群点?
对。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;高维或多密度数据要谨慎。