使用Scipy绘制Dendogram失败求助:单变量用户均值聚类问题
解决Scipy Dendogram的ValueError问题
你遇到的这个错误核心原因是:linkage()函数需要的是样本间的距离矩阵,而不是直接传入单个样本的数值列表。你现在的Y是每个用户的均值数据,属于单维的样本特征,不是两两用户之间的距离,所以不符合linkage的输入要求。
正确的解决步骤:
- 将单维特征转为二维数组:Scipy的距离计算函数要求每个样本作为一行,所以需要把
Y转换成形状为(7,1)的二维数组。 - 计算两两样本的距离矩阵:使用
scipy.spatial.distance.pdist()生成压缩形式的距离矩阵(也就是满足n = k*(k-1)/2的格式,这里k=7,n=21),这个格式正好是linkage()需要的输入。 - 执行聚类并绘制树状图:用生成的距离矩阵调用
linkage,再绘制树状图。
完整可运行代码:
import numpy as np from scipy.cluster.hierarchy import linkage, dendrogram import matplotlib.pyplot as plt # 你的原始数据 Y = [71.407452200146807, 0, 33.700136456196823, 1112.3757110973756, 31.594949722819372, 34.823881975554166, 28.36368420190157] X = ["user1", "user2", "user3", "user4", "user5", "user6", "user7"] # 步骤1:转为二维数组(每个用户是一个样本,特征为均值) Y_2d = np.array(Y).reshape(-1, 1) # 步骤2:计算两两样本的欧氏距离(压缩形式) from scipy.spatial.distance import pdist dist_matrix = pdist(Y_2d, metric='euclidean') # 你也可以换成其他距离,比如'manhattan' # 步骤3:执行聚类链接 Z = linkage(dist_matrix, method='ward') # method可选ward/complete/single等,根据需求选择 # 绘制树状图,替换叶节点为用户名 plt.figure(figsize=(10, 6)) dendrogram(Z, leaf_rotation=45., leaf_font_size=12., show_contracted=True, labels=X) plt.style.use("seaborn-whitegrid") plt.title("Dendogram to find clusters") plt.ylabel("Distance") plt.show()
额外说明:
- 关于距离度量:
pdist的metric参数可以选不同的距离计算方式,比如欧氏距离(默认)、曼哈顿距离、余弦距离等,根据你的数据特性选择。 - 关于聚类方法:
linkage的method参数决定了聚类的合并策略,比如ward是最小化类内方差,complete是用类间最大距离,你可以根据聚类目标调整。 - 之前你尝试的
np.concatenate(X,Y)是错误的,因为X是字符串标签,不需要和数值特征合并,只需要在dendrogram的labels参数里传入X即可替换叶节点显示。
内容的提问来源于stack exchange,提问作者Jannik
相关产品推荐
相关产品推荐

