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

Python层次聚类分步树状图进度展示相关咨询:现成函数查询与实现建议

回答

Great question! 目前确实没有开箱即用的Python工具能直接帮你展示凝聚式层次聚类每一步迭代的树状图进度——毕竟这类需求更偏向教学演示,而非常规数据分析场景。不过我们可以自己动手实现,核心思路是在每次聚类合并后,基于当前的簇结构生成简化的树状图并实时展示,下面是具体的实现建议和示例代码:

核心思路

要实现分步展示,关键在于跟踪每次聚类合并的核心信息,然后将这些信息转换成scipy.cluster.hierarchy模块能识别的格式,进而绘制对应阶段的树状图:

  • 每次合并两个簇时,记录三个关键数据:被合并的两个簇的ID、它们之间的距离、合并后新簇包含的样本总数(这三个正是scipy的linkage矩阵的三列内容)
  • 初始时每个样本都是独立簇,ID为0到n-1;每次合并后,新簇的ID用n、n+1……这样的递增数字标记

分步实现示例

下面是一个完整的演示代码,模拟凝聚式聚类的合并过程,并在每一步绘制当前状态的树状图:

import numpy as np
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram

# 模拟5个样本的简单数据,方便教学演示
X = np.array([[1, 2], [2, 1], [4, 5], [5, 4], [10, 10]])
n_samples = X.shape[0]

# 初始化:每个样本为一个独立簇,用字典存储簇ID到样本列表的映射
current_clusters = {i: [i] for i in range(n_samples)}
# 记录每一步的合并信息(对应linkage矩阵的行)
linkage_steps = []
# 新簇的起始ID(从样本数量开始递增)
next_cluster_id = n_samples

# 模拟凝聚式聚类的合并过程(这里用簇中心欧氏距离,可替换为你自己的距离计算逻辑)
while len(current_clusters) > 1:
    min_distance = float('inf')
    cluster_a_id = cluster_b_id = -1
    cluster_ids = list(current_clusters.keys())
    
    # 遍历所有簇对,找到距离最近的一对
    for i in range(len(cluster_ids)):
        for j in range(i + 1, len(cluster_ids)):
            id_a = cluster_ids[i]
            id_b = cluster_ids[j]
            # 计算两个簇的中心距离(可替换为单链接、全链接等其他簇间距离)
            center_a = np.mean(X[current_clusters[id_a]], axis=0)
            center_b = np.mean(X[current_clusters[id_b]], axis=0)
            distance = np.linalg.norm(center_a - center_b)
            
            if distance < min_distance:
                min_distance = distance
                cluster_a_id, cluster_b_id = id_a, id_b
    
    # 记录本次合并的信息,存入linkage_steps
    merged_cluster_size = len(current_clusters[cluster_a_id]) + len(current_clusters[cluster_b_id])
    linkage_steps.append([cluster_a_id, cluster_b_id, min_distance, merged_cluster_size])
    
    # 执行簇合并操作
    current_clusters[next_cluster_id] = current_clusters[cluster_a_id] + current_clusters[cluster_b_id]
    del current_clusters[cluster_a_id]
    del current_clusters[cluster_b_id]
    
    # 绘制当前阶段的树状图
    current_linkage = np.array(linkage_steps)
    plt.figure(figsize=(8, 4))
    dendrogram(
        current_linkage,
        labels=[f"Sample {i}" for i in range(n_samples)],
        leaf_rotation=45
    )
    plt.title(f"Iteration {len(linkage_steps)}: Merged clusters {cluster_a_id} & {cluster_b_id}\nDistance: {min_distance:.2f}")
    plt.xlabel("Samples / Clusters")
    plt.ylabel("Cluster Distance")
    plt.tight_layout()
    plt.pause(2)  # 暂停2秒,方便学生观察每一步变化
    plt.close()
    
    next_cluster_id += 1

# 最后绘制完整的最终树状图
plt.figure(figsize=(8, 4))
dendrogram(np.array(linkage_steps), labels=[f"Sample {i}" for i in range(n_samples)])
plt.title("Final Hierarchical Clustering Dendrogram")
plt.xlabel("Samples")
plt.ylabel("Distance")
plt.tight_layout()
plt.show()

优化建议

  • 适配自定义聚类算法:如果你的代码已经实现了特定的簇间距离计算(比如单链接、全链接、沃德法等),只需要替换示例中计算簇距离的部分,保留跟踪合并信息和绘图的逻辑即可。
  • 提升演示效果:如果觉得每次绘图暂停不够流畅,可以用matplotlib.animation.FuncAnimation制作连贯的动画,把每一步的树状图帧组合起来。
  • 处理大数据量:如果样本数量较多,分步绘制会非常缓慢,可以选择每隔N次合并展示一次,或者简化树状图的标签和细节(比如隐藏部分簇标签)。
  • 保存演示素材:可以把每一步的树状图保存为图片,后续拼接成教学用的幻灯片或视频。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:02:43