本次Task使用进阶的机器学习模型lightgbm解决本次问题,以达到更好的预测效果。
基础概念入门
GBDT(Gradient Boosting Decision Tree)梯度提升决策树
GBDT,是一种基于决策树的集成学习算法,也是一种迭代式的boosting算法。基本原理是迭代地训练决策树,每次训练都基于之前训练结果来进行优化。训练过程基于梯度下降的思想,使用了加法模型和函数优化方法。
LightGBM(Light Gradient Boosting Machine)
LightGBM是一个基于GBDT的高效、可扩展的机器学习算法,作为GBDT框架的算法的一员,并且作为XGB算法的后来者,LGBM综合了包括XGB在内的此前GBDT算法框架内各算法的一系列优势,并在此基础上做了一系列更进一步的优化。
LightGBM代码
1.导入必要的库
import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error
import tqdm
import sys
import os
import gc
import argparse
import warnings
warnings.filterwarnings('ignore') # 忽略警告信息以保持输出整洁
2.读取和合并数据
# 从指定路径读取训练集和测试集数据文件。
train = pd.read_csv('./data/data283931/train.csv')
test = pd.read_csv('./data/data283931/test.csv')
# 将测试集和训练集按行合并成一个数据集 data
data = pd.concat([test, train], axis=0, ignore_index=True)
# 按 id 和 dt 列排序,确保时间序列数据的顺序正确。
data = data.sort_values(['id', 'dt'], ascending=False).reset_index(drop=True)
3.生成特征
# 生成滞后特征(last10_target 到 last29_target),这些特征是每个 id 下 target 列的前 10 到 29 个时间步的值
for i in range(10, 30):
data[f'last{i}_target'] = data.groupby(['id'])['target'].shift(i)
# 计算窗口为 3 的平均值特征 win3_mean_target,即 last10_target、last11_target 和 last12_target 的平均值
data[f'win3_mean_target'] = (data['last10_target'] + data['last11_target'] + data['last12_target']) / 3
4.划分训练集和测试集
# 将目标变量 target 非空的记录作为训练集,将 target 为空的记录作为测试集
train = data[data.target.notnull()].reset_index(drop=True)
test = data[data.target.isnull()].reset_index(drop=True)
# 确定训练中使用的特征列,排除 id 和 target 列
train_cols = [f for f in data.columns if f not in ['id', 'target']]
5.定义和训练模型
# 定义 time_model 函数,用于训练和验证 LightGBM 模型。
def time_model(lgb, train_df, test_df, cols, clf=None):
# 将训练集进一步划分为训练子集(dt >= 31)和验证子集(dt <= 30)。
trn_x, trn_y = train_df[train_df.dt >= 31][cols], train_df[train_df.dt >= 31]['target']
val_x, val_y = train_df[train_df.dt <= 30][cols], train_df[train_df.dt <= 30]['target']
# 设置 LightGBM 模型参数并训练模型,使用早停策略防止过拟合
train_matrix = lgb.Dataset(trn_x, label=trn_y)
valid_matrix = lgb.Dataset(val_x, label=val_y)
# lightgbm参数
lgb_params = {
'boosting_type': 'gbdt',
'objective': 'regression',
'metric': 'mse',
'min_child_weight': 5,
'num_leaves': 2 ** 5,
'lambda_l2': 10,
'feature_fraction': 0.8,
'bagging_fraction': 0.8,
'bagging_freq': 4,
'learning_rate': 0.05,
'seed': 2024,
'nthread': 16,
'verbose': -1,
}
# 训练模型
model = lgb.train(lgb_params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix], categorical_feature=[], verbose_eval=500, early_stopping_rounds=500)
# 预测验证集和测试集的目标值,并计算验证集的均方误差(MSE)
val_pred = model.predict(val_x, num_iteration=model.best_iteration)
test_pred = model.predict(test_df[cols], num_iteration=model.best_iteration)
# 离线分数评估
score = mean_squared_error(val_pred, val_y)
print(score)
return val_pred, test_pred
6.训练模型并生成提交文件
# 调用 time_model 函数进行训练和预测。
lgb_oof, lgb_test = time_model(lgb, train, test, train_cols)
# 将预测结果填入测试集的 target 列
test['target'] = lgb_test
# 将包含 id、dt 和预测 target 的结果保存到 submit.csv 文件中
test[['id', 'dt', 'target']].to_csv('submit.csv', index=None)
关键点
1.读取并合并数据。
2.生成滞后特征。
3.划分训练集和测试集。
4.定义并训练 LightGBM 模型。
5.进行预测并保存结果。
实践中产生的问题
运行时报错:
发现是缺少lightgbm模块,去终端里安装:
再次运行仍然报错:
不同版本的lightgbm有不同的参数命名或功能增减,lightgbm的更新会增加新的功能和参数。
最新版本的train()函数没有verbose_eval参数,因此报错。
卸载最新版本的lightgbm:
根据文档,安装3.3.0版本的lightgbm,并重启BML内核:
运行成功:
去官网提交:
总结
相比基于经验模型的baseline,机器学习模型lightgbm可以达到更好的预测效果。
通过特征工程挖掘特征可以很快的提升模型预测效果,这是数据挖掘比赛中的主要优化方向。