前言
XGBoost(eXtreme Gradient Boosting)[1]是经过优化的分布式梯度提升库,旨在高效、灵活且可移植,是Boosting算法的其中一种,其思想是将许多弱分类器集成在一起,形成一个强分类器。它可以很好地解决工业界大规模数据的问题。
XGBoost可用于分类和回归问题,具体原理的解释可下载原文或在微信公众号、CSDN和B站等网站检索学习。
笔者认为,对于机器学习/深度学习算法理论的学习应配合具体案例代码。因此,本文将通过一个钢筋混凝土梁长期挠度预测实验数据集,使用python来展示XGBoost的回归建模效果。
1. 数据来源
本文所采用的钢筋混凝土梁长期挠度数据集来源于之前在世界各地进行的实验工作中收集的包含217个测试的数据集。详细的数据库由Espion[2]从29个不同的研究计划中总结和记录。
下表给出所使用数据的变量名称和统计描述
需要该数据集可关注公众号“UQLearn”,后台回复“Espion”获取。
2. Python代码实现
# 使用XGBoost预测钢筋混凝土梁长期挠度
# Edit by Yue
# 2024.8.7
###################### 1. 导入必要的第三方库库 ######################
import numpy as np
import matplotlib
matplotlib.use('TkAgg') # 用于指定matplotlib使用TkAgg后端进行图形渲染。TkAgg是matplotib的一个后端,它使用Tkinter库来创建图形窗口并显示图表。
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
import pandas as pd
import xgboost as xgb
###################### 2. 读取钢筋混凝土梁长期挠度数据 ######################
Data = pd.read_excel('Long-Term Deflection of Reinforced Concrete Beams_New.xlsx') # 读取钢筋混凝土梁长期挠度数据
print(Data.describe()) # 输出数据的统计信息,包括计数、平均值、标准差、最小值、最大值、中位数、25%的分位数和75%的分位数。
pd.set_option('display.max_columns', None) # 设置显示数据的所有列
print(Data) # 打印显示所有的列的数据
print(Data.head()) # 显示数据的前5行
###################### 3. 数据预处理 ######################
X = Data.drop(columns=['X2', 'Y']) # 删除输出列
features = X.columns # 将X每个变量的每个变量名提取出来,用于后续的特征重要性分析
X = preprocessing.scale(X) # 进行标准化处理
y = Data['Y'] # 模型输出为数据中的“Y”列
###################### 4. 数据集划分 ######################
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=50) # 划分训练集和测试集
# 4. 模型训练
# 初始化XGBoost模型初始参数,控制模型的学习速率、提升方法、损失函数等,这些参数后续也可用来优化XGBoost模型
params_xgb = {
'max_depth': 6, # 树的最大深度,控制模型的复杂度,防止过拟合
'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, # 每次迭代时随机选择的样本比例,用于增加模型的泛化能力
'reg_lambda': 1 # L2正则化项的权重,值越大,模型越简单,用于防止过拟合
}
# 创建XGBoost回归模型
xgb_reg = xgb.XGBRegressor(**params_xgb)
# 训练模型
xgb_reg.fit(X_train, y_train)
###################### 5. 模型评估 ######################
y_train_pred = xgb_reg.predict(X_train) # 预测输出
y_test_pred = xgb_reg.predict(X_test) # 预测输出
# 训练集均方根误差
RMSE_train = np.sqrt(mean_squared_error(y_train, y_train_pred))
print(f'训练集RMSE:{RMSE_train: .4f}') # 打印输出RMSE值
# 训练集决定系数R2
R2_train =r2_score(y_train, y_train_pred)
print(f'训练集R2:{R2_train: .4f}') # 打印输出R2值
# 测试集均方根误差
RMSE_test = np.sqrt(mean_squared_error(y_test, y_test_pred))
print(f'测试集RMSE:{RMSE_test: .4f}') # 打印输出RMSE值
# 测试集决定系数R2
R2_test =r2_score(y_test, y_test_pred)
print(f'测试集R2:{R2_test: .4f}') # 打印输出R2值
###################### 6. 可视化实际值与预测值的关系 ######################
plt.subplot(1, 3, 1)
plt.scatter(y_train, y_train_pred, alpha=0.3, label='XGBoost') # XGBoost与真实值的比较
plt.plot([y_train.min(), y_train.max()], [y_train.min(), y_train.max()], 'r--', lw=2, label='Best Line of Fit') # 最优拟合线
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title(f'Actual vs Predicted \nR2_train: {R2_train: .4f}')
plt.legend()
plt.subplot(1, 3, 2)
plt.scatter(y_test, y_test_pred, alpha=0.3, label='XGBoost') # XGBoost与真实值的比较
plt.plot([y_test_pred.min(), y_test_pred.max()], [y_test_pred.min(), y_test_pred.max()], 'r--', lw=2, label='Best Line of Fit') # 最优拟合线
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title(f'Actual vs Predicted \nR2_test: {R2_test: .4f}')
plt.legend()
###################### 7. 特征重要性分析 ######################
importance = xgb_reg.feature_importances_
# 可视化
plt.subplot(1, 3, 3)
plt.barh(features, importance)
plt.xlabel('Importance')
plt.ylabel('Features')
plt.title('Features Importance')
plt.tight_layout() # 自动调整图形的布局,确保元素如坐标轴标签、刻度和标题不会重叠
plt.show() # 显示图像
3. 结果展示
从上图展示的结果来看,XGBoost可用于钢筋混凝土梁长期挠度的预测。
参考文献
[1]: Chen T.Q., Guestrin C. XGBoost: A Scalable Tree Boosting System. In Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining. Association for Computing Machinery, New York, NY, USA. 2016, 785–794.
[2] Espion B (1988a) Long term sustained loading tests on reinforced concrete beams. Bull Serv Génie Civil