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

How to get CORRECT feature importance plot in 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]

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_)

Pandas 数据帧

# 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)

问题

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

参考资料

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

根据经验,如果您不能使用外部包,我会选择 gain,因为它更能代表一个人感兴趣的内容(一个人通常对原始事件不感兴趣拆分特定功能,而不是这些拆分有多大帮助),请参阅此问题以获得很好的总结:https://datascience.stackexchange.com/q/12318/53060. If you can use other tools, shap 表现出非常好的行为,我会 always 选择它而不是构建-在 xgb 树测量中,除非计算时间受到强烈限制。

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

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

  • 使用built-in特征重要性(我更喜欢gain类型),
  • 使用 permutation-based 特征重要性
  • 使用 SHAP 值计算特征重要性

在我的 post 中,我为所有 3 种方法编写了代码示例。就个人而言,我使用 permutation-based 特征重要性。在我看来,built-in 特征重要性可以在对数据过度拟合后显示特征的重要性(这只是根据我的经验得出的意见)。 SHAP 解释很棒,但有时计算它们可能 time-consuming(并且您需要对数据进行下采样)。