You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Scipy分离距离矩阵计算与聚类结果不一致问题排查

预计算距离矩阵后层次聚类结果不一致的解决方法

问题背景

我正在使用Python处理一个二进制DataFrame,其中存储了不同用户在不同时间点的0和1值。原本直接对DataFrame执行层次聚类的代码能得到正确结果:

metodo='average'
clusters = linkage(user_df, method=metodo, metric='hamming')

# 绘制树状图
plt.figure(figsize=(10, 7))
dendrogram(clusters, labels=user_df.index, leaf_rotation=90)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('User')
plt.ylabel('Distance')
plt.savefig(f'dendrogram_{metodo}_entero.png')
plt.show()

但尝试将距离矩阵计算与聚类操作分离后,结果和原方法不一致:

dist_matrix = pdist(user_df.values, metric='hamming')

# 转换为平方形式并转为DataFrame
dist_matrix_square = squareform(dist_matrix)
dist_df = pd.DataFrame(dist_matrix_square, index=user_df.index, columns=user_df.index)

clusters = linkage(dist_df, method=metodo)

想知道是否可以通过预计算距离矩阵进行聚类,以及正确的实现方式。

原因分析

问题出在linkage函数对输入的要求:当传入预计算的距离矩阵时,必须是pdist返回的压缩一维数组形式,而不是平方形式的方阵(或DataFrame)。

你手动转成方阵后传给linkage,函数会错误地将这个方阵当作样本特征矩阵处理(把每一行视为一个样本的特征向量),这和原方法的逻辑完全不同,因此得到的聚类结果自然不一致。而原方法直接传入DataFrame时,linkage内部会自动调用pdist生成压缩形式的距离矩阵,逻辑正确。

正确实现方式

预计算距离矩阵完全可行,但要直接将pdist返回的压缩数组传给linkage,无需转成方阵或DataFrame:

metodo='average'
# 预计算压缩形式的距离矩阵
dist_matrix = pdist(user_df.values, metric='hamming')
# 直接传入压缩距离矩阵执行聚类
clusters = linkage(dist_matrix, method=metodo)

# 绘制树状图(和原代码一致)
plt.figure(figsize=(10, 7))
dendrogram(clusters, labels=user_df.index, leaf_rotation=90)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('User')
plt.ylabel('Distance')
plt.savefig(f'dendrogram_{metodo}_entero.png')
plt.show()

如果后续需要使用平方形式的距离矩阵做其他分析,依然可以保留dist_df的生成,但聚类操作必须依赖pdist返回的压缩数组。

内容的提问来源于stack exchange,提问作者slow_learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:45:27