正在加载中...

展开本页目录
算法教程Hierarchical-层次聚类

Hierarchical-层次聚类

No.119 · 在线教程

层次聚类(Hierarchical Clustering)是一类通过递归合并或递归拆分来构建簇层次结构的聚类方法。与 K-Means、GMM 等“先设定簇结构再优化”的方法不同,层次聚类会先生成完整的树状层次关系,然后再按照目标簇数或距离阈值进行切割,因此特别适合用于观察样本之…

Hierarchical-层次聚类

1. 方法概述

层次聚类(Hierarchical Clustering)是一类通过递归合并或递归拆分来构建簇层次结构的聚类方法。与 K-Means、GMM 等“先设定簇结构再优化”的方法不同,层次聚类会先生成完整的树状层次关系,然后再按照目标簇数或距离阈值进行切割,因此特别适合用于观察样本之间的逐步合并过程以及簇的层次结构。

本项目中的 Hierarchical-层次聚类 模块采用的是 SciPy 层次聚类路线:核心计算直接调用 scipy.cluster.hierarchy.linkagefclusterdendrogramcophenet,不是 sklearnAgglomerativeClustering 封装。程序支持:

  1. wardcompleteaveragesingle 四种 linkage 方法;
  2. euclideancityblockcosinecorrelationchebyshev 五种距离度量;
  3. maxclustdistance 两种切割准则;
  4. noneminmaxzscore 三种预处理方式;
  5. 输出联接矩阵、簇标签、簇中心、簇内平方和、Cophenetic 相关系数以及树状图。

设共有 \(n\) 个样本、\(p\) 个参与聚类的数值特征。对选定特征列构成原始特征矩阵

$$ X=(x_{ij})_{n\times p},\quad i=1,2,\ldots,n,\ j=1,2,\ldots,p \tag{1} $$

其中可选的 label_col 仅用于样本名称展示,不参与聚类计算;若未指定,则程序自动生成 样本1, 样本2, \ldots, 样本n 作为样本标识。

2. 问题定义与数据预处理

记第 \(i\) 个样本的特征向量为 \(x_i\in\mathbb{R}^p\)。项目支持 noneminmaxzscore 三种预处理方式。

2.1 Min-Max 归一化

normalize="minmax" 时,第 \(j\) 个特征按

$$ z_{ij}=\frac{x_{ij}-x_j^{\min}}{x_j^{\max}-x_j^{\min}} \tag{2} $$

变换到 \([0,1]\) 区间。若某列极差为 0,代码会把缩放因子置为 1。

2.2 Z-score 标准化

normalize="zscore" 时,第 \(j\) 个特征按

$$ z_{ij}=\frac{x_{ij}-\bar x_j}{s_j} \tag{3} $$

进行标准化,其中 \(\bar x_j\) 为均值,\(s_j\) 为总体标准差;若 \(s_j=0\),程序同样会以 1 代替。

normalize="none",则直接令 \(z_{ij}=x_{ij}\)。经预处理后得到层次聚类输入矩阵

$$ Z=(z_{ij})_{n\times p} \tag{4} $$

2.3 符号说明

符号 含义
\(n\) 样本数量
\(p\) 特征维数
\(z_i\) 第 \(i\) 个样本的预处理后特征向量
\(D(A,B)\) 簇 \(A\) 与簇 \(B\) 的 linkage 距离
\(L\) linkage 生成的联接矩阵
\(K\) 目标簇数
\(d_0\) 距离阈值 distance_threshold
\(y_i\) 第 \(i\) 个样本的最终簇标签
\(c_k\) 第 \(k\) 个簇的中心
\(\mathrm{SSE}_k\) 第 \(k\) 个簇的簇内平方和
\(r_{\text{coph}}\) Cophenetic 相关系数

3. 核心数学模型

3.1 四种 linkage 合并准则

层次聚类从每个样本各自成簇开始,逐步选择距离最近的两个簇进行合并。当前项目暴露四种 linkage 方法。

若采用 single,则两簇距离定义为最小样本间距离:

