hierarchical clustering如何设置限制 排除距离>5的元素参与计算
现有数据集
| # | c1 | c2 | c3 | c4 | c5 |
|---|---|---|---|---|---|
| r1 | 3 | 7 | 4 | 3 | 5 |
| r2 | 4 | 2 | 6 | 5 | 2 |
| r3 | 8 | 4 | 4 | 6 | 2 |
| r4 | 9 | 4 | 5 | 6 | 2 |
| r5 | 3 | 7 | 4 | 5 | 8 |
| r6 | 2 | 6 | 9 | 1 | 10 |
注:数据集中每行元素代表对应位置间的距离,例如r1与c2之间的距离为7km。
解决方案
要实现距离值大于5的元素不参与层次聚类计算,核心思路是对距离矩阵做阈值掩码处理,不需要修改聚类算法本身的源码,具体操作如下:
- 首先将原始数据整理为标准的n×n对称距离矩阵,n为参与聚类的总点位数量,保证矩阵中
dist[i][j]和dist[j][i]值相等,均为点位i和点位j的实际距离,对角线元素(点位到自身的距离)统一为0。 - 遍历距离矩阵所有元素,将所有值大于5的元素替换为正无穷
np.inf,对角线元素保留为0不做替换。 - 调用层次聚类接口时,指定距离参数为「预计算距离矩阵」模式,传入处理完成的矩阵即可。
这种处理的逻辑是:层次聚类合并簇的核心依据是簇间距离,当两个点/簇的连通路径上存在无穷大的距离值时,算法会判定二者不可连通,永远不会将其合并到同一个簇中,完全满足"距离大于5的配对不参与聚类"的要求。
代码示例(Python + Scipy)
import numpy as np from scipy.cluster.hierarchy import linkage, fcluster # 1. 构造完整对称距离矩阵,此处需根据你实际的点位对应关系补全所有值 # 示例仅为占位,你需要把r1-r6、c1-c5所有点位两两之间的距离补全为对称方阵 point_num = 11 # 总点位数量:r1-r6共6个,c1-c5共5个,合计11个 dist_matrix = np.zeros((point_num, point_num)) # 按表格里的已知值填充对应位置即可 # 2. 应用阈值规则:距离>5的替换为正无穷 dist_threshold = 5 dist_matrix[dist_matrix > dist_threshold] = np.inf np.fill_diagonal(dist_matrix, 0) # 确保自身距离为0 # 3. 执行层次聚类,指定metric为precomputed表示传入预计算距离矩阵 # method参数可根据需求替换为single/complete/ward等簇间距离计算方式 Z = linkage(dist_matrix, method='average', metric='precomputed') # 4. 获取聚类标签,按距离阈值切分簇 cluster_labels = fcluster(Z, t=dist_threshold, criterion='distance')
注意事项
- 不要直接删除距离大于5的矩阵元素,会破坏距离矩阵的方阵结构,导致算法输入维度不匹配报错。
- 如果某个点位和其他所有点位的距离都大于5,该点位会被单独划分为一个独立簇,不会和任何其他点位合并,符合规则预期。
- 处理距离矩阵时不要修改≤5的有效距离值,否则会导致聚类结果失真。
内容的提问来源于stack exchange,提问作者alireza
相关产品推荐
相关产品推荐

