用kmeans聚类需标准化数据、设n_init≥20、init='k-means++'、固定random_state;选k时结合肘部法、轮廓系数等多指标;避免k=1,大数据先抽样;收敛警告优先检查标准化和k值合理性。

怎么用 sklearn.cluster.KMeans 做基础聚类
直接调用 KMeans 本身不难,但结果不稳定、标签乱序、中心点漂移是高频问题。核心在于初始化和重复运行。
-
n_init=10是底线,别用默认的 10(旧版是 1,新版已改);设成20或50能明显减少局部最优陷阱 -
init='k-means++'必须显式写上,它比'random'更快收敛且质量高——不是默认值但应该当默认用 -
random_state一定要固定,否则每次跑结果不同,调试时根本没法比对 - 别直接拿
labels_当最终分类:同一簇在不同运行中可能被标成 0/1/2 或 2/0/1,需用cluster_centers_对齐语义
肘部法则画图总不明显?inertia_ 不是万能指标
inertia_(簇内平方和)下降变缓的位置常被当作“肘点”,但它对噪声敏感、对非球形簇失效,且 K 小的时候下降天然剧烈,容易误判。
- 别只画一条
inertia_曲线——叠加silhouette_score或calinski_harabasz_score,三者趋势一致才可信 - K 从 2 开始试,别从 1 开始(K=1 时
inertia_就是总方差,毫无参考价值) - 如果数据量 > 10k,先用
sample抽样(比如 30%),否则计算inertia_太慢,且大样本下曲线更平滑,“肘”更模糊 - 示例:
from sklearn.metrics import silhouette_score scores = [silhouette_score(X, KMeans(n_clusters=k, n_init=20, random_state=42).fit(X).labels_) for k in range(2, 11)]
为什么 KMeans 对数值范围敏感?必须做标准化
KMeans 算的是欧氏距离,某列单位是「万元」、另一列是「百分比」,前者数值大十倍,就等于在距离计算里占了十倍权重——结果完全被量纲绑架。
- 永远用
StandardScaler,别用MinMaxScaler:后者压缩到 [0,1] 会扭曲原始分布形态,尤其对长尾特征灾难性 - 标准化必须在训练集上
fit,再对训练/测试集统一transform;不能分别对全量数据标准化后切分,那会泄露信息 - 如果有类别型变量(如 one-hot 后的列),别跟连续变量混在一起标准化——one-hot 列本身就是 0/1,标准化反而破坏语义
遇到 ConvergenceWarning: Number of iterations has reached max_iter 怎么办
这不是报错,是算法提前放弃优化,意味着当前 max_iter 下没收敛,聚类中心还在晃,结果不可靠。
- 先检查是否漏了标准化——未标准化的数据极易导致迭代发散或极慢收敛
-
max_iter默认是 300,对多数中小数据够用;如果频繁触发警告,优先加到500或1000,而不是调小n_init - 如果加大
max_iter后仍警告,大概率是 K 设得太大,或数据本身不适合 K-Means(比如簇是环形、带状)——该换 DBSCAN 或高斯混合模型了 - 注意:
tol(收敛阈值)默认是1e-4,太小也会拖慢收敛;若数据噪声大,可放宽到1e-3
KMeans 实例的 cluster_centers_,而中心点坐标本身又得还原回原始量纲才能业务解读。漏掉任一环,结论就悬在半空。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











