如何在不重新训练模型的情况下在 XGBoost 特征重要性图中获取实际特征名称?

15 python dataframe xgboost

我在 Stackoverflow 上遇到了几个问题,其中大众面临的问题是他们在使用例如拟合/训练 XGBoost 模型之前对训练数据进行预处理,例如使用中心和比例等

`

scaler = MinMaxScaler(feature_range=(0, 1))
X = scaler.fit_transform(X)
my_model_name = XGBClassifier()
my_model_name.fit(X,Y)` 
Run Code Online (Sandbox Code Playgroud)

其中 X 和 Y 分别是训练数据和标签,缩放返回 2D NumPy 数组,从而丢失特征名称。

我已经训练了我的 XGBoost 模型,但使用了预处理数据(使用 MinMaxScaler 进行中心和缩放)。因此,我处于类似的情况,其中列名/功能名称丢失。因此,当我尝试使用 时plot_importance(my_model_name),它会导致特征重要性的图,但只有特征名称为 f0、f1、f2 等,而不是数据集中的实际特征名称,这一定是显而易见的。

SO 上的大多数答案都与以不丢失特征名称的方式训练模型有关(例如在数据框列上使用 pd.get_dummies。我有一个查询,即如何在使用时获取实际特征名称plot_importance(my_model_name),而无需重新训练模型?有没有办法将特征名称 f0、f1、f2 等从原始训练数据(未预处理,带有列名称)映射到生成的特征重要性图,以便将实际特征名称绘制在图表?在这方面的任何帮助都非常感谢。

Bin*_*ven 24

您可以通过以下方式获取功能名称:

model.get_booster().feature_names

  • 正如您在我的答案(甚至在问题中)中看到的那样,这不是正确的答案,因为当您将 numpy 数组传递给 fit 方法时,您会丢失原始特征名称。 (3认同)
  • 如果模型已保存然后使用 save_model 和 load_model 加载,则此方法不起作用。 (3认同)
  • 关于您的答案,您可以在答案中添加有关使用 DataFrame 而不是 NumPy 数组的注释,因为现在它不能回答问题,因为用户正在使用 NumPy 数组,因此使用“model.get_booster().feature_names”不起作用为了他。 (2认同)

Ner*_*xis 12

你是对的,当你将 NumPy 数组传递给 XGBoost 的 fit 方法时,你会丢失特征名称。在这种情况下,调用model.get_booster().feature_names没有用,因为返回的名称采用表单形式[f0, f1, ..., fn],并且这些名称也显示在方法的输出中plot_importance

但是应该有几种方法可以实现你想要的 - 假设你将原始特征名称存储在某个地方,例如,orig_feature_names = ['f1_name', 'f2_name', ..., 'fn_name']或者如果 X 是 pandas DataFrame 则直接存储orig_feature_names = X.columns

那么你应该能够:

  • 更改存储的特征名称 ( model.get_booster().feature_names = orig_feature_names),然后使用plot_importance应该已采用更新名称并将其显示在绘图上的方法
  • 或者由于此方法返回 matplotlib ax,您可以使用修改标签plot_importance(model).set_yticklabels(orig_feature_names)(但您必须设置功能的正确顺序)
  • 或者你可以model.feature_importances_自己将它与你原来的特征名称组合起来(即我们自己绘制它)
  • 同样,您也可以使用model.get_booster().get_score()方法并将其与您的功能名称结合起来
  • 或者您可以尝试使用xgboost学习 APIDMatrix,并在创建数据集(缩放后)期间指定您的特征名称train_data = xgb.DMatrix(X, label=Y, feature_names=orig_feature_names)(但我对这种训练方式没有太多经验,因为我通常使用Scikit-Learn API

编辑:

感谢@Noob Programmer(请参阅下面的评论),基于使用不同的特征重要性方法,可能会出现一些“不一致”。这些是最重要的:

  • xgboost.plot_importance使用“权重”作为默认重要性类型(参见plot_importance
  • model.get_booster().get_score()还使用“weight”作为默认值(参见get_score
  • model.feature_importances_取决于important_type参数 ( model.importance_type) 并且结果似乎被归一化为 1 的总和(请参阅此评论

有关此主题的更多信息,请参阅如何获取功能重要性