You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于合并顺序获取Python层次聚类标签,Scipy是否有对应实现?

问题解答

scipy有内置方法可以直接实现你的需求,不需要手动解析层次聚类的合并树,也不需要硬编码距离阈值。

核心实现方法

你需要用scipy.cluster.hierarchy.fcluster方法,搭配criterion='maxclust'参数即可。
层次聚类的合并顺序和最终簇数有严格的对应关系:假设你共有N个初始样本,每完成1次合并簇数减少1,完成k次合并后最终簇数为N - k。你只需要把目标簇数传给fcluster的t参数,就能得到对应合并阶段的聚类标签。
以你举的5个样本(p1-p5)的场景为例:

  • 需要完成至少1次合并(得到3个簇):调用fcluster(Z, t=3, criterion='maxclust')
  • 需要完成至少2次合并(得到2个簇):调用fcluster(Z, t=2, criterion='maxclust')
    返回的结果是和样本顺序一一对应的聚类标签数组,和你举例的划分结果完全匹配。

完整代码示例

from scipy.cluster.hierarchy import linkage, fcluster
import numpy as np

# 模拟5个样本的特征数据
X = np.array([
    [1, 2], # p1
    [4, 5], # p2
    [10, 12], # p3
    [10.5, 12.2], # p4
    [4.2, 5.1] # p5
])
# 生成层次聚类合并矩阵Z
Z = linkage(X, method='ward')

# 获取完成1次合并后的3簇标签
labels_3cluster = fcluster(Z, t=3, criterion='maxclust')
print("3簇标签:", labels_3cluster) # 输出类似[1,2,3,3,2],对应你举例的划分

# 获取完成2次合并后的2簇标签
labels_2cluster = fcluster(Z, t=2, criterion='maxclust')
print("2簇标签:", labels_2cluster) # 输出类似[1,2,2,2,2],对应你举例的划分

手动解析扩展(可选)

如果需要自定义处理合并过程,可以直接解析linkage方法返回的Z矩阵:
Z矩阵是形状为(N-1, 4)的二维数组,每一行对应一次合并操作,按合并先后顺序排列:

  • 第1、2列:本次合并的两个簇的编号
  • 第3列:本次合并的距离阈值
  • 第4列:合并后新簇包含的样本总数
    你可以按行遍历Z矩阵,自行维护簇的分组关系,实现更定制化的需求。

场景适配说明

你的需求刚好匹配该方法的适用场景:即使新增样本后合并的距离阈值发生变化,只要你需要的是固定合并次数后的聚类结果,直接指定对应的目标簇数即可,完全不需要硬编码距离阈值,也不受阈值波动影响。
你提到的层次聚类示意图如下:
层次聚类示意图

内容的提问来源于stack exchange,提问作者user96564

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 10:15:01