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

如何将SKLearn KMeans的cluster_centers_正确映射到原始DataFrame?

解决KMeans cluster_centers_与原始DataFrame列名不匹配的问题

我明白你碰到的麻烦了——预处理过程中调整了特征(删原列加二值化列),导致聚类用的特征顺序和原始DataFrame对不上,直接给cluster_centers_套原始列名自然会错位。下面给你一步步解决的办法,还有能避免下次踩坑的技巧:

第一步:先锁定聚类时用的真实特征列

你最后用来训练KMeans的那个DataFrame(就是做完标准化、二值化、删加列之后的),先把它的列名存下来,这才是和cluster_centers_对应的特征顺序:

# 假设这个处理后的DataFrame叫processed_df
cluster_feature_names = processed_df.columns.tolist()

然后先给聚类中心匹配正确的特征名:

import pandas as pd

# 先让聚类中心和处理后的特征列对应上
centers_df = pd.DataFrame(k_means.cluster_centers_, columns=cluster_feature_names)

第二步:映射回原始DataFrame的列

接下来要把这些聚类中心值对应回原始DataFrame的列,得根据你的预处理步骤拆分处理:

区分标准化列和二值化列处理

假设你是把原始的两列(比如colX、colY)换成了二值化列(比如colX_bin、colY_bin),剩下的列是标准化后的:

  1. 先拆分出标准化列和二值化列:
# 按你的二值化列命名规则来筛选,这里假设后缀是_bin
scaled_cols = [col for col in cluster_feature_names if not col.endswith('_bin')]
bin_cols = [col for col in cluster_feature_names if col.endswith('_bin')]
  1. 对标准化列做逆变换(注意要用处理后的特征顺序):
# 先把标准化列按MinMaxScaler拟合时的原始列顺序排序(保证逆变换的维度正确)
scaled_cols_sorted = [col for col in scaler.feature_names_in_ if col in scaled_cols]
scaled_centers = centers_df[scaled_cols_sorted]

# 执行逆变换
scaled_centers_inversed = scaler.inverse_transform(scaled_centers)
scaled_centers_inversed_df = pd.DataFrame(scaled_centers_inversed, columns=scaled_cols_sorted)
  1. 合并逆变换后的列和二值化列,再按原始DataFrame的列顺序排列:
# 合并两类列
merged_centers = pd.concat([scaled_centers_inversed_df, centers_df[bin_cols]], axis=1)

# 按原始DataFrame的列顺序重新整理,得到最终对应正确的聚类中心
final_centers = merged_centers[df.columns]

预防踩坑:用Pipeline封装预处理+聚类

下次别手动一步步改特征了,用SKLearn的Pipeline和ColumnTransformer把预处理和聚类封装在一起,它会自动跟踪特征顺序,根本不会出现列错位的问题:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler, Binarizer
from sklearn.compose import ColumnTransformer
from sklearn.cluster import KMeans

# 定义预处理:指定哪些列做标准化,哪些做二值化
preprocessor = ColumnTransformer(
    transformers=[
        ('scaler', MinMaxScaler(), ['feat1', 'feat4', 'feat5']),  # 替换成你要标准化的列
        ('binarizer', Binarizer(threshold=0.5), ['feat2', 'feat3'])  # 替换成你要二值化的列
    ])

# 把预处理和KMeans打包成Pipeline
pipeline = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('kmeans', KMeans(n_clusters=4))
])

# 直接用原始DataFrame训练
pipeline.fit(df)

# 获取处理后的特征名,和聚类中心对应
processed_feature_names = pipeline.named_steps['preprocessor'].get_feature_names_out()
centers_df = pd.DataFrame(pipeline.named_steps['kmeans'].cluster_centers_, columns=processed_feature_names)

# 要逆变换的话,直接从Pipeline里取对应的scaler
scaler = pipeline.named_steps['preprocessor'].named_transformers_['scaler']
# 提取标准化后的聚类中心列,去掉前缀
scaled_centers = centers_df.filter(regex='scaler__')
scaled_centers.columns = [col.replace('scaler__', '') for col in scaled_centers.columns]
# 逆变换
scaled_centers_inversed = scaler.inverse_transform(scaled_centers)
scaled_centers_inversed_df = pd.DataFrame(scaled_centers_inversed, columns=scaled_centers.columns)

# 提取二值化列,去掉前缀
bin_centers = centers_df.filter(regex='binarizer__')
bin_centers.columns = [col.replace('binarizer__', '') for col in bin_centers.columns]

# 合并后按原始列顺序排列
final_centers = pd.concat([scaled_centers_inversed_df, bin_centers], axis=1)[df.columns]

这样整个流程都被标准化管理,特征顺序不会乱,后续维护也方便。

内容的提问来源于stack exchange,提问作者Tomi Gelo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:38:37