所有文章 > AI驱动 > 树模型系列:如何通过XGBoost提取特征贡献度

树模型系列:如何通过XGBoost提取特征贡献度

背景

在机器学习的众多模型中,树模型因其易于解释、可处理多种数据类型以及强大的泛化能力,广受数据科学家的青睐,而XGBoost作为树模型家族中的一员,以其高效的并行计算和良好的预测能力,成为了回归与分类任务中的首选之一

今天这篇文章,将带你深入了解如何通过XGBoost提取特征贡献度,帮助我们理解模型做出决策时,各个特征的重要性

什么是特征贡献度?

特征贡献度,是机器学习模型对每个输入特征的重要性评估,简单来说,它能告诉我们模型认为哪些特征对最终的预测结果起了关键作用。在特征众多的数据集里,合理利用特征贡献度可以帮助我们筛选最关键的特征,进而提升模型的效率和性能

为什么要使用XGBoost提取特征贡献度?

XGBoost是一种基于决策树的梯度提升算法,它在许多比赛和实际应用中表现优异。相比其他算法,XGBoost有以下几个优点:

  • 更强的泛化能力:XGBoost通过随机采样特征和样本的方式,减少了模型的过拟合风险
  • 高效的并行计算:利用硬件资源更好地加速训练过程
  • 自动计算特征贡献度:通过决策树的分裂点,我们可以轻松获得每个特征的重要性

具体步骤

  • 数据准备:我们使用一个气象、环境与火灾数据集来训练XGBoost模型,首先我们需要划分特征和目标变量,并进行训练集和测试集的划分
  • XGBoost模型初始化与参数设定:使用网格搜索(GridSearchCV)优化超参数,比如学习率、树的数量、最大深度等
  • 模型训练与评估:通过5折交叉验证,我们可以找到模型的最优参数,并根据负均方误差(RMSE)评估模型的性能
  • 特征贡献度提取:训练好的模型会自动提供每个特征的重要性值,按从高到低的顺序排列,我们可以绘制出特征贡献度的柱状图,以直观的方式展示模型对每个特征的看法

通过5折交叉验证找到模型的最优参数,并根据负均方误差(RMSE)评估模型性能,由于本文重点是特征贡献度的提取,我们不必过多关注模型的精确度。实际上,特征贡献度也可以用来帮助优化模型性能。在实际项目中,读者确保模型精度即可,特征贡献度的结果也可用于进一步提升模型表现

代码实现

数据读取并分割

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_excel('气象、环境、火灾烧毁.xlsx')

# 划分特征和目标变量
X = df.drop(['month', 'day', 'area'], axis=1)
y = df['area']
# 划分训练集和测试集
# 注意:random_state=42 是为了确保结果的可复现性,并且针对该数据集进行了特定处理。读者在使用自己的数据时,可以自由修改此参数。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=42)
df.head()

“这个数据集包含了气象、环境和火灾信息,其中X、Y表示地理位置,month和day是日期信息,FFMC、DMC、DC、ISI是火灾相关的气象指数,temp表示温度,RH是湿度,wind是风速,rain是降雨量,area是火灾烧毁的面积,在建模时,我们未使用日期信息(month 和 day)

模型建立

import xgboost as xgb
from sklearn.model_selection import GridSearchCV

# XGBoost回归模型参数
params_xgb = {
'learning_rate': 0.02, # 学习率,控制每一步的步长,用于防止过拟合。典型值范围:0.01 - 0.1
'booster': 'gbtree', # 提升方法,这里使用梯度提升树(Gradient Boosting Tree)
'objective': 'reg:squarederror', # 损失函数,这里使用平方误差,适用于回归任务
'max_leaves': 127, # 每棵树的叶子节点数量,控制模型复杂度
'verbosity': 1, # 控制 XGBoost 输出信息的详细程度,0表示无输出,1表示输出进度信息
'seed': 42, # 随机种子,用于重现模型的结果
'nthread': -1, # 并行运算的线程数量,-1表示使用所有可用的CPU核心
'colsample_bytree': 0.6, # 每棵树随机选择的特征比例,用于增加模型的泛化能力
'subsample': 0.7, # 每次迭代时随机选择的样本比例,用于增加模型的泛化能力
'eval_metric': 'rmse' # 评价指标,这里使用均方根误差(rmse)
}

