news 2026/4/10 20:22:45

从零开始:如何用Scipy的Dendrogram解锁数据背后的层次结构

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零开始:如何用Scipy的Dendrogram解锁数据背后的层次结构

从零开始:用Scipy的Dendrogram揭示数据层次结构的完整指南

当你面对一堆看似杂乱无章的数据时,是否曾想过这些数据内部可能隐藏着某种层次结构?层次聚类算法正是解决这一问题的利器,而Scipy库中的dendrogram(树状图)则是展示这种层次结构的绝佳工具。本文将带你从基础概念出发,通过一个完整的案例,掌握如何使用Scipy的linkage和dendrogram函数来构建和解读层次聚类树状图。

1. 层次聚类基础与核心概念

层次聚类是一种无需预先指定聚类数量的无监督学习方法,它通过计算数据点之间的相似度(距离)来构建树形结构。与K-means等划分式聚类不同,层次聚类能够展示数据在不同粒度下的分组情况。

核心概念解析

  • 凝聚式(Agglomerative):自底向上方法,每个数据点初始为一个簇,逐步合并最相似的簇
  • 分裂式(Divisive):自顶向下方法,所有数据点初始为一个簇,逐步分裂为更小的簇
  • 连接准则(Linkage Criterion):决定如何计算簇间距离的方法,常见有:
    • 单连接(single):两个簇中最近点之间的距离
    • 全连接(complete):两个簇中最远点之间的距离
    • 平均连接(average):两个簇所有点对距离的平均值
    • Ward方法:最小化合并后的簇内方差增量
from scipy.cluster.hierarchy import linkage, dendrogram from matplotlib import pyplot as plt import numpy as np # 生成示例数据 np.random.seed(42) data = np.concatenate([ np.random.normal(loc=[0,0], scale=1, size=(50,2)), np.random.normal(loc=[5,5], scale=1, size=(50,2)) ]) # 计算连接矩阵 Z = linkage(data, method='ward')

2. 数据准备与预处理实战

在应用层次聚类前,数据准备是至关重要的一步。不合适的预处理可能导致聚类结果失真。

关键预处理步骤

  1. 数据清洗

    • 处理缺失值(删除或填充)
    • 去除异常值(使用IQR或Z-score方法)
  2. 特征标准化

    • 当特征量纲不同时,必须进行标准化
    • 常用方法:Z-score标准化、Min-Max归一化
  3. 距离度量选择

    • 欧氏距离:适用于连续变量
    • 余弦相似度:适用于文本或高维稀疏数据
    • 马氏距离:考虑特征间相关性
from sklearn.preprocessing import StandardScaler # 标准化数据 scaler = StandardScaler() data_scaled = scaler.fit_transform(data) # 不同距离度量的效果对比 methods = ['euclidean', 'cityblock', 'cosine'] fig, axes = plt.subplots(1, 3, figsize=(18, 5)) for ax, metric in zip(axes, methods): Z = linkage(data_scaled, method='complete', metric=metric) dendrogram(Z, ax=ax) ax.set_title(f'Metric: {metric}') plt.tight_layout()

3. 构建与解读树状图

树状图是层次聚类的可视化呈现,正确解读它需要理解几个关键元素:

树状图组成要素

  • 叶子节点:代表原始数据点
  • 连接高度:表示两个簇合并时的距离
  • 颜色阈值:用于区分不同簇的视觉辅助

解读技巧

  1. 观察连接高度的突变点,这通常表示自然的聚类分割
  2. 水平切割树状图可以得到不同数量的簇
  3. 簇内连接高度差异小表示簇内一致性高
