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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:10:40