$$ D_{\text{single}}(A,B)=\min_{x_i\in A,\ x_j\in B} d(z_i,z_j) \tag{5} $$

若采用 complete,则两簇距离定义为最大样本间距离:

$$ D_{\text{complete}}(A,B)=\max_{x_i\in A,\ x_j\in B} d(z_i,z_j) \tag{6} $$

若采用 average,则两簇距离定义为所有跨簇样本距离的平均值:

$$ D_{\text{average}}(A,B)=\frac{1}{|A||B|}\sum_{x_i\in A}\sum_{x_j\in B} d(z_i,z_j) \tag{7} $$

若采用 ward,则合并两个簇时最小化簇内平方和的增量,可写为

$$ \Delta_{\text{ward}}(A,B)=\frac{|A||B|}{|A|+|B|}\left\|\bar z_A-\bar z_B\right\|_2^2 \tag{8} $$

其中 \(\bar z_A,\bar z_B\) 分别为簇 \(A,B\) 的均值向量。由于 Ward 方法基于欧氏空间中的方差分解,项目在 _fit_linkage() 中会强制把距离度量改为 euclidean,即便用户在界面上原本选择了其他度量。

3.2 联接矩阵与簇切割准则

scipy.cluster.hierarchy.linkage 会输出联接矩阵 \(L\),其中每一行记录一次合并操作,对应:

  1. 被合并的两个簇编号;
  2. 两簇合并时的距离;
  3. 合并后新簇包含的样本数。

项目支持两种簇切割方式。

criterion="maxclust",则按目标簇数 \(K\) 切割层次树:

$$ y_i=\operatorname{fcluster}(L,\ t=K,\ \text{criterion}=\texttt{"maxclust"}) \tag{9} $$

criterion="distance",则按距离阈值 \(d_0\) 切割层次树:

$$ y_i=\operatorname{fcluster}(L,\ t=d_0,\ \text{criterion}=\texttt{"distance"}) \tag{10} $$

前者适合已有明确簇数预期的场景,后者更适合依据树状图中的距离断层进行切割。

3.3 簇中心、簇内平方和与 Cophenetic 相关系数

项目在得到最终簇标签后,会基于预处理后的数据计算每个簇的均值中心。对第 \(k\) 个簇,有

$$ c_k=\frac{1}{n_k}\sum_{i:y_i=k} z_i \tag{11} $$

其中 \(n_k\) 为簇 \(k\) 的样本数。进一步,项目在 ClusterSummary 中输出每个簇的簇内平方和:

$$ \mathrm{SSE}_k=\sum_{i:y_i=k}\left\|z_i-c_k\right\|_2^2 \tag{12} $$

此外,若样本数大于 2,程序会用 scipy.cluster.hierarchy.cophenet 计算 Cophenetic 相关系数:

$$ r_{\text{coph}}=\operatorname{corr}\!\left(d_{ij},\ \hat d_{ij}\right) \tag{13} $$

其中 \(d_{ij}\) 为原始成对距离,\(\hat d_{ij}\) 为由树状图诱导的 cophenetic 距离。该值越接近 1,通常说明树状结构对原始距离关系的保持越好。

3.4 中心反变换

项目会同时输出预处理空间中的簇中心 Centers 和反变换回原始尺度的 Centers_Original

对 Min-Max 归一化,反变换公式为

$$ c_{kj}^{(\text{orig})}=c_{kj}^{(\text{norm})}\cdot (x_j^{\max}-x_j^{\min})+x_j^{\min} \tag{14} $$

对 Z-score 标准化,反变换公式为

$$ c_{kj}^{(\text{orig})}=c_{kj}^{(\text{norm})}\cdot s_j+\bar x_j \tag{15} $$

因此,论文中若要解释每个类在原始指标上的中心水平,应优先引用 Centers_Original

4. 算法流程

