GBDT与LightGBM
Gradient Boosting Decision Tree (GBDT) 是一种强大的机器学习技术,它通过构建多个决策树来预测结果。与随机森林不同,GBDT不是同时生成多棵树,而是顺序地添加树来逐步改进模型。每一棵新树都专注于纠正前一棵树的错误,这种逐步优化的方式使得GBDT在许多问题上表现出色。
LightGBM是微软开发的一个基于梯度提升框架的高效机器学习算法,它是GBDT的一种实现方式。LightGBM的特点在于其高效的训练速度和优秀的性能,这得益于它的特殊设计,比如基于直方图的决策树算法、Leaf-wise(而不是Level-wise)的增长策略、以及对连续数据的排序采样。此外,LightGBM支持并行学习,因为它将特征划分为多个bin,这样可以在不同的bin上并行计算,大大加快了训练过程。它也支持多种数据类型和缺失值的处理,使其成为实际应用中的一个强大工具。
代码详解
导入模块
这段代码主要导入了一系列用于数据分析和建模的Python库,下面是对导入部分的逐行分析:
1.import numpy as np: 导入NumPy库,这是一个基础的数值计算库,提供了高性能的多维数组对象以及用于处理这些数组的函数。
2.import pandas as pd: 导入Pandas库,这是一个强大的数据结构和数据分析工具,常用于数据处理和分析任务。
3.import lightgbm as lgb: 导入LightGBM,这是一个梯度提升框架,用于构建高效的机器学习模型。
4.from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error: 从scikit-learn库中导入几个常用的评估指标,用于衡量模型性能。mean_squared_log_error用于对数均方误差,mean_absolute_error用于绝对误差的均值,mean_squared_error用于平方误差的均值。
5.import tqdm: 导入tqdm库,这是一个进度条工具,可以让循环操作可视化进度,提高用户体验。
6.import sys: 导入系统模块,可以用来访问系统特定的属性和功能。
7.import os: 导入操作系统模块,用于执行各种与操作系统相关的任务。
8.import gc: 导入垃圾回收模块,用于手动控制内存管理。
9.import argparse: 导入argparse库,这是一个命令行参数解析器,允许用户解析命令行参数。
10.import warnings: 导入warnings模块,用于处理警告信息。
11.warnings.filterwarnings('ignore'): 设置警告过滤器,忽略所有警告信息。
整体来看,这段代码是为了准备进行电力消耗预测任务,使用了LightGBM作为模型,同时也准备了评估模型性能的指标和数据处理的工具。接下来的步骤可能包括读取数据、数据预处理、模型训练和评估等环节。
探索性数据分析
这里的代码展示了如何使用Pandas和Matplotlib进行数据分析和可视化。通过柱状图可以直观地看到不同房屋类型的平均电力消耗情况,而通过折线图可以观察特定房屋随时间的电力消耗趋势。这对于理解数据分布和可能存在的模式非常有帮助,有助于后续模型的选择和特征。
特征工程
模型训练与测试集预测
这段代码定义了一个函数time_model,用于训练LightGBM模型并对训练集和测试集进行预测。下面是对代码的逐行分析和建议:
1.划分训练集和验证集:
1.trn_x, trn_y = train_df[train_df.dt>=31][cols], train_df[train_df.dt>=31]['target']: 将训练集划分为至少31天的数据。
2.val_x, val_y = train_df[train_df.dt<=30][cols], train_df[train_df.dt<=30]['target']: 将验证集划分为最多30天的数据。
2.创建LightGBM数据集:
1.train_matrix = lgb.Dataset(trn_x, label=trn_y)
2.valid_matrix = lgb.Dataset(val_x, label=val_y)
3.LightGBM参数设置:
1.'boosting_type': 'gbdt': 使用梯度提升决策树。
2.'objective': 'regression': 因为目标是预测连续值,所以设置为回归问题。
3.'metric': 'mse': 使用均方误差作为评估指标。
4.'min_child_weight': 5: 控制树的深度和复杂度。
5.'num_leaves': 2 ** 5: 设置叶子节点的数量。
6.'lambda_l2': 10: 正则化项的系数。
7.'feature_fraction': 0.8, 'bagging_fraction': 0.8, 'bagging_freq': 4: 控制特征和样本的采样频率。
8.'learning_rate': 0.05: 学习率。
9.'seed': 2024: 设置随机种子以保证可重复性。
10.'nthread' : 16: 设置并行线程数。
11.'verbose' : -1: 设置日志输出频率。
4.训练模型:
1.model = lgb.train(lgb_params, train_matrix, 50000, ...): 使用指定参数训练模型。
2.early_stopping_rounds=500: 当验证集上的性能在500轮内没有改善时停止训练。
5.预测验证集和测试集:
1.val_pred = model.predict(val_x, num_iteration=model.best_iteration)
2.test_pred = model.predict(test_df[cols], num_iteration=model.best_iteration)
6.评估验证集性能:
1.score = mean_squared_error(val_pred, val_y)
7.输出结果:
1.lgb_oof, lgb_test = time_model(lgb, train, test, train_cols)
2.test['target'] = lgb_test
3.test[['id','dt','target']].to_csv('submit.csv', index=None)
改进建议:
1.特征选择: 在划分训练集和验证集之前,应确保已经完成了特征工程,包括必要的特征选择和特征构造。
2.交叉验证: 考虑使用交叉验证来更准确地评估模型性能。
3.学习率调整: 可以尝试使用学习率调度器来动态调整学习率。
4.超参数调优: 使用网格搜索或随机搜索来寻找最佳的超参数组合。
5.提前停止: 虽然已经设置了early_stopping_rounds,但也可以根据验证集的表现提前停止训练,避免过拟合。
6.特征重要性: 输出特征重要性,帮助理解哪些特征对模型贡献最大。
7.模型集成: 考虑使用模型集成方法来提高预测准确性。
修改后的代码:
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']
# 创建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)
# 获取特征重要性
feature_importance = model.feature_importance()
# 验证集和测试集结果预测
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_y, val_pred)
print(f'MSE on validation set: {score}')
return val_pred, test_pred, feature_importance
lgb_oof, lgb_test, importance = time_model(lgb, train, test, train_cols)
# 输出特征重要性
print('Feature Importance:', importance)
# 保存结果文件到本地
test['target'] = lgb_test
test[['id','dt','target']].to_csv('submit.csv', index=None)
在这个修改后的版本中,我增加了获取特征重要性的步骤,并在返回结果中包含它,同时,我打印出了验证集上的MSE,以便监控模型的性能。