如何在 XGBOOST 中获得正确的特征重要性图?

Pou*_*del 8 python xgboost

在 XGBOOST 特征重要性中使用两种不同的方法,给了我两个不同的最重要的特征,应该相信哪一个?

什么时候应该使用哪种方法?我很困惑。

设置

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline

import seaborn as sns
import xgboost as xgb

df = sns.load_dataset('mpg')
df = df.drop(['name','origin'],axis=1)

X = df.iloc[:,1:]
y = df.iloc[:,0]
Run Code Online (Sandbox Code Playgroud)

Numpy 数组

# fit the model
model_xgb_numpy = xgb.XGBRegressor(n_jobs=-1,objective='reg:squarederror')
model_xgb_numpy.fit(X.to_numpy(), y.to_numpy())

plt.bar(range(len(model_xgb_numpy.feature_importances_)), model_xgb_numpy.feature_importances_)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

熊猫数据框

# fit the model
model_xgb_pandas = xgb.XGBRegressor(n_jobs=-1,objective='reg:squarederror')
model_xgb_pandas.fit(X, y)
axsub = xgb.plot_importance(model_xgb_pandas)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

问题

Numpy 方法显示第 0 个特征柱面是最重要的。Pandas 方法显示型号年份最重要。哪一项是正确的最重要的特征?

参考

ppl*_*ski 7

有 3 种方法可以从 Xgboost 获取特征重要性:

  • 使用内置的特征重要性(我更喜欢gain类型),
  • 使用基于排列的特征重要性
  • 使用SHAP值来计算特征重要性

在我的文章中,我为所有 3 种方法编写了代码示例。就我个人而言,我使用基于排列的特征重要性。在我看来,内置的特征重要性可以在过度拟合数据后显示特征的重要性(这只是基于我的经验的意见)。SHAP 解释非常棒,但有时计算它们可能非常耗时(并且您需要对数据进行下采样)。


Myk*_*vyi 4

很难定义正确的特征重要性度量。每个都有优点和缺点。这是一个广泛的话题,目前还没有黄金法则,我个人建议阅读 Christoph Molnar 的这本在线书籍:https ://christophm.github.io/interpretable-ml-book/ 。这本书对不同的措施和不同的算法有很好的概述。

根据经验,如果您不能使用外部包,我会选择gain,因为它更能代表人们感兴趣的内容(人们通常对特定功能上分裂的原始发生不感兴趣,而是对分裂的数量感兴趣这些分割有帮助),请参阅此问题以获得很好的总结:https://datascience.stackexchange.com/q/12318/53060。如果您可以使用其他工具,shap表现出非常好的行为,我总是会选择它而不是内置的 xgb 树度量,除非计算时间受到强烈限制。

至于您在问题中直接指出的差异,差异的根源来自于xgb.plot_importance用作weight默认提取的特征重要性类型,而其XGBModel本身用作gain默认类型。如果您将它们配置为使用相同的重要性类型,那么您将获得类似的分布(最多在 中进行额外的归一化feature_importance_和排序plot_importance)。