【问题标题】:XGBoost plot_importance doesn't show feature namesXGBoost plot_importance 不显示特征名称
【发布时间】:2018-04-07 04:28:29
【问题描述】:

我正在将 XGBoost 与 Python 结合使用,并已使用在 DMatrix 数据上调用的 XGBoost train() 函数成功训练了一个模型。该矩阵是从 Pandas 数据框创建的,该数据框具有列的特征名称。

Xtrain, Xval, ytrain, yval = train_test_split(df[feature_names], y, \
                                    test_size=0.2, random_state=42)
dtrain = xgb.DMatrix(Xtrain, label=ytrain)

model = xgb.train(xgb_params, dtrain, num_boost_round=60, \
                  early_stopping_rounds=50, maximize=False, verbose_eval=10)

fig, ax = plt.subplots(1,1,figsize=(10,10))
xgb.plot_importance(model, max_num_features=5, ax=ax)

我现在想使用 xgboost.plot_importance() 函数查看特征重要性,但生成的图没有显示特征名称。相反,这些功能被列为f1f2f3 等,如下所示。

我认为问题在于我将原始 Pandas 数据框转换为 DMatrix。如何正确关联特征名称以便特征重要性图显示它们?

【问题讨论】:

    标签: python pandas machine-learning xgboost


    【解决方案1】:

    如果您使用 scikit-learn 包装器,则需要访问底层 XGBoost Booster 并在其上设置功能名称,而不是 scikit 模型,如下所示:

    model = joblib.load("your_saved.model")
    model.get_booster().feature_names = ["your", "feature", "name", "list"]
    xgboost.plot_importance(model.get_booster())
    

    【讨论】:

    • 好帮手
    • 这应该是答案
    【解决方案2】:

    您想在创建xgb.DMatrix 时使用feature_names 参数

    dtrain = xgb.DMatrix(Xtrain, label=ytrain, feature_names=feature_names)
    

    【讨论】:

      【解决方案3】:

      train_test_split 会将数据帧转换为不再包含列信息的 numpy 数组。

      您可以按照@piRSquared 的建议进行操作,并将这些功能作为参数传递给 DMatrix 构造函数。或者,您可以将 train_test_split 返回的 numpy 数组转换为 Dataframe,然后使用您的代码。

      Xtrain, Xval, ytrain, yval = train_test_split(df[feature_names], y, \
                                          test_size=0.2, random_state=42)
      
      # See below two lines
      X_train = pd.DataFrame(data=Xtrain, columns=feature_names)
      Xval = pd.DataFrame(data=Xval, columns=feature_names)
      
      dtrain = xgb.DMatrix(Xtrain, label=ytrain)
      

      【讨论】:

        【解决方案4】:

        使用 Scikit-Learn Wrapper 接口“XGBClassifier”,plot_importance 返回类“matplotlib Axes”。所以我们可以使用axes.set_yticklabels。

        plot_importance(model).set_yticklabels(['feature1','feature2'])

        【讨论】:

          【解决方案5】:

          我在玩 feature_names 时发现的另一种方法。在玩弄它的同时,我写了这篇文章,它适用于我目前正在运行的 XGBoost v0.80。

          ## Saving the model to disk
          model.save_model('foo.model')
          with open('foo_fnames.txt', 'w') as f:
              f.write('\n'.join(model.feature_names))
          
          ## Later, when you want to retrieve the model...
          model2 = xgb.Booster({"nthread": nThreads})
          model2.load_model("foo.model")
          
          with open("foo_fnames.txt", "r") as f:
              feature_names2 = f.read().split("\n")
          
          model2.feature_names = feature_names2
          model2.feature_types = None
          fig, ax = plt.subplots(1,1,figsize=(10,10))
          xgb.plot_importance(model2, max_num_features = 5, ax=ax)
          

          所以这是单独保存feature_names 并稍后将其添加回来。由于某种原因feature_types也需要初始化,即使值为None

          【讨论】:

            【解决方案6】:

            您应该在实例化 XGBoost 分类器时指定 feature_names:

            xgb = xgb.XGBClassifier(feature_names=feature_names)
            

            请注意,如果您将 xgb 分类器包装在对列执行任何选择(例如 VarianceThreshold)的 sklearn 管道中,则 xgb 分类器在尝试拟合或转换时将失败。

            【讨论】:

            • 我没有看到 'feature_names' 是 xgb.XGBClassifer() 的参数。这是一个错误吗?
            【解决方案7】:

            如果受过训练

            model = XGBClassifier(
                max_depth = 8, 
                learning_rate = 0.25, 
                n_estimators = 50, 
                objective = "binary:logistic",
                n_jobs = 4
            )
            
            # x, y are pandas DataFrame
            model.fit(train_data_x, train_data_y)
            

            您可以通过model.get_booster().get_fscore() 获取功能名称和功能重要性作为 python 字典

            【讨论】:

            • xgb.plot_importance() 也适用于使用 XGBClassifier :)
            • 你知道为什么我从 plot_importance 得到不同的结果作为 feature_importance 与 xgb 模型?
            【解决方案8】:

            您还可以在没有 DMatrix 的情况下使代码更简单。列名用作标签:

            from xgboost import XGBClassifier, plot_importance
            model = XGBClassifier()
            model.fit(Xtrain, ytrain)
            plot_importance(model)
            

            【讨论】:

              猜你喜欢
              • 2018-11-16
              • 2012-12-17
              • 2018-07-07
              • 1970-01-01
              • 2020-04-08
              • 1970-01-01
              • 2018-12-06
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多