Python案例 | LightGBM预测钢筋混凝土梁长期挠度

前言

LightGBM (Light Gradient Boosting Machine)是微软[1]于2017年首次发布的一种基于决策树的梯度增强方法,是另一种梯度增强方法。与其他boosting方法的关键区别在于它是基于叶子进行树的分裂,即它可以通过关键点位检测和停计算(其他boosting算法是基于深度或基于级别的)。但是它不支持字符串类型的数据,需要使用特殊算法拆分分类数据,因为必须输入整数值(例如索引)而不是列的字符串名称。

LightGBM可用于分类和回归问题,具体原理的解释可下载原文或在微信公众号、CSDN和B站等网站检索学习。

笔者认为,对于机器学习/深度学习算法理论的学习应配合具体案例代码。因此,本文将通过一个钢筋混凝土梁长期挠度预测实验数据集,使用python来展示LightGBM的回归建模效果。

1. 数据来源

本文所采用的钢筋混凝土梁长期挠度数据集来源于之前在世界各地进行的实验工作中收集的包含217个测试的数据集。详细的数据库由Espion[2]从29个不同的研究计划中总结和记录。

下表给出所使用数据的变量名称和统计描述
在这里插入图片描述
需要该数据集可关注公众号“UQLearner”,后台回复“Espion”获取。

数据收集不易,如果对您发表文章有用,还请引用文章:

Dan, W.; Yue, X.; Yu, M.; Li, T.; Zhang, J. Prediction and Global Sensitivity Analysis of Long-Term Deflections in Reinforced Concrete Flexural Structures Using Surrogate Models. Materials 2023, 16 (13), 4671. https://doi.org/10.3390/ma16134671.

2. Python代码实现

# 使用LightGBM预测钢筋混凝土梁长期挠度
# Edit by Yue
# 2024.8.11
###################### 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 lightgbm as lgb

###################### 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. 模型训练
# LightGBM模型参数
params_lgb = {
    'learning_rate': 0.02,       # 学习率,控制每一步的步长,用于防止过拟合。典型值范围:0.01 - 0.1
    'boosting_type': 'gbdt',     # 提升方法,这里使用梯度提升树(Gradient Boosting Decision Tree,简称GBDT)
    'objective': 'mse',          # 损失函数,这里使用均方误差(Mean Squared Error,简称MSE)
    'metric': 'rmse',            # 评估指标,这里使用均方根误差(Root Mean Squared Error,简称RMSE)
    'num_leaves': 127,           # 每棵树的叶子节点数量,控制模型复杂度。较大值可以提高模型复杂度但可能导致过拟合
    'verbose': -1,               # 控制 LightGBM 输出信息的详细程度,-1表示无输出,0表示最少输出,正数表示输出更多信息
    'seed': 42,                  # 随机种子,用于重现模型的结果
    'n_jobs': -1,                # 并行运算的线程数量,-1表示使用所有可用的CPU核心
    'feature_fraction': 0.8,     # 每棵树随机选择的特征比例,用于增加模型的泛化能力
    'bagging_fraction': 0.9,     # 每次迭代时随机选择的样本比例,用于增加模型的泛化能力
    'bagging_freq': 4            # 每隔多少次迭代进行一次bagging操作,用于增加模型的泛化能力
}
# 创建LightGBM回归模型
lgb_reg = lgb.LGBMRegressor(**params_lgb)
# 训练模型
lgb_reg.fit(X_train, y_train)

###################### 5. 模型评估 ######################
y_train_pred = lgb_reg.predict(X_train)  # 预测输出
y_test_pred = lgb_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='LightGBM')   # LightGBM与真实值的比较
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='LightGBM')          # LightGBM与真实值的比较
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 = lgb_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. 结果展示

在这里插入图片描述

从上图展示的结果来看,在相同的数据划分条件下预测钢筋混凝土梁长期挠度,在LightGBM的精度低于XGBoost。

参考文献

[1] Ke, G.; Meng, Q.; Finley, T.; Wang, T.; Chen, W.; Ma, W.; Ye, Q.; Liu, T.-Y. LightGBM: A Highly Efficient Gradient Boosting Decision Tree. In Proceedings of the 31st International Conference on Neural Information Processing Systems; NIPS’17; Curran Associates Inc.: Red Hook, NY, USA, 2017; pp 3149–3157.

[2] Espion B, Long term sustained loading tests on reinforced concrete beams. Bull Serv Génie Civil, 1988.

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值