我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文讨探xgboost的稍稍基础一些的内容:“特征重要性”。对应到数据集里面,就是特征特性features。对于任何一个模型的预测结果来说,它都是对这些特征进行各种分析得出的结论。这些特征都有一个重要性的说法。谁对结论的影响更大呢?是不是存在着一些影响不重要的特征?

苏南大叔:机器学习xgboost模型,特性重要性输出的依据是什么? - xgboost特征重要性输出
机器学习xgboost模型,特性重要性输出的依据是什么?(图6-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验文章。测试环境:python@3.12.3pandas@2.2.2numpy@1.26.4xlrd@2.0.1openpyxl@3.1.2scikit-learn@1.5.0xgboost@2.0.3

xgboost基模型

基础模型是基于树还是基于线性的,影响了特征重要性的输出依据。而xgboost的构造函数中,booster参数表示迭代的模型。它包括:

  • gbtree,基于树的模型。
  • gblinear,基于线性模型。
模型名基于参数booster.coef_.feature_importances_plot_importance()
gbtree树模型默认值不存在存在(越大越重要)存在(越大越重要)
gblinear线性模型非默认值存在(越小越重要)存在(越大越重要)存在(越大越重要)

使用上面的几种方法都可以得出特征重要性的排序结果。但是,可以看到,排序的结果并不一致。其中,

  • 默认的.feature_importances_属性和plot_importance(importance_type='gain')的结果是一致的。
  • .feature_importances_属性和.coef_属性,特性情况下,是可以同时存在的。但是,两者结论相反。

本文的结论就是上面这个表格,后续的文章内容就是对它进行的阐述和解释。

龙套代码

这里的龙套代码还是基于斯坦福大学的泰坦尼克数据集,使用xgboost模型进行预测。参考文章:

import pandas as pd
df = pd.read_csv("titanic.csv")
df = df.drop('Name', axis=1)
df = pd.get_dummies(df, columns=['Pclass', 'Sex'], drop_first=True)
target = df['Survived']
features = df.drop('Survived', axis=1)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_true = train_test_split(features, target, test_size=0.25, random_state=42)
import xgboost as xgb
model = xgb.XGBClassifier()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

注意里面的构造函数xgb.XGBClassifier(),它隐藏了一个参数booster='gbtree'

model = xgb.XGBClassifier()

特征重要性相关属性

xgboost使用的booster参数,它拥有两个属性取值,分别是:gbtreegblinear。在这两种情况下,重要性相关属性有着不同的表现:

默认值是gbtree,它仅仅拥有其中一个属性.feature_importances_

model = xgb.XGBClassifier(booster='gbtree')
# ...
print(model.feature_importances_)
print(model.coef_)                   # Coefficients are not defined for Booster type gbtree

xgboost使用的booster改成gblinear,它拥有两个属性.feature_importances_.coef_

model = xgb.XGBClassifier(booster='gblinear')
# ...
print(model.feature_importances_)
print(model.coef_)                    # 依然存在

参考文章:

特征重要性相关属性加工

无论是.feature_importances_还是.coef_,返回值仅是个list数组,并没有直观的表明对应的是哪一个字段。
对于属性.coef_来说,多数为负数。其数值越小越相关。和feature_importances_的结论完全相反。

所以需要点特殊的代码加工:

importance_ = pd.Series(model.feature_importances_, index=features.columns).sort_values()
# importance_ = importance_.sort_values(ascending=False)
print(importance_)
# model = xgb.XGBClassifier(booster='gblinear')
coef_ = pd.Series(model.coef_, index=features.columns).sort_values()
# coef_ = coef_.sort_values(ascending=False)
print(coef_)

输出:

Fare                      -0.000842
Age                        0.005639
Parents/Children Aboard    0.019782
Siblings/Spouses Aboard    0.064652
Pclass_2                   0.123056
Pclass_3                   0.320397
Sex_male                   0.467315
dtype: float32
Sex_male                  -2.795780
Pclass_3                  -1.916820
Pclass_2                  -0.736201
Siblings/Spouses Aboard   -0.386790
Parents/Children Aboard   -0.118348
Age                       -0.033738
Fare                       0.005039
dtype: float64

特征重要性相关属性画图

从画图结果上,可以继续验证相关结论。

import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]  # 显示中文
plt.rc('axes', unicode_minus=False)
importance_.plot.barh(figsize=(6, 3.5), fontsize=12)
# coef_.plot.barh(figsize=(6, 3.5), fontsize=12, rot=-45)
plt.tight_layout()
plt.show()

重点就是一句话:

# model = xgb.XGBClassifier(booster='gbtree')
# ...
importance_.plot.barh()

苏南大叔:机器学习xgboost模型,特性重要性输出的依据是什么? - importance
机器学习xgboost模型,特性重要性输出的依据是什么?(图6-2)

# model = xgb.XGBClassifier(booster='gbtree')
# ...
coef_.plot.barh()

苏南大叔:机器学习xgboost模型,特性重要性输出的依据是什么? - coef
机器学习xgboost模型,特性重要性输出的依据是什么?(图6-3)

plot_importance()

对于xgbooster来说,还可以直接画图。使用的核心代码是:

from xgboost import plot_importance
plot_importance(model,ax=ax,importance_type='gain')

这个函数的原型里面,参数很多。在本文中,就讨论它的importance_type这个参数,它表述的是重要性计算的规则。

测试代码

这个plot_importance()的画图结果是对标.feature_importances_的。然而,两者的默认结果有较大区别。其主要影响因素是importance_type参数。

# model = xgb.XGBClassifier(booster='gbtree')
# ...
from xgboost import plot_importance
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]        # 显示中文
plt.rc('axes', unicode_minus=False)
fig,ax = plt.subplots(figsize=(6.5,3.6))            # 纸张大小
plot_importance(model,ax=ax,importance_type='gain') # 必须写ax,否则画图奇怪输出
plt.show()

规则之'weight'【默认】

weight指的是特征在提升树里出现的次数。也就是在所有树中,某个特征作为分裂节点的次数。这个就是plot_importance()的默认值,得出的结论和importance_type差别较大。

plot_importance(model,ax=ax)

苏南大叔:机器学习xgboost模型,特性重要性输出的依据是什么? - weight
机器学习xgboost模型,特性重要性输出的依据是什么?(图6-4)

规则之'gain'【重点】

gain指的是在所有树中,某个特征在分裂后带来的平均信息增益。importance_type改成这个gain参数后,plot_importance()的画图结果,就能对标.feature_importances_属性了。

plot_importance(model,ax=ax,importance_type='gain')

苏南大叔:机器学习xgboost模型,特性重要性输出的依据是什么? - gain
机器学习xgboost模型,特性重要性输出的依据是什么?(图6-5)

规则之'cover'

cover指的是与特征相关的记录(observation)的相对数量,待议。
"cover" is the average coverage of splits which use the feature where coverage is defined as the number of samples affected by the split.

plot_importance(model,ax=ax,importance_type='cover')

苏南大叔:机器学习xgboost模型,特性重要性输出的依据是什么? - cover
机器学习xgboost模型,特性重要性输出的依据是什么?(图6-6)

参考文章

结束语

更多机器学习的文章总结,可以参考苏南大叔的文章。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python