前一篇笔记里面有赛题背景和相关介绍,这里不再贴出,补上赛题链接:
上一篇结束时在改进思路板块提到使用机器学习的线性回归模型,本次task也采用机器学习模型进行改进(使用机器学习方法一般主要需要从 获取数据&增强、特征提取和模型 三个方面下手。)
下面简单介绍一下机器学习的经典模型:
GBDT(Gradient Boosting Decision Tree)
GBDT (Gradient Boosting Decision Tree) 是一种集成学习方法,基于梯度提升算法(Gradient Boosting Algorithm)构建多个决策树。每棵树在之前树的基础上进行优化,从而逐步减少模型的误差。GBDT 在许多机器学习任务中,如回归、分类、排序等,具有广泛应用。
主要特点
- 迭代训练:每一棵新树的构建都是为了纠正之前所有树的误差。
- 加法模型:模型由多个弱学习器(一般是决策树)组成,每个学习器的输出加在一起。
- 梯度下降:通过梯度下降优化损失函数,确保每次迭代都朝着减少误差的方向前进。
算法步骤
- 初始化模型:使用一个简单的模型,如常数模型。
- 计算残差:对于每个样本,计算当前模型预测值与实际值的残差。
- 训练新树:使用残差作为新的目标变量,训练一棵新的决策树。
- 更新模型:将新树的输出乘以学习率后加到当前模型上,更新模型。
- 迭代上述步骤:重复计算残差、训练新树和更新模型,直到达到预定的树数量或误差收敛。
LightGBM(Light Gradient Boosting Machine)
LightGBM 是一个基于梯度提升框架的分布式高效实现。它是由微软开发的一种新的 GBDT 算法,专门针对大数据集和高维数据进行了优化。
主要特点
- 基于直方的决策树算法:通过将连续特征离散化成直方,减少了决策树生成过程中的计算量。
- 基于叶子的增长策略:与传统的基于层的增长策略不同,LightGBM 每次从当前叶子节点分裂损失最小的节点,提升了训练效率。
- 支持并行和分布式计算:可利用多线程和多机环境加速训练过程。
本次task的核心代码与解释
完整代码:
def time_model(lgb, train_df, test_df, cols):
# 训练集和验证集切分
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']
# 构建模型输入数据
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)
# 验证集和测试集结果预测
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
lgb_oof, lgb_test = time_model(lgb, train, test, train_cols)
# 保存结果文件到本地
test['target'] = lgb_test
test[['id','dt','target']].to_csv('submit.csv', index=None)
代码解释:
def time_model(lgb, train_df, test_df, cols):
# 训练集和验证集切分
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']
这部分代码将 train_df
数据按照 dt
列的值进行切分,dt
列值大于等于 31 的作为训练集,小于等于 30 的作为验证集。cols
是特征列的列表,'target'
列是目标变量。
# 构建模型输入数据
train_matrix = lgb.Dataset(trn_x, label=trn_y)
valid_matrix = lgb.Dataset(val_x, label=val_y)
这部分代码将切分后的训练集和验证集数据转换为 LightGBM 的数据集格式 lgb.Dataset
。
后面的参数定义:
boosting_type
: 提升类型,这里使用梯度提升决策树 (GBDT)。objective
: 目标函数,这里使用回归任务。metric
: 评估指标,这里使用均方误差 (MSE)。- 其他参数用于控制模型复杂度、正则化、学习率、种子、线程数等。
重要的训练模型!
# 训练模型
model = lgb.train(lgb_params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix],
categorical_feature=[], verbose_eval=500, early_stopping_rounds=500)
lgb_params
: 参数字典。train_matrix
: 训练数据。50000
: 最大迭代次数。valid_sets
: 验证数据集列表,用于早停和评估。categorical_feature
: 类别特征列表,这里为空。verbose_eval
: 每 500 次迭代打印一次日志。early_stopping_rounds
: 如果在 500 次迭代后验证集指标没有提升,停止训练。
再次强调:
通过特征工程挖掘特征可以很快的提升模型预测效果,这也是数据挖掘比赛中的主要优化方向,很多情况下会决定最终的成绩!!!!
附加说明:
task在前面数据处理部分使用了经典的三件套:numpy、pandas、matplotlib
此外,特征工程也有提及(在第一篇笔记改进思路中我也提到);
数据处理的三件套以及sklearn是机器学习必须掌握的基础,对此我进行了相关的学习,下面贴上学习的资源链接并附上自己的笔记:
Matplotlib 教程 | 菜鸟教程 (runoob.com)
自己的笔记(使用的是jupyter notebook形式,可能需要相关软件打开比如vscode,放在百度网盘):
链接:https://pan.baidu.com/s/1wpOh3Y3ukkpiaKHnahugsA?pwd=gqoz
提取码:gqoz
链接:https://pan.baidu.com/s/1Jgqtd60gQTOd9TCJdAKiWA?pwd=cyt4
提取码:cyt4