结合当前项目实现,Hierarchical-层次聚类 的实际流程如下:

  1. 读取 .xlsx.xls.csv 文件;CSV 会依次尝试 utf-8-sigutf-8gbk 编码。
  2. 上传阶段检查数据是否为空,且样本数至少为 2。
  3. 在“特征设置”页选择可选样本名称列 label_col,并勾选参与聚类的数值特征列。
  4. 程序检查所选特征列是否存在空值或非数值项;对常数列仅给出日志警告,但不会阻止计算。
  5. normalize 设置对特征矩阵进行预处理,得到 \(Z\)。
  6. 调用 scipy.cluster.hierarchy.linkage 生成联接矩阵 \(L\);若 linkage_method="ward",则距离度量自动改为 euclidean
  7. criterion 选择“按簇数”或“按距离阈值”方式,通过 fcluster 生成最终簇标签。
  8. 计算簇中心、反变换中心、簇内平方和、样本占比以及 Cophenetic 相关系数。
  9. 绘制树状图 dendrogram.png 与聚类散点图 cluster_scatter.png
  10. 导出 Excel 文件 hierarchical_results.xlsx,并自动生成复现脚本 repro_hierarchical_层次聚类.py

5. 关键参数说明

5.1 linkage_method

联接方法,当前界面支持:

  1. ward
  2. complete
  3. average
  4. single

默认值为 ward。其中 ward 最强调簇内紧凑性,single 更容易形成“链式连接”,complete 倾向于生成更紧凑的球状簇,average 介于两者之间。

5.2 metric

距离度量,当前界面支持:

  1. euclidean
  2. cityblock
  3. cosine
  4. correlation
  5. chebyshev

默认值为 euclidean。需要注意:当 linkage_method="ward" 时,项目会强制使用 euclidean,并在界面上禁用其他距离选择。

5.3 criterion

聚类准则,可选:

  1. maxclust:按目标簇数切割;
  2. distance:按距离阈值切割。

界面中分别对应“按聚类数”和“按距离阈值”。

5.4 n_clusters

criterion="maxclust" 时生效,界面允许范围为 2200,默认值为 3。该参数直接控制最终输出的簇数量上限。

5.5 distance_threshold

criterion="distance" 时生效,界面允许范围为 0.011000.0,默认值为 1.0。该值越小,通常得到的簇越多;该值越大,越容易把多个簇合并。

5.6 normalize

预处理方式与界面映射关系如下:

  • none
  • Min-Maxminmax
  • Z-Scorezscore

若不同特征量纲差异较大,建议优先尝试 minmaxzscore

5.7 dendrogram_p

树状图叶子显示数量,界面允许范围为 5200,默认值为 30。当样本数超过该值时,程序会使用 truncate_mode="lastp",仅展示最后 p 个合并节点,而不是完整树状图。

6. 评价指标与输出结果解释

程序导出的 Excel 文件固定命名为 hierarchical_results.xlsx。当前实现的结果目录通常形如:

results/Hierarchical-层次聚类分析结果_<时间戳>/

当前代码中的 RESULTS_DIR 直接指向模块目录下的 results/,并未像部分其他模块那样在打包环境中切换到用户主目录。当前实现会输出以下工作表:

  1. Parameters:参数配置、特征列、标签列与输出文件路径。
  2. RawData:原始数据表。
  3. ProcessedData:预处理后的建模数据。
  4. Linkage:联接矩阵,每行记录一次簇合并过程。
  5. Labels:样本名称与最终簇标签。
  6. Centers:预处理空间中的簇中心。
  7. Centers_Original:反变换回原始尺度后的簇中心。
  8. ClusterSummary:簇样本数、簇内平方和与样本占比。
  9. Metrics:样本数、特征数、聚类数、Cophenetic 相关系数、linkage 方法、距离度量、聚类准则等。
  10. Charts:图表路径索引。

同时,结果目录下还会生成:

  1. plots/dendrogram.png
  2. plots/cluster_scatter.png
  3. repro_hierarchical_层次聚类.py
  4. repro_inputs/ 下的复现输入文件

