基于年龄和体重的K-Means聚类数据点不收敛到质心问题咨询
1 概念认知偏差
K-Means算法的收敛判定标准是迭代前后质心位置的变化量小于设定阈值,而非要求所有数据点聚集到质心位置。质心是所属簇内所有样本特征的均值,和簇内样本存在距离是正常情况。
2 代码逻辑错误(核心诱因)
你的代码存在多处变量未定义的问题,如果实际运行未报错,说明你调用的数据集和你预期的年龄、体重数据集不一致,直接导致聚类结果不符合预期:
- 构造DataFrame时使用的
age_array、weight_array未定义,你已声明的样本存储在age、weight两个列表中 - 标准化时传入的
df未定义,你构造的DataFrame变量名为df_main - 可视化时y轴标注为「身高」,与你实际使用的「体重」字段不匹配,会干扰结果判断
修正后的参考代码如下:
import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans import matplotlib.pyplot as plt age = [20,21,22,20,21,22,23,27,28,26,23,28,29,33,28,25,24,28,29,30,33,31,40,22,28,29,27,25,29,23] weight = [80,50,70,50,82,49,60,66,76,45,66,86,77,56,76,81,72,92,72,91,72,75,60,61,99,54,56,45,40,76] # 修正变量名错误 df_main = pd.DataFrame({'age':age,'weight':weight}) # 修正传入的DataFrame变量名错误 X_std = StandardScaler().fit_transform(df_main) # 增加random_state固定初始质心,保证结果可复现 km = KMeans(n_clusters=2, max_iter=100, random_state=42) km.fit(X_std) centroids = km.cluster_centers_ # 绘图 fig, ax = plt.subplots(figsize=(6, 6)) plt.scatter(X_std[km.labels_ == 0, 0], X_std[km.labels_ == 0, 1], c='green', label='cluster 1') plt.scatter(X_std[km.labels_ == 1, 0], X_std[km.labels_ == 1, 1], c='blue', label='cluster 2') plt.scatter(centroids[:, 0], centroids[:, 1], marker='*', s=150, c='red', label='centroid') plt.legend() plt.xlim([-2, 3]) plt.ylim([-2, 3]) plt.xlabel('年龄') # 修正y轴标注错误 plt.ylabel('体重') plt.title('聚类结果可视化', fontweight='bold') plt.show()
3 数据集本身特性
你使用的样本数据的年龄、体重分布本身聚类区分度较低,簇内样本离散度较高,因此质心和簇内样本的距离天然较大,看起来会出现样本未向质心聚集的观感。
你提供的聚类可视化效果如下:
内容的提问来源于stack exchange,提问作者user11387524
相关产品推荐
相关产品推荐