plt.figure(figsize=(12, 6)) dendrogram(Z, truncate_mode='lastp', # 显示最后p个合并的簇 p=12, # 显示12个叶节点 show_leaf_counts=True, # 显示叶节点数量 leaf_rotation=90., # 旋转叶标签 leaf_font_size=12., # 叶标签字体大小 show_contracted=True) # 显示收缩的叶节点 plt.title('层次聚类树状图') plt.xlabel('样本索引或(簇大小)') plt.ylabel('距离') plt.axhline(y=5, c='k', linestyle='--') # 添加水平切割线 plt.show()

4. 参数调优与高级技巧

Scipy的dendrogram函数提供了丰富的参数来控制树状图的显示效果和聚类行为。

关键参数详解

参数类型描述常用值
pint控制显示的簇数量10-30
truncate_modestr截断模式'lastp', 'level', None
color_thresholdfloat颜色区分阈值0.7*max(Z[:,2])
orientationstr树状图方向'top', 'bottom', 'left', 'right'
labelslist叶节点标签自定义标签列表
leaf_rotationfloat叶标签旋转角度0-90

高级技巧

  1. 动态颜色阈值:根据数据特性自动设置颜色阈值
  2. 自定义叶标签:使用leaf_label_func参数添加丰富信息
  3. 交互式可视化:结合plotly实现可交互树状图
# 自定义颜色阈值和标签 color_threshold = 0.7 * max(Z[:,2]) plt.figure(figsize=(15, 8)) dendrogram(Z, color_threshold=color_threshold, labels=[f'样本_{i}' for i in range(len(data))], leaf_label_func=lambda x: f'ID:{x}', above_threshold_color='grey') # 高于阈值的连接颜色 plt.title('带自定义颜色和标签的树状图') plt.show()

5. 实战案例:鸢尾花数据集分析

让我们通过经典的鸢尾花数据集来展示层次聚类的完整流程。

from sklearn.datasets import load_iris # 加载数据 iris = load_iris() X = iris.data y = iris.target # 标准化并计算连接矩阵 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) Z = linkage(X_scaled, method='ward') # 绘制树状图 plt.figure(figsize=(12, 6)) dendrogram(Z, labels=y, orientation='right') plt.title('鸢尾花数据集层次聚类') plt.xlabel('距离') plt.ylabel('鸢尾花种类') plt.show() # 提取聚类结果 from scipy.cluster.hierarchy import fcluster clusters = fcluster(Z, t=3, criterion='maxclust') # 评估聚类效果 from sklearn.metrics import adjusted_rand_score print(f"调整兰德指数: {adjusted_rand_score(y, clusters):.3f}")

结果分析

  • 树状图清晰显示了三个主要簇,与鸢尾花的三个种类基本吻合
  • 调整兰德指数接近1表明聚类结果与真实分类高度一致
  • 可以观察到setosa种类与其他两种区分明显,versicolor和virginica有部分重叠

6. 常见问题与解决方案

在实际应用中,你可能会遇到以下典型问题:

问题1:大数据集导致树状图难以阅读

  • 解决方案:使用truncate_mode参数简化显示
dendrogram(Z, truncate_mode='level', p=5)

问题2:如何确定最佳聚类数量

  • 解决方案:结合轮廓系数和树状图高度变化
from sklearn.metrics import silhouette_score # 尝试不同聚类数量 range_n_clusters = range(2, 10) silhouette_scores = [] for n_clusters in range_n_clusters: clusters = fcluster(Z, n_clusters, criterion='maxclust') silhouette_scores.append(silhouette_score(X_scaled, clusters)) plt.plot(range_n_clusters, silhouette_scores) plt.xlabel('聚类数量') plt.ylabel('轮廓系数') plt.show()

问题3:处理高维数据

  • 解决方案:先降维再聚类
from sklearn.decomposition import PCA pca = PCA(n_components=2) X_pca = pca.fit_transform(X_scaled) Z_pca = linkage(X_pca, method='ward')

7. 与其他聚类方法的对比

层次聚类并非适用于所有场景,了解其优缺点有助于做出正确选择:

对比表格

方法优点缺点适用场景
层次聚类可视化直观,无需预设K值计算复杂度高(O(n³))中小数据集,需要层次关系
K-means计算效率高(O(n))需要预设K值,对异常值敏感大数据集,球形簇
DBSCAN能发现任意形状簇,抗噪声参数敏感,高维效果差非凸形状,含噪声数据

选择建议

  • 当数据量<1000且需要可视化解释时,优先考虑层次聚类
  • 对于文本数据,可尝试结合TF-IDF和余弦相似度
  • 在生物信息学等领域,层次聚类仍是首选方法
# 对比K-means和层次聚类 from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=3) kmeans_labels = kmeans.fit_predict(X_scaled) hierarchical_labels = fcluster(Z, 3, criterion='maxclust') fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6)) ax1.scatter(X[:,0], X[:,1], c=kmeans_labels) ax1.set_title('K-means聚类') ax2.scatter(X[:,0], X[:,1], c=hierarchical_labels) ax2.set_title('层次聚类') plt.show()

在实际项目中,我经常发现层次聚类在探索性分析阶段特别有价值。它提供的树状图不仅能展示最终聚类结果,还能揭示数据在不同尺度下的组织结构,这是其他聚类方法难以替代的。当处理基因表达数据时,通过调整颜色阈值和切割高度,往往能发现意想不到的生物标记物组合。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/5 18:33:25

Screen to Gif 时间轴功能通俗解释:精准编辑动图

ScreenToGif 时间轴:一个被低估的「时间外科医生」 你有没有过这样的经历? 录完一段IDE操作,想突出某次点击——结果删一帧,光标跳变;加速两倍,高亮一闪而过;手动调延迟,整段节奏全乱……最后导出的GIF像喝醉了一样晃。 这不是你的问题。是绝大多数GIF工具根本没把「…

作者头像 李华
网站建设 2026/4/8 23:29:06

零基础玩转AI绘画:WuliArt Qwen-Image Turbo保姆级教程

零基础玩转AI绘画&#xff1a;WuliArt Qwen-Image Turbo保姆级教程 不用懂代码、不需配环境、不看参数文档&#xff0c;一台RTX 4090就能跑起来的AI绘画神器来了。本文将带你从完全零基础开始&#xff0c;5分钟完成部署&#xff0c;10分钟生成第一张10241024高清图——全程中文…

作者头像 李华
网站建设 2026/4/10 14:22:56

通俗解释USB转232驱动安装步骤(适合初学者)

USB转232驱动安装:不是点下一步,而是读懂硬件与系统的对话 你有没有过这样的经历——新买的USB转RS-232线插上电脑,设备管理器里却只显示一个“未知设备”,或者明明装了驱动,COM端口就是不出现?更糟的是,端口出现了,一发数据就乱码、超时、丢帧……调试到凌晨三点,最…

作者头像 李华
网站建设 2026/4/8 7:13:03

LongCat-Image-Edit动物百变秀:5分钟学会用自然语言编辑图片

LongCat-Image-Edit动物百变秀&#xff1a;5分钟学会用自然语言编辑图片 你有没有试过想把一张宠物照变成卡通形象&#xff0c;或者让家里的猫瞬间化身森林之王&#xff1f;不用打开PS&#xff0c;不用学图层蒙版&#xff0c;甚至不用点选任何区域——只要一句话&#xff0c;就…

作者头像 李华
网站建设 2026/4/5 16:36:46

keil5编译器5.06下载+注册机使用合法合规性深度剖析

Keil Vision5 与 ARMCC v5.06&#xff1a;一场嵌入式开发者的确定性实践 你有没有遇到过这样的情况&#xff1a; 同一份代码&#xff0c;在同事电脑上跑得稳如泰山&#xff0c;烧进自己板子却在某个中断里莫名跳飞&#xff1f; 调试时明明设置了断点&#xff0c;IDE 却提示“…

作者头像 李华
网站建设 2026/4/10 19:29:17

WordPress插件 星空飘动广告插件

源码介绍&#xff1a; 后台可上传本地图片、设置大小、链接和初始位置&#xff0c;广告可在网页上浮动&#xff0c;鼠标悬停暂停, 可从媒体库选择图片&#xff0c;能无限添加广告。星空图床系统也是默默无闻做的哦。 下载地址 &#xff08;无套路&#xff0c;无须解压密码&a…

作者头像 李华