从结果解释角度看:

  1. Linkage 是理解层次聚类过程的核心表,其中 distance 列表示对应合并发生时的距离高度。
  2. Labels 中的簇标签从 1 开始编号,来自 fcluster 的输出。
  3. Centers 用于解释预处理空间中的簇位置,Centers_Original 用于解释原始指标尺度下的中心水平。
  4. ClusterSummary 中的 簇内平方和 越小,说明该簇内部越紧凑;样本占比 用于衡量各簇规模。
  5. Cophenetic相关系数 越高,通常表示树状结构越能保留原始样本距离关系。
  6. dendrogram.png 在样本较多时会截断展示最后 p 个合并节点,因此它是“压缩版树状图”,不是完整叶节点全展示。
  7. cluster_scatter.png 仅使用处理后数据的前两维绘图;若只有一个特征,则程序绘制单轴散点图。
  8. 结果页界面中的标签表只预览前 50 行,完整标签结果应以导出的 Excel 为准。

7. 论文写作模板

7.1 方法描述模板

可将当前项目实现表述为:

“本文采用层次聚类方法对样本进行分组分析。首先对所选数值型指标进行预处理,并基于样本间距离构造层次聚类树。随后采用 Ward、complete、average 或 single 等 linkage 方法递归合并样本簇,并根据预设簇数或距离阈值对树状结构进行切割,得到最终聚类结果。为评价层次树对原始距离关系的保持程度,进一步计算 Cophenetic 相关系数;同时输出各簇的中心、样本占比与簇内平方和,用于分析聚类结构的紧凑性与层次关系。”

若需要更贴近本项目工程实现,还可补充说明:本文实现直接调用 scipy.cluster.hierarchy 完成联接矩阵计算、树状图绘制和阈值切割,并同时输出预处理空间与原始尺度下的簇中心结果。

7.2 结果解释模板

结果部分可写为:层次聚类在给定 linkage 规则下形成树状层次结构,并通过设定簇数或距离阈值获得最终聚类方案。若 Cophenetic 相关系数较高,则说明树状结构较好保持了原始样本间距离关系;若不同 linkage 下结果差异较大,则应在正文中讨论距离与合并规则对分组稳定性的影响。

7.3 表格标题模板

表题可写为:层次聚类分组结果与 Cophenetic 相关系数汇总表。

7.4 图表题注模板

图注可写为:层次聚类树状图及最终簇划分结果。

7.5 表格示例

建议列名:簇编号、样本数、样本占比、簇中心、簇内平方和、Cophenetic 相关系数、linkage 方法。

8. 实现说明与注意事项

  1. 层次聚类适合样本规模中等、需要观察簇层次结构和合并过程的场景。
  2. 当前实现要求样本数至少为 2,且所选特征列必须能够完整转为数值型。
  3. 与 GMM、HDBSCAN 等模块不同,本模块对常数列不会直接报错,而是仅记录日志警告;这意味着常数特征可以参与计算,但通常不会提供有效区分信息。
  4. ward 方法只能在欧氏距离下使用,当前项目已在代码层面强制处理;因此若论文选择 ward,不应再宣称使用了 cosinecorrelation 等其他距离。
  5. single linkage 容易出现链式效应,可能把原本相距较远的样本通过一串近邻连接为一个长链簇,解释结果时应特别注意。
  6. distance_threshold 的切割结果往往对预处理方式敏感,因此若采用“按距离阈值”准则,论文中应明确说明是否先做了标准化或归一化。
  7. 当前模块并未输出轮廓系数、Davies-Bouldin、Calinski-Harabasz 等经典聚类评价指标,而是更强调 Linkage 结构、簇内平方和和 Cophenetic 相关系数。
  8. 当前散点图仅使用前两维处理后特征,不能完整代表高维空间中的真实层次结构。
  9. 复现脚本会完整记录本次参数组合,但若用户选择了包含常数列的特征集,复现结果中也会保留该设置,因此论文方法部分最好显式说明最终采用的有效特征列。

9. 论文写作建议

