Hierarchical-层次聚类
层次聚类(Hierarchical Clustering)是一类通过递归合并或递归拆分来构建簇层次结构的聚类方法。与 K-Means、GMM 等“先设定簇结构再优化”的方法不同,层次聚类会先生成完整的树状层次关系,然后再按照目标簇数或距离阈值进行切割,因此特别适合用于观察样本之…
Hierarchical-层次聚类
1. 方法概述
层次聚类(Hierarchical Clustering)是一类通过递归合并或递归拆分来构建簇层次结构的聚类方法。与 K-Means、GMM 等“先设定簇结构再优化”的方法不同,层次聚类会先生成完整的树状层次关系,然后再按照目标簇数或距离阈值进行切割,因此特别适合用于观察样本之间的逐步合并过程以及簇的层次结构。
本项目中的 Hierarchical-层次聚类 模块采用的是 SciPy 层次聚类路线:核心计算直接调用 scipy.cluster.hierarchy.linkage、fcluster、dendrogram 与 cophenet,不是 sklearn 的 AgglomerativeClustering 封装。程序支持:
ward、complete、average、single四种 linkage 方法;euclidean、cityblock、cosine、correlation、chebyshev五种距离度量;maxclust与distance两种切割准则;none、minmax、zscore三种预处理方式;- 输出联接矩阵、簇标签、簇中心、簇内平方和、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\)。项目支持 none、minmax、zscore 三种预处理方式。
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\),其中每一行记录一次合并操作,对应:
- 被合并的两个簇编号;
- 两簇合并时的距离;
- 合并后新簇包含的样本数。
项目支持两种簇切割方式。
若 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-层次聚类 的实际流程如下:
- 读取
.xlsx、.xls或.csv文件;CSV 会依次尝试utf-8-sig、utf-8、gbk编码。 - 上传阶段检查数据是否为空,且样本数至少为 2。
- 在“特征设置”页选择可选样本名称列
label_col,并勾选参与聚类的数值特征列。 - 程序检查所选特征列是否存在空值或非数值项;对常数列仅给出日志警告,但不会阻止计算。
- 按
normalize设置对特征矩阵进行预处理,得到 \(Z\)。 - 调用
scipy.cluster.hierarchy.linkage生成联接矩阵 \(L\);若linkage_method="ward",则距离度量自动改为euclidean。 - 按
criterion选择“按簇数”或“按距离阈值”方式,通过fcluster生成最终簇标签。 - 计算簇中心、反变换中心、簇内平方和、样本占比以及 Cophenetic 相关系数。
- 绘制树状图
dendrogram.png与聚类散点图cluster_scatter.png。 - 导出 Excel 文件
hierarchical_results.xlsx,并自动生成复现脚本repro_hierarchical_层次聚类.py。
5. 关键参数说明
5.1 linkage_method
联接方法,当前界面支持:
wardcompleteaveragesingle
默认值为 ward。其中 ward 最强调簇内紧凑性,single 更容易形成“链式连接”,complete 倾向于生成更紧凑的球状簇,average 介于两者之间。
5.2 metric
距离度量,当前界面支持:
euclideancityblockcosinecorrelationchebyshev
默认值为 euclidean。需要注意:当 linkage_method="ward" 时,项目会强制使用 euclidean,并在界面上禁用其他距离选择。
5.3 criterion
聚类准则,可选:
maxclust:按目标簇数切割;distance:按距离阈值切割。
界面中分别对应“按聚类数”和“按距离阈值”。
5.4 n_clusters
当 criterion="maxclust" 时生效,界面允许范围为 2 到 200,默认值为 3。该参数直接控制最终输出的簇数量上限。
5.5 distance_threshold
当 criterion="distance" 时生效,界面允许范围为 0.01 到 1000.0,默认值为 1.0。该值越小,通常得到的簇越多;该值越大,越容易把多个簇合并。
5.6 normalize
预处理方式与界面映射关系如下:
无→noneMin-Max→minmaxZ-Score→zscore
若不同特征量纲差异较大,建议优先尝试 minmax 或 zscore。
5.7 dendrogram_p
树状图叶子显示数量,界面允许范围为 5 到 200,默认值为 30。当样本数超过该值时,程序会使用 truncate_mode="lastp",仅展示最后 p 个合并节点,而不是完整树状图。
6. 评价指标与输出结果解释
程序导出的 Excel 文件固定命名为 hierarchical_results.xlsx。当前实现的结果目录通常形如:
results/Hierarchical-层次聚类分析结果_<时间戳>/
当前代码中的 RESULTS_DIR 直接指向模块目录下的 results/,并未像部分其他模块那样在打包环境中切换到用户主目录。当前实现会输出以下工作表:
Parameters:参数配置、特征列、标签列与输出文件路径。RawData:原始数据表。ProcessedData:预处理后的建模数据。Linkage:联接矩阵,每行记录一次簇合并过程。Labels:样本名称与最终簇标签。Centers:预处理空间中的簇中心。Centers_Original:反变换回原始尺度后的簇中心。ClusterSummary:簇样本数、簇内平方和与样本占比。Metrics:样本数、特征数、聚类数、Cophenetic 相关系数、linkage 方法、距离度量、聚类准则等。Charts:图表路径索引。
同时,结果目录下还会生成:
plots/dendrogram.pngplots/cluster_scatter.pngrepro_hierarchical_层次聚类.pyrepro_inputs/下的复现输入文件
从结果解释角度看:
Linkage是理解层次聚类过程的核心表,其中distance列表示对应合并发生时的距离高度。Labels中的簇标签从1开始编号,来自fcluster的输出。Centers用于解释预处理空间中的簇位置,Centers_Original用于解释原始指标尺度下的中心水平。ClusterSummary中的簇内平方和越小,说明该簇内部越紧凑;样本占比用于衡量各簇规模。Cophenetic相关系数越高,通常表示树状结构越能保留原始样本距离关系。dendrogram.png在样本较多时会截断展示最后p个合并节点,因此它是“压缩版树状图”,不是完整叶节点全展示。cluster_scatter.png仅使用处理后数据的前两维绘图;若只有一个特征,则程序绘制单轴散点图。- 结果页界面中的标签表只预览前 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. 实现说明与注意事项
- 层次聚类适合样本规模中等、需要观察簇层次结构和合并过程的场景。
- 当前实现要求样本数至少为 2,且所选特征列必须能够完整转为数值型。
- 与 GMM、HDBSCAN 等模块不同,本模块对常数列不会直接报错,而是仅记录日志警告;这意味着常数特征可以参与计算,但通常不会提供有效区分信息。
ward方法只能在欧氏距离下使用,当前项目已在代码层面强制处理;因此若论文选择ward,不应再宣称使用了cosine、correlation等其他距离。singlelinkage 容易出现链式效应,可能把原本相距较远的样本通过一串近邻连接为一个长链簇,解释结果时应特别注意。distance_threshold的切割结果往往对预处理方式敏感,因此若采用“按距离阈值”准则,论文中应明确说明是否先做了标准化或归一化。- 当前模块并未输出轮廓系数、Davies-Bouldin、Calinski-Harabasz 等经典聚类评价指标,而是更强调
Linkage结构、簇内平方和和 Cophenetic 相关系数。 - 当前散点图仅使用前两维处理后特征,不能完整代表高维空间中的真实层次结构。
- 复现脚本会完整记录本次参数组合,但若用户选择了包含常数列的特征集,复现结果中也会保留该设置,因此论文方法部分最好显式说明最终采用的有效特征列。
9. 论文写作建议
论文中建议把层次聚类结果写成“树状层次结构 + 切割结果”两部分:
- 先介绍 linkage 方法和距离度量;
- 再说明是按簇数切割还是按距离阈值切割;
- 最后报告切割后的簇规模与评价指标。
如果正文篇幅有限,建议把 Linkage 矩阵或树状图放在附录,把最终簇结果和 Cophenetic 相关系数放在正文。
10. 单篇终审补充
10.1 图题与表题对齐建议
当前 Hierarchical 模块的真实工作簿包含:
ParametersRawDataProcessedDataLinkageLabelsCentersCenters_OriginalClusterSummaryMetricsCharts
这套输出里,Linkage 是最能体现“层次聚类过程”的核心结果表,适合在论文中作为“层次合并矩阵”或“联接矩阵结果表”引用;ClusterSummary 和 Metrics 则更适合放在正文做最终分组结果与评价汇总。不要只保留最终标签而忽略 Linkage,否则会把层次聚类写得和普通划分类方法过于接近。
图文件位于结果目录 plots/ 子目录,当前实现真实输出:
dendrogram.pngcluster_scatter.png
因此图题建议分别写成“层次聚类树状图”“层次聚类最终分组散点图”。不要写成“聚类中心演化图”或“距离热力图”,因为当前程序并未导出这些图。
10.2 终审说明
这篇文档的关键,不是再解释一遍层次聚类的通用原理,而是把项目真实导出和论文表述对齐。当前实现同时导出 Centers 与 Centers_Original,这意味着正文解释簇中心时,应明确区分“预处理空间中心”和“原始量纲中心”,否则容易把标准化后的中心误写成原始业务指标值。
另外,当前 repro 脚本的新结果目录已经稳定采用 repro_inputs/... 相对路径,但旧结果目录中仍可见早期绝对路径脚本。因此文档中应以“当前新框架结果”为准写可复现性,同时避免笼统声称历史结果全部都已统一。
10.3 全量强化补充
本次全量强化绑定的真实结果目录为 具体的算法3/聚类与降维/Hierarchical-层次聚类/results/Hierarchical-层次聚类分析结果_20260329_171254。该目录内主工作簿为 hierarchical_results.xlsx,实际工作表为 Parameters、RawData、ProcessedData、Linkage、Labels、Centers、Centers_Original、ClusterSummary、Metrics、Charts。由此可见,当前单轮实物确实把联接矩阵 Linkage 与最终切割结果放在同一工作簿中,正文不应只引用最终 Labels 而忽略层次聚类过程表。
图件位于 plots/ 下,真实文件为 dendrogram.png 与 cluster_scatter.png。同一目录还包含 repro_hierarchical_层次聚类.py 与 repro_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 = 2、distance_threshold = 1.0、normalize = 'zscore'、dendrogram_p = 30。
因此 Hierarchical 当前的最佳证据应绑定这轮目录,而不是继续引用旧版增强目录或早期绝对路径脚本。对于论文方法与结果章节,完全可以直接以“树状图 + Linkage 工作表 + 切割结果表”的三段式来描述当前程序的真实输出结构。
11. 软件实现核查补充(2026-07)
- 当前主结果目录应写作
具体的算法3/聚类与降维/Hierarchical-层次聚类/results/Hierarchical-层次聚类分析结果_20260329_171254。 - 正文应围绕
Parameters、RawData、ProcessedData、Linkage、Labels、Centers、Centers_Original、ClusterSummary、Metrics、Charts来写。 - 图证应对应
dendrogram.png与cluster_scatter.png,并把树状合并过程和最终切割结果区分开。 - 复现脚本应按
repro_hierarchical_层次聚类.py + repro_inputs/window1_hierarchical_input.csv的口径说明。