如何在 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 方法显示型号年份是最重要的。哪个是最重要的正确特征?
参考资料
- How to get feature importance in xgboost?
很难定义正确的特征重要性度量。每个都有优点和缺点。这是一个广泛的话题,目前还没有黄金法则,我个人建议阅读 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(并且您需要对数据进行下采样)。
在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 方法显示型号年份是最重要的。哪个是最重要的正确特征?
参考资料
- How to get feature importance in xgboost?
很难定义正确的特征重要性度量。每个都有优点和缺点。这是一个广泛的话题,目前还没有黄金法则,我个人建议阅读 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(并且您需要对数据进行下采样)。