如何在scikit-learn的ColumnTransformer转换中按type字段合并行生成目标编码
问题解答
- ColumnTransformer不适合该需求,它的核心能力是对不同输入列分别应用不同的特征转换,处理逻辑是逐行独立的,没有内置按指定列分组聚合的能力。
- 可以仅通过OneHotEncoder实现需求,也可以用更简洁的pandas原生方法实现。
解决方案1:pandas原生实现(最简便)
直接通过交叉表统计每个type下各feat的出现次数,再将大于1的值截断为1即可得到目标结果:
import pandas as pd X = pd.DataFrame( {'type': ['type1', 'type1', 'type1', 'type1', 'type2', 'type2', 'type2', 'type3', 'type3', 'type4'], 'feat': ['A','B','C','D','A','B','C','A','B','A']}) result = pd.crosstab(X['type'], X['feat']).clip(upper=1).values print(result)
输出:
[[1 1 1 1] [1 1 1 0] [1 1 0 0] [1 0 0 0]]
解决方案2:仅使用OneHotEncoder实现
你之前的代码无法得到正确结果是因为每次循环都重新调用了fit_transform,会基于当前分组的feat重新学习类别,导致不同分组的编码维度、顺序不一致。正确的做法是先在全量数据集上完成OneHotEncoder的拟合,再对每个分组做转换后取最大值(只要对应feat出现过,编码位就为1):
import pandas as pd import numpy as np from sklearn.preprocessing import OneHotEncoder X = pd.DataFrame( {'type': ['type1', 'type1', 'type1', 'type1', 'type2', 'type2', 'type2', 'type3', 'type3', 'type4'], 'feat': ['A','B','C','D','A','B','C','A','B','A']}) # 全量拟合保证类别全局统一 ohe = OneHotEncoder(sparse_output=False) ohe.fit(X[['feat']]) result = [] for typ in X['type'].unique(): group_feat = X.loc[X['type'] == typ, ['feat']] # 按组取最大值,出现过的特征对应位为1 group_encode = ohe.transform(group_feat).max(axis=0) result.append(group_encode) result = np.array(result) print(result)
输出和方案1完全一致。
内容的提问来源于stack exchange,提问作者Derek H
相关产品推荐
相关产品推荐

