观文听傑

返回

上一篇的 DBSCAN 用一组 eps/min_samples 切出密度连通簇。但商品目录可能同时有“食品—饮料—无糖饮料”三层结构,用户分群也可能既需要 3 个大类,又需要 12 个细分群。一次只给一组扁平标签,会丢掉这些嵌套关系。

凝聚层次聚类(Agglomerative Hierarchical Clustering)先把每个样本看成一个簇,再反复合并最接近的两个簇,形成一棵树。本文只讲透三个环节:簇间距离 linkage、逐步合并,以及如何切树得到不同粒度。

01 为什么一组标签不够?#

扁平聚类只回答“现在分几组”,层次结构还记录“哪些小组先组成大组”:

样本层          局部小组             全部样本

A   B   C   D     {A,B}   {C,D}       {A,B,C,D}
│   │   │   │       \       /             │
└─1─┘   └─2─┘        \─4.5─/              根

在高度 1.5 切:{A,B}, {C}, {D}
在高度 3.0 切:{A,B}, {C,D}
text

树状图(Dendrogram)的叶子是样本,内部节点是一次合并,纵轴通常是本次合并的距离或代价。它保存了从 NN 个单点簇到 1 个总簇的全部嵌套过程;最终标签只是选择一条水平切线后的结果。

02 算法每一轮究竟比较什么?#

输入 XRN×DX\in\mathbb R^{N\times D}。初始化时:

C(0)={{x1},,{xN}}\mathcal C^{(0)}=\{\{x_1\},\ldots,\{x_N\}\}

tt 轮在当前簇集合中寻找:

(A,B)=argminABdlink(A,B)(A^*,B^*)=\arg\min_{A\ne B} d_{\text{link}}(A,B)

再用 ABA^*\cup B^* 替换这两个簇。真正决定几何的不是“合并”二字,而是簇间距离 dlinkd_{\text{link}},也称联接准则(Linkage Criterion)。

X [N,D]
  │ 两两样本距离

距离/近邻结构 ──► 当前所有簇对的 linkage
                         │ 取最小

              children[t] = [left,right]
              distances[t] = merge_height
                         │ 重复 N-1 次

              合并树 ──切割──► labels [N]
text

03 四种 linkage 如何改变“最近的两个簇”?#

设簇 A,BA,B 中点对距离为 d(xi,xj)d(x_i,x_j)

dsingle(A,B)=miniA,jBd(xi,xj)d_{single}(A,B)=\min_{i\in A,j\in B}d(x_i,x_j) dcomplete(A,B)=maxiA,jBd(xi,xj)d_{complete}(A,B)=\max_{i\in A,j\in B}d(x_i,x_j) daverage(A,B)=1ABiAjBd(xi,xj)d_{average}(A,B)=\frac{1}{|A||B|}\sum_{i\in A}\sum_{j\in B}d(x_i,x_j)
linkage关注什么常见几何典型风险
single最近的一对点可沿细长或弯曲链延伸少量桥接点造成 chaining
complete最远的一对点偏好直径较小的紧凑簇对极端点敏感
average所有跨簇点对平均在两者之间折中仍依赖距离与尺度
ward合并后增加的 SSE偏好紧凑、方差小的簇只适合欧氏几何

Ward 联接(Ward Linkage)不是简单点对距离。若 A,BA,B 的样本数为 nA,nBn_A,n_B,均值为 μA,μB\mu_A,\mu_B,合并导致的簇内平方和增量为:

Δ(A,B)=nAnBnA+nBμAμB22\Delta(A,B)=\frac{n_An_B}{n_A+n_B}\|\mu_A-\mu_B\|_2^2

它选择 Δ\Delta 最小的合并,因此和 K 均值一样偏好欧氏空间中的紧凑簇。ward 不能随意换成余弦距离。

04 用四个一维点手算完整合并树#

A=0,B=1,C=4,D=6A=0,B=1,C=4,D=6,使用绝对距离与 average linkage。初始最小距离是 d(A,B)=1d(A,B)=1,先合并 {A,B}\{A,B\}。剩余候选:

davg({A,B},{C})=04+142=3.5d_{avg}(\{A,B\},\{C\})=\frac{|0-4|+|1-4|}{2}=3.5 d(C,D)=2d(C,D)=2

所以第二步合并 {C,D}\{C,D\}。最后两个簇的距离为:

04+06+14+164=4+6+3+54=4.5\frac{|0-4|+|0-6|+|1-4|+|1-6|}{4} =\frac{4+6+3+5}{4}=4.5
步骤 tt合并节点新节点编号高度新簇大小
0A(0), B(1)41.02
1C(2), D(3)52.02
2节点 4, 节点 564.54
高度
4.5          ┌───────────────┐
             │               │
2.0          │          ┌────┴────┐
1.0     ┌────┴────┐     │         │
0       A         B     C         D

             在 3.0 处切割 -> 两簇 {A,B} 与 {C,D}
text

节点编号大于等于 NN 时表示先前产生的内部节点;第 tt 个新节点编号就是 N+tN+t。这正是 scikit-learn children_ 的编码方式。

05 不调用聚类器,写出最小 average linkage#

下面实现故意每轮枚举所有簇对,只适合小数据教学核对:

真实实现会维护距离更新和优先结构;不要把这段 O(N3)O(N^3) 风格的教学代码用于生产数据。

06 用 scikit-learn 1.9 正确落地#

