基于item_id分组的多分类特征目标均值编码实现问题
问题分析与解决方案
你的代码只能处理单个分类特征,核心问题是:fit方法中每次循环都会覆盖mean、name变量,最终仅保留最后一个特征的统计结果;且transform方法未遍历所有特征,只会沿用最后一次循环的特征参数执行操作。
要实现多特征的分组目标均值编码,你需要用字典存储每个特征对应的统计结果,同时遵循特征工程类的规范:fit阶段仅计算并保存统计量,不修改输入数据;transform阶段用保存的统计量生成编码特征。
修改后的完整代码
from typing import List import pandas as pd class FeatureEngineeringCategoryToTargetMean: def __init__(self, features: List[str]): self.features = features # 字典存储每个特征对应的分组均值(键:特征名,值:分组后的均值Series) self.feature_mean_maps = {} def fit(self, X: pd.DataFrame, y=None) -> "FeatureEngineeringCategoryToTargetMean": # fit阶段仅计算统计量,不修改输入数据 for feature in self.features: # 按item_id+当前特征分组,计算target均值 mean_series = X["target"].groupby([X["item_id"], X[feature]]).mean() self.feature_mean_maps[feature] = mean_series return self def transform(self, X: pd.DataFrame) -> pd.DataFrame: X_transformed = X.copy() for feature in self.features: mean_series = self.feature_mean_maps[feature] new_col_name = f"{feature}_target_mean" # 将均值Series转为DataFrame,方便与原数据合并 mean_df = mean_series.reset_index(name=new_col_name) # 按item_id和特征列合并,填充均值 X_transformed = pd.merge( X_transformed, mean_df, on=["item_id", feature], how="left" ) return X_transformed
调用示例
# 初始化类,传入需要编码的特征列表 feature_engineering = FeatureEngineeringCategoryToTargetMean(features=['City', 'Class']) # 拟合数据,保存统计量 feature_engineering.fit(X=df) # 生成编码后的特征 data = feature_engineering.transform(X=df.copy()) # 查看结果 print(data)
输出结果会新增City_target_mean和Class_target_mean两列,每列的编码值都是对应item_id分组下的target均值。
关键修改说明
- 用
self.feature_mean_maps字典存储每个特征的分组均值,彻底解决变量覆盖问题 fit阶段不修改输入数据,避免数据污染,符合机器学习流程规范- 用
pd.merge替代循环loc赋值,代码更简洁,处理大数据量时效率更高 - 支持任意数量的分类特征,只需在初始化时传入特征列表即可
内容的提问来源于stack exchange,提问作者Randy Morrison
相关产品推荐
相关产品推荐