论文中建议把层次聚类结果写成“树状层次结构 + 切割结果”两部分:

  1. 先介绍 linkage 方法和距离度量;
  2. 再说明是按簇数切割还是按距离阈值切割;
  3. 最后报告切割后的簇规模与评价指标。

如果正文篇幅有限,建议把 Linkage 矩阵或树状图放在附录,把最终簇结果和 Cophenetic 相关系数放在正文。

10. 单篇终审补充

10.1 图题与表题对齐建议

当前 Hierarchical 模块的真实工作簿包含:

  • Parameters
  • RawData
  • ProcessedData
  • Linkage
  • Labels
  • Centers
  • Centers_Original
  • ClusterSummary
  • Metrics
  • Charts

这套输出里,Linkage 是最能体现“层次聚类过程”的核心结果表,适合在论文中作为“层次合并矩阵”或“联接矩阵结果表”引用;ClusterSummaryMetrics 则更适合放在正文做最终分组结果与评价汇总。不要只保留最终标签而忽略 Linkage,否则会把层次聚类写得和普通划分类方法过于接近。

图文件位于结果目录 plots/ 子目录,当前实现真实输出:

  • dendrogram.png
  • cluster_scatter.png

因此图题建议分别写成“层次聚类树状图”“层次聚类最终分组散点图”。不要写成“聚类中心演化图”或“距离热力图”,因为当前程序并未导出这些图。

10.2 终审说明

这篇文档的关键,不是再解释一遍层次聚类的通用原理,而是把项目真实导出和论文表述对齐。当前实现同时导出 CentersCenters_Original,这意味着正文解释簇中心时,应明确区分“预处理空间中心”和“原始量纲中心”,否则容易把标准化后的中心误写成原始业务指标值。

另外,当前 repro 脚本的新结果目录已经稳定采用 repro_inputs/... 相对路径,但旧结果目录中仍可见早期绝对路径脚本。因此文档中应以“当前新框架结果”为准写可复现性,同时避免笼统声称历史结果全部都已统一。

10.3 全量强化补充

本次全量强化绑定的真实结果目录为 具体的算法3/聚类与降维/Hierarchical-层次聚类/results/Hierarchical-层次聚类分析结果_20260329_171254。该目录内主工作簿为 hierarchical_results.xlsx,实际工作表为 ParametersRawDataProcessedDataLinkageLabelsCentersCenters_OriginalClusterSummaryMetricsCharts。由此可见,当前单轮实物确实把联接矩阵 Linkage 与最终切割结果放在同一工作簿中,正文不应只引用最终 Labels 而忽略层次聚类过程表。

图件位于 plots/ 下,真实文件为 dendrogram.pngcluster_scatter.png。同一目录还包含 repro_hierarchical_层次聚类.pyrepro_inputs/window1_hierarchical_input.csv。脚本当前真实参数写法为 INPUT_FILE = 'repro_inputs/window1_hierarchical_input.csv'OUTPUT_FILE = 'hierarchical_results.xlsx',并绑定 linkage_method = 'ward'metric = 'euclidean'criterion = 'maxclust'n_clusters = 2distance_threshold = 1.0normalize = 'zscore'dendrogram_p = 30

因此 Hierarchical 当前的最佳证据应绑定这轮目录,而不是继续引用旧版增强目录或早期绝对路径脚本。对于论文方法与结果章节,完全可以直接以“树状图 + Linkage 工作表 + 切割结果表”的三段式来描述当前程序的真实输出结构。

11. 软件实现核查补充(2026-07)

  • 当前主结果目录应写作 具体的算法3/聚类与降维/Hierarchical-层次聚类/results/Hierarchical-层次聚类分析结果_20260329_171254
  • 正文应围绕 ParametersRawDataProcessedDataLinkageLabelsCentersCenters_OriginalClusterSummaryMetricsCharts 来写。
  • 图证应对应 dendrogram.pngcluster_scatter.png,并把树状合并过程和最终切割结果区分开。
  • 复现脚本应按 repro_hierarchical_层次聚类.py + repro_inputs/window1_hierarchical_input.csv 的口径说明。