背景
在机器学习任务中,特征的重要性对于理解模型的决策过程以及模型的解释性至关重要,尤其是在树模型中,特征的重要性可以帮助识别哪些特征在模型中起到了更大的作用,从而为特征选择和模型优化提供指导,本篇文章将通过一个实际例子,展示如何使用LightGBM提取特征贡献度,并可视化其排序结果
LightGBM的优势
在大规模数据集上,LightGBM由于其高效的处理速度和较强的性能表现,逐渐成为了众多回归和分类任务的首选模型。相比传统的决策树模型,LightGBM在处理缺失值、提高并行计算效率以及处理大数据方面有显著的优势
特征贡献度是LightGBM的一大亮点,它能够告诉我们每个特征在模型中的贡献程度,进而帮助我们理解模型是如何进行预测的,通过特征贡献度,我们可以
- 识别重要特征: 哪些特征在预测结果中起到更关键的作用
- 减少过拟合: 剔除不重要的特征 ,减少模型的复杂度,从而提升模型的泛化能力
- 提高模型解释性: 理解模型背后的逻辑,让预测过程更加透明
代码实现
数据集及特征划分
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()
本文使用的示例数据集包含气象、环境和火灾数据,目标是预测某个区域的火灾损失面积(area),首先,需要进行数据的处理,将不必要的特征(如month、day)去除,并划分特征矩阵 X 和目标变量 y 最后进行训练集、测试集分割
LightGBM模型构建与参数调优
import lightgbm as lgb
from sklearn.model_selection import GridSearchCV
# LightGBM回归模型参数
params_lgb = {
'learning_rate': 0.02, # 学习率,控制每一步的步长,用于防止过拟合
'boosting_type': 'gbdt', # 提升方法,这里使用梯度提升决策树
'objective': 'regression', # 损失函数,这里使用回归任务
'num_leaves': 127, # 每棵树的叶子节点数量,控制模型复杂度
'verbosity': 1, # 控制 LightGBM 输出信息的详细程度
'seed': 42, # 随机种子,用于重现模型的结果
'n_jobs': -1, # 并行运算的线程数量,-1表示使用所有可用的CPU核心
'colsample_bytree': 0.6, # 每棵树随机选择的特征比例,用于增加模型的泛化能力
'subsample': 0.7, # 每次迭代时随机选择的样本比例,用于增加模型的泛化能力
'metric': 'rmse' # 评价指标,这里使用均方根误差(rmse)
}
# 初始化LightGBM回归模型
model_lgb = lgb.LGBMRegressor(**params_lgb)
# 定义参数网格,用于网格搜索
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_lgb,
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_lgb = grid_search.best_estimator_
为了获得更好的预测效果,使用网格搜索(GridSearchCV)进行超参数调优。使用5折交叉验证来确保模型的稳健性。以下是LightGBM回归模型的主要参数及其作用:
- learning_rate: 学习率,用于控制每次迭代的步长
- num_leaves: 每棵树的叶子节点数,数值越大,模型的复杂度越高
- colsample_bytree: 每棵树的随机特征选择比例,用于提升模型的泛化能力
对以下参数进行网格搜索优化,包括树的数量(n_estimators)、树的深度(max_depth)以及学习率(learning_rate),通过网格搜索,能够找到最优的参数组合,并基于这些参数重新训练模型
提取特征贡献度
# 获取LightGBM模型的特征贡献度(重要性)
feature_importances = best_model_lgb.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:}")
当模型训练完毕后,LightGBM能够直接输出每个特征的贡献度,特征贡献度反映了各特征对最终预测结果的影响,贡献度越高,说明该特征在模型决策过程中起到了更关键的作用,通过上述代码,可以获取并按降序排列各特征的重要性
值得注意的是,不同树模型在计算特征贡献度时采用的方法不同,因此数值尺度可能存在显著差异,然而,在大多数情况下,关注的是特征贡献度的相对排名,而非具体数值,接下来,将对这些特征贡献度进行可视化展示
特征贡献度可视化
# 绘制按重要性排序的特征贡献性柱状图
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()
从图中可以看出,temp(温度)、DMC(湿润度代码) 和 ISI(火灾初始蔓延指数) 是对火灾面积预测贡献最大的特征,表明这些气象和环境因素对火灾的影响最为显著,而 rain(降雨量) 对模型的贡献最小,说明在这个数据集中,降雨量对火灾面积的预测作用相对较小
往期推荐
不止 SHAP 力图:LIME 实现任意黑盒模型的单样本解释
微信号|deep_ML
欢迎添加作者微信进入Python、ChatGPT群
进群请备注Python或AI进入相关群
无需科学上网、同步官网所有功能、使用无限制
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考