训练XGB模型后如何反转TargetEncoder以获取可解释的特征重要性?
解决方法
首先修正你代码里的两处问题,即可直接生成具备可解释性的特征重要性图,TargetEncoder不需要做“反转编码”操作:
- 第一处:数据泄露问题,你先对全量数据集做编码再拆分训练测试集的操作会泄露测试集的标签信息,大幅高估模型效果,必须改为先拆分数据集,仅用训练集拟合编码器
- 第二处:原代码中
encoder.fit_transform(X,y)的返回值没有赋值,后续拆分的X还是原始字符串类型数据集,无法直接输入XGBoost训练
TargetEncoder对每个分类特征只会生成1列编码结果,且默认保留原始特征的列名,模型的feature_importances_顺序和输入特征的列顺序完全对应,直接用原始特征名映射即可。
修正后可运行完整代码
import numpy as np import category_encoders as ce from xgboost import XGBClassifier from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt # 第一步:先拆分训练集和测试集,彻底避免数据泄露 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y_closed) # 第二步:识别分类特征,仅用训练集拟合TargetEncoder cat_cols = X_train.select_dtypes(['object']).columns encoder = ce.TargetEncoder(cols=cat_cols) # 分别编码训练集和测试集 X_train_enc = encoder.fit_transform(X_train, y_train) X_test_enc = encoder.transform(X_test) # 训练XGB模型 model = XGBClassifier(use_label_encoder=False, eval_metric='logloss') model.fit(X_train_enc, y_train) # 绘制带原始特征名的特征重要性图 %matplotlib inline N_FEATURES = 10 importances = model.feature_importances_ # 直接取编码后数据集的列名(和原始特征名完全一致) feature_names = X_train_enc.columns # 取重要性最高的N个特征的索引 indices = np.argsort(importances)[-N_FEATURES:] plt.title('Feature Importances') plt.barh(range(len(indices)), importances[indices], align='center') # y轴替换为对应的原始特征名 plt.yticks(range(len(indices)), [feature_names[i] for i in indices]) plt.xlabel('Relative Importance') plt.tight_layout() plt.show()
如果你需要查看单个分类特征下不同原始类别对应的编码值,可以通过encoder.mapping属性查看对应映射关系。
内容的提问来源于stack exchange,提问作者Tara-S1983
相关产品推荐
相关产品推荐

