首页
/ SciPy层次聚类算法详解:scipy.cluster.hierarchy模块解析

SciPy层次聚类算法详解:scipy.cluster.hierarchy模块解析

2025-07-06 02:47:44作者:虞亚竹Luna

层次聚类概述

层次聚类(Hierarchical Clustering)是一种重要的无监督机器学习方法,它通过构建树状图(dendrogram)来表示数据点之间的层次关系。SciPy库中的scipy.cluster.hierarchy模块提供了完整的层次聚类实现,包含多种聚类算法、可视化工具和辅助函数。

核心功能模块

1. 聚类切割函数

这些函数用于将层次聚类结果切割成平面聚类或找到切割后形成的森林的根节点:

  • fcluster: 根据给定阈值从层次聚类中形成平面聚类
  • fclusterdata: 直接对原始数据执行聚类并返回平面聚类结果
  • leaders: 识别平面聚类中的领导节点

2. 凝聚聚类算法

提供多种凝聚聚类(agglomerative clustering)方法,每种方法定义了不同的簇间距离计算方式:

  • linkage: 核心聚类函数,支持多种方法
  • single: 单链接(最近邻)算法
  • complete: 全链接(最远邻)算法
  • average: 平均链接(UPGMA)算法
  • weighted: 加权平均链接(WPGMA)算法
  • centroid: 质心链接(UPGMC)算法
  • median: 中值链接(WPGMC)算法
  • ward: Ward方差最小化算法

3. 层次结构统计

计算层次聚类相关统计量的函数:

  • cophenet: 计算共表相关系数
  • inconsistent: 计算不一致性系数
  • maxinconsts: 计算最大不一致性
  • maxdists: 计算最大距离
  • maxRstat: 计算特定统计量的最大值

4. 可视化工具

  • dendrogram: 绘制树状图
  • set_link_color_palette: 设置树状图链接颜色

5. 树结构表示

用于将层次结构表示为树对象的工具:

  • ClusterNode: 聚类节点类
  • leaves_list: 获取叶子节点列表
  • to_tree: 将链接矩阵转换为树对象
  • cut_tree: 在指定高度切割树
  • optimal_leaf_ordering: 优化叶子节点排序

关键算法详解

1. 单链接(Single Linkage)算法

单链接算法也称为最近邻算法,它定义两个簇之间的距离为两个簇中最近的两个点之间的距离。这种算法容易产生"链式效应",适合发现非椭圆形状的簇。

from scipy.cluster.hierarchy import single
Z = single(y)  # y是距离矩阵

2. 全链接(Complete Linkage)算法

全链接算法也称为最远邻算法,它定义两个簇之间的距离为两个簇中最远的两个点之间的距离。这种算法倾向于生成紧凑的、大小相近的簇。

from scipy.cluster.hierarchy import complete
Z = complete(y)

3. 平均链接(Average Linkage)算法

平均链接算法(UPGMA)计算两个簇中所有点对之间的平均距离。它是单链接和全链接的折中方案,平衡了前两者的特点。

from scipy.cluster.hierarchy import average
Z = average(y)

4. Ward方法

Ward方法是一种方差最小化方法,它在每一步合并使总簇内方差增加最小的两个簇。这种方法倾向于生成大小相近的簇,适合欧氏距离空间。

from scipy.cluster.hierarchy import ward
Z = ward(y)

实际应用示例

数据准备

from scipy.spatial.distance import pdist
import numpy as np

# 创建示例数据
X = np.array([[0, 0], [0, 1], [1, 0],
              [0, 4], [0, 3], [1, 4],
              [4, 0], [3, 0], [4, 1],
              [4, 4], [3, 4], [4, 3]])

# 计算距离矩阵
y = pdist(X)

执行聚类

from scipy.cluster.hierarchy import linkage, dendrogram
import matplotlib.pyplot as plt

# 使用ward方法进行层次聚类
Z = linkage(y, method='ward')

# 绘制树状图
plt.figure(figsize=(10, 5))
dendrogram(Z)
plt.show()

获取平面聚类

from scipy.cluster.hierarchy import fcluster

# 以距离阈值3切割树状图,获取平面聚类
clusters = fcluster(Z, t=3, criterion='distance')
print(clusters)

性能考虑

  1. 对于大型数据集,层次聚类可能会消耗较多内存,因为需要计算和存储O(n²)的距离矩阵。

  2. 不同的链接方法有不同的时间复杂度:

    • 单链接、全链接、平均链接:O(n³)
    • Ward方法:O(n² log n) (使用优先队列优化时)
  3. 对于非常大的数据集,可以考虑先使用其他聚类方法(如k-means)进行预聚类,再对聚类中心应用层次聚类。

总结

SciPy的scipy.cluster.hierarchy模块提供了完整的层次聚类实现,包含多种算法和丰富的辅助功能。通过合理选择链接方法和切割阈值,可以适应各种数据分布和应用场景。理解不同算法的特性和适用条件,是成功应用层次聚类的关键。