当前官方 AgglomerativeClustering API 使用 metric 而不是旧参数 affinity。若要保存完整树及合并高度:

也可以不用预先指定簇数,改用距离阈值切树:

cut = AgglomerativeClustering(
    n_clusters=None,
    distance_threshold=2.4,
    metric='euclidean',
    linkage='complete',
    compute_full_tree=True,
    compute_distances=True,
)
labels = cut.fit_predict(X_scaled)
python

distance_threshold 非空时,n_clusters 必须为 None,完整树必须计算。compute_distances=True 便于画树状图,但会增加计算与内存开销。

07 连通约束怎样阻止“不该发生的跨越”?#

图像像素只应与空间邻居先合并,网页也可能只允许沿链接关系合并。连接矩阵 connectivity [N,N] 指定哪些样本对有资格跨簇连接:

约束能保留局部结构并减少候选合并,但图若断裂或 n_neighbors 太小,会让结果被人为拓扑主导。记录连通分量数、节点度分布,并在相邻的邻居数上做稳定性检查。

08 怎样切树,而不是对树状图“看图说话”?#

树状图可帮助发现明显的高度跳跃,但切线仍是模型选择:

  1. 在业务可接受的簇数范围内比较多个切法;
  2. 检查重采样、时间切片和小幅参数变化后的簇匹配稳定性;
  3. 同时报告簇大小,防止产生大量单点簇;
  4. 有标签时才使用 ARI 等外部指标,不能偷看测试标签选切线;
  5. 无标签时结合轮廓系数、领域解释与下游任务,但不要把任一内部指标当真值。

合并高度的绝对值依赖特征缩放、距离和 linkage。不同设置下的“高度 2.4”不能直接比较。

09 为什么它没有自然的 predict(X_new)#

层次聚类的树是训练样本集合上的全局合并结果。加入一个新点,可能改变早期最近簇对,随后整棵树都不同。因此 AgglomerativeClustering 提供 fit/fit_predict 和训练标签,没有原生 predict

如果业务必须持续接收新样本,应明确改写语义:冻结旧簇后训练一个监督分类器进行近似外推;定期全量重聚类并匹配簇身份;或使用有原生新样本分配规则的方法。不要把“分到最近质心”说成层次聚类本身。

10 复杂度、失败场景与调试路径#

层次方法通常至少需要平方级距离或候选关系;稠密大样本时,时间和内存会先于公式成为瓶颈。最短检查路径是:

  1. 特征量纲主导:打印缩放前后各列分位数,抽查最近点是否符合语义。
  2. single 链化:检查连接两个主体簇的少数点,改用 average/complete 或处理噪声。
  3. complete 被异常点拉高:定位决定最大跨簇距离的样本,不要只看最终颜色。
  4. Ward 用错距离:Ward 只能用欧氏距离;类别/文本数据应另选度量和 linkage。
  5. 切线不稳定:对样本重采样,比较树切割后的共聚类矩阵,而非直接比较可置换的编号。
  6. 大数据耗尽内存:先抽样验证,构建有意义的稀疏 connectivity,或评估 BIRCH/mini-batch 方法。
  7. 把树当因果分类学:层次只反映输入表示与准则,不证明真实世界存在对应物种式层级。

11 与相近方法的边界#

方法输出结构主要几何/参数噪声与新样本
K 均值一层扁平标签中心、簇数、欧氏 SSE强制分配;可按中心预测
DBSCAN密度连通标签eps/min_samples可标噪声;无原生预测
凝聚层次合并树与切割linkage、距离、切线通常强制入树;无原生预测
谱聚类图嵌入后的标签相似图、特征向量、簇数非凸结构;通常是传导式方法
BIRCHCF 压缩树阈值、分支因子面向大数据增量压缩

层次聚类的核心价值是保留多粒度关系,不是自动免除“选多少簇”的判断。

12 今天真正需要记住什么?#

凝聚层次聚类从单点簇出发,每轮按 linkage 合并最近簇,并用 children_ 与合并高度保存一棵树。single、complete、average 和 Ward 对“簇有多近”给出不同答案;切树得到的标签依赖尺度、距离、联接与粒度选择。可靠实践要检查树的稳定性、簇大小和计算成本,并承认它没有自然的新样本预测。

13 思考题与小练习#

  1. [0,1,4,6][0,1,4,6] 分别手算 single 与 complete linkage 的三次合并高度。最后一次高度为何分别是 3 与 6?
  2. 给四点例子加入异常点 100,比较 average、complete 与 Ward 的树。哪个联接最直接受到最大距离影响?
  3. 在月牙数据上比较无约束和 10 近邻 connectivity 的 Ward 聚类;画出近邻图、合并高度和两种切割,并解释差异来自哪里。

相关工作#

14 下一篇预告#

linkage 在原空间里决定合并顺序,但两条缠绕曲线上的“全局欧氏距离”仍可能误导。下一篇将把样本变成相似图,推导图拉普拉斯与谱嵌入:为什么在原空间难切的非凸簇,能在特征向量坐标中被简单分开。

不预先选定粒度,样本怎样长成一棵簇树?层次聚类的 linkage 与树状图
https://zwjcode.cn/blog/hierarchical-clustering-linkage-dendrogram
作者
发布于 2026年8月28日
版权协议 CC BY-NC-SA 4.0
评论加载似乎遇到了问题,请尝试刷新页面。