Python中KMeans聚类结果不符合预期,如何排查与修复?
问题排查与解决步骤
一、代码里的明显错误
- 你明确要聚成6个簇,但代码中
KMeans(n_clusters=5)把簇数设成了5,这是最直接的需求不符,先把这个参数改成n_clusters=6。 - 代码里先执行
model.fit(df1),接着又调用model.fit_predict(df1)——这会让模型重新训练一次,导致之前计算的centroids和最终的聚类结果不匹配。正确的做法是:要么先fit再用model.predict(df1)获取标签,要么直接用labels = model.fit_predict(df1),之后再从模型里取centroids = model.cluster_centers_。
二、KMeans特性导致的聚类偏差
KMeans的效果受几个关键因素影响,也是你反复出现错分的核心原因:
- 数据尺度不一致:如果
AudReg和AudIrreg两个特征的数值范围差异很大,KMeans会偏向数值大的特征进行聚类,结果自然不符合视觉上的簇分布。解决方法是先对数据做标准化处理:from sklearn.preprocessing import StandardScaler scaler = StandardScaler() df1_scaled = scaler.fit_transform(df1) # 用缩放后的数据训练模型 model = KMeans(n_clusters=6, init='k-means++', max_iter=1000, n_init='auto') labels = model.fit_predict(df1_scaled) # 把质心转回原始尺度用于可视化 centroids = scaler.inverse_transform(model.cluster_centers_) - 初始质心的随机性:即使用了
k-means++,KMeans还是可能因为初始质心的随机选择陷入局部最优。可以设置random_state固定初始值方便调试,或者用n_init='auto'(sklearn 1.2+版本支持)让模型自动多次运行,选择SSE最小的最优结果。 - 数据分布不匹配KMeans:如果你的数据簇不是凸形的(比如有嵌套、不规则形状的簇),KMeans的效果会很差。这种情况下可以换用更适合的算法:
- DBSCAN:适合基于密度的不规则簇,不需要预先指定簇数
- 层次聚类(AgglomerativeClustering):可通过树状图调整簇数,适配非凸簇
三、修正后的完整代码示例
import pandas as pd import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler # 提取目标特征 df1 = df[['AudReg','AudIrreg']] # 标准化数据消除尺度影响 scaler = StandardScaler() df1_scaled = scaler.fit_transform(df1) # 训练KMeans模型(指定6个簇,自动多次初始化取最优) model = KMeans(n_clusters=6, init='k-means++', max_iter=1000, n_init='auto', random_state=42) labels = model.fit_predict(df1_scaled) # 获取转回原始尺度的质心 centroids = scaler.inverse_transform(model.cluster_centers_) # 整理聚类结果用于可视化 df1_cluster = df1.copy() df1_cluster['Cluster'] = labels color = ['red','blue','yellow','orange','black','cyan'] df1_cluster['color'] = df1_cluster['Cluster'].map(lambda p: color[p]) # 绘制聚类图 plt.figure(figsize=(8,5)) plt.scatter(df1['AudReg'], df1['AudIrreg'], c=df1_cluster['color']) plt.scatter(centroids[:,0], centroids[:,1], c='green', s=100) plt.show()
内容的提问来源于stack exchange,提问作者Zhaleh
相关产品推荐
相关产品推荐