# 初始化XGBoost回归模型
model_xgb = xgb.XGBRegressor(**params_xgb)

# 定义参数网格,用于网格搜索
param_grid = {
'n_estimators': [100, 200, 300, 400, 500], # 树的数量
'max_depth': [3, 4, 5, 6, 7], # 树的深度
'learning_rate': [0.01, 0.02, 0.05, 0.1], # 学习率
}

# 使用GridSearchCV进行网格搜索和k折交叉验证
grid_search = GridSearchCV(
estimator=model_xgb,
param_grid=param_grid,
scoring='neg_mean_squared_error', # 评价指标为负均方误差
cv=5, # 5折交叉验证
n_jobs=-1, # 并行计算
verbose=1 # 输出详细进度信息
)

# 训练模型
grid_search.fit(X_train, y_train)

# 输出最优参数
print("Best parameters found: ", grid_search.best_params_)
print("Best RMSE score: ", (-grid_search.best_score_) ** 0.5) # 还原RMSE

# 使用最优参数训练模型
best_model_xgboost = grid_search.best_estimator_

使用网格搜索(GridSearchCV)和5折交叉验证来优化XGBoost模型的超参数(如树的数量、深度、学习率等),然后输出最优参数和通过负均方误差评估得到的最小均方根误差(RMSE),最后使用最优参数训练模型

获取特征重要性

# 获取XGBoost模型的特征贡献度(重要性)
feature_importances = best_model_xgboost.feature_importances_

# 将特征和其重要性一起排序
sorted_indices = np.argsort(feature_importances)[::-1] # 逆序排列,重要性从高到低
sorted_features = X_train.columns[sorted_indices]
sorted_importances = feature_importances[sorted_indices]

# 打印排序后的特征及其重要性
for feature_name, importance in zip(sorted_features, sorted_importances):
print(f"Feature: {feature_name}, Importance: {importance:.4f}")

从训练好的XGBoost模型中提取特征的重要性,并将这些特征按重要性从高到低进行排序。首先,通过best_model_xgboost.feature_importances_ 获取各特征的贡献度,然后利用np.argsort() 对贡献度进行排序,接着将特征名称和对应的重要性值按顺序存储,最后,代码通过for循环打印出每个特征及其贡献度,帮助我们识别出模型中对预测结果影响最大的特征

特征重要性可视化

# 绘制按重要性排序的特征贡献性柱状图
plt.figure(figsize=(10, 6), dpi=1200)
plt.barh(sorted_features, sorted_importances, color='steelblue')
plt.xlabel('Importance', fontsize=14)
plt.ylabel('Features', fontsize=14)
plt.title('Sorted Feature Importance', fontsize=16)
plt.gca().invert_yaxis()
plt.savefig("Sorted Feature Importance.pdf", format='pdf',bbox_inches='tight')
# 显示图表
plt.show()

通过 plt.barh() 绘制了按重要性排序的特征贡献柱状图,并将其保存为 PDF 文件,该图展示了各个特征对 XGBoost 模型在预测火灾面积时的相对重要性

从图中可以看出,RH(相对湿度)、temp(温度) 和 DMC(湿润度代码) 是对火灾面积预测贡献最大的特征,表明这些环境因素对火灾的影响最为显著。而 rain(降雨量) 对模型的贡献最小,这意味着在这个数据集中,降雨量对火灾面积的预测起到的作用相对较小

总结

在之前的文章中,我们探讨了如何通过随机森林模型的特征贡献度来衡量各个特征在预测中的重要性,然而,特征贡献度不仅适用于随机森林,像 XGBoost、CatBoost和  LightGBM等强大的树模型同样可以为我们揭示特征对模型的贡献度,因此,我将推出一个系列文章,逐步讲解如何从这些不同的树模型中提取特征贡献度,让你学会在不同算法中挖掘最重要的特征

细心的读者可能已经注意到,XGBoost 的特征贡献度与随机森林有显著的区别,正是这些差异,让我们对特征有了不同的见解和理解,最终,我们的目标是通过多模型特征贡献度的可视化,帮助你直观地比较各个模型对同一特征的不同看法,最终可以将多种模型的特征贡献度整合在一张图中,轻松地对比每个模型对特征的不同判断,从而更好地理解模型的行为和特征的重要性

文章转自微信公众号@Python机器学习AI