一张传感器读数表里,绝大多数点挤在几条带状区域,另有几十个点散落在空白处。把这份数据交给 AI 做聚类,用 K-means 跑,这些孤点会被硬塞进最近的簇,把簇心拽偏;用 DBSCAN 跑,它们被单独标成噪声,不参与任何簇的统计。差别不在算法聪明与否,而在它允不允许不归属这件事存在。这篇讲清 DBSCAN 用哪两个参数定义密度、簇是怎么从一个种子扩散开的、参数选错时会出现哪几种症状,以及它在密度不均匀的数据上为什么会失灵。
两个参数,定义了挤的标准
DBSCAN 不关心簇的形状,只关心点的邻居多不多。它用两个数把密度说清楚:邻域半径 eps,以及邻域内至少要有多少个点 minPts。有了这两个数,每个点就有了身份。核心点是邻居数量达标的那种,它是簇的种子;边界点自己的邻居不够,但落在某个核心点的圈里,只能算作簇的边缘;剩下的既不是核心点、也不在任何核心点邻域内,就被判为噪声。这套划分的好处是把异常写进了算法本身,不用另外训一个检测模型。
簇是靠扩散长出来的
算法从一个尚未处理的核心点出发,把它邻域内的点全部收进当前簇。新收进来的点如果本身也是核心点,就继续以它为圆心往外扩,这个过程像水在粗糙地面上蔓延,遇到密度够的地方就流过去,遇到空隙就停下。扩散不到任何核心点的区域,自然留成噪声。整个流程只扫一遍数据,不需要迭代优化,也不会有收敛到局部最优的困扰,代价是它对参数的依赖被放大了,因为没有任何迭代过程能修正一开始的划分。
参数一动,结论就换一个故事
DBSCAN 没有标签可以对照,参数的影响只能从结果形态反推。下面四种症状,基本覆盖了实际调参时会遇到的情况:
| 参数状态 | 你看到的结果 | 背后原因 | 调整方向 |
|---|---|---|---|
| eps 偏小 | 大量点被判成噪声,簇碎成小块 | 邻域够不到足够邻居,核心点太少 | 按 k-距离曲线的拐点往上调 |
| eps 偏大 | 所有点并成一两个大簇 | 不同簇之间被稀疏点桥接起来 | 缩小半径,或先剔除桥接点 |
| minPts 偏小 | 噪声点被当成小簇 | 两三个点的组合就能成为核心点 | 不低于特征维度加一,通常取更大 |
| minPts 偏大 | 稀疏但真实的簇整体消失 | 密度低的区域无法产生核心点 | 结合业务上一簇最少几个样本来定 |
实操中比较可靠的办法是画 k-距离曲线:对每个点算它到第 k 个近邻的距离,排序后画出来,曲线拐弯的位置通常是个合理的 eps。这只是起点,最终还得看分出来的簇在业务上说不说得通。
它默认了哪些前提
DBSCAN 的隐含假设比它表面上看起来多。第一,它假设同一个簇内部的密度大致均匀,这样一套 eps 和 minPts 才能同时适用;第二,它假设簇与簇之间隔着明显的低密度区域,否则扩散会跨过去;第三,它假设所用的距离度量在这个空间里有意义,这一点在高维数据上很容易不成立——维度一高,点与点之间的距离趋于接近,密度的区分度被抹平,eps 调到哪里都差不多。距离怎么选本身就是个问题,可参考 余弦相似度与欧氏距离的差别。
密度不均匀时它会把两簇并成一簇
密度不均是最常见的失效场景,也是它和 K-means 最本质的差距所在。数据里如果有一团很密的小簇和一片很疏的大簇,按密簇调出来的 eps 会让疏簇整个变成噪声,按疏簇调出来的 eps 又会把密簇和周围的杂点粘成一坨。这个矛盾不是调参能解决的,需要换用能处理多密度的方法,或者先做变换。除此之外还有几条:它不能直接给新样本打标签,模型里没有预测这一步,新点来了只能重跑或者另找办法;结果对点的处理顺序有轻微依赖,边界点归属哪个簇可能不稳定;样本量大时邻域查询的开销也不低,通常要靠空间索引才跑得动。还有一点常被忽略——它把噪声点单独拎出来了,但这些点未必真是错误数据,可能只是少数群体,直接删掉会造成另一种偏差。
怎么判断一次聚类结果值不值得信
没有标准答案的算法,更需要外部校验。三个动作成本很低:把簇画到二维上看形状是否符合预期;拿几个簇的样本回业务方确认这些人和这些设备真的是一类吗;换一组参数重跑,看划分是否稳定,如果 eps 微调就让结果面目全非,那这个结论不该拿去决策。数据本身也会变,上个月调好的参数,这个月可能就不合适了,这种整体分布的变化属于 数据漂移 的范畴,需要定期重跑而不是一劳永逸。相比之下,K-means 和 层次聚类 各有自己的假设,选哪个取决于你的数据更像哪一种,而不是哪个方法更新。
速查:DBSCAN
- 两个参数:邻域半径 eps、最小邻居数 minPts
- 三类点:核心点、边界点、噪声点
- 强项:不预设簇数、能识别任意形状、自带噪声标记
- 硬伤:密度不均时一套参数无法兼顾,高维空间下密度失去区分度


