Task2:入门LightGBM,开始特征工程
-
进阶思路Q&A
- 解决该问题常见的几种思路 使用机器学习模型如LightGBM或XGBoost,或深度学习模型进行实践。LightGBM简化了数据预处理需求,特别适合于数值数据的标准化处理。
-
Task2版本教程的思路
- Task1使用了基于经验的模型(如均值预测)。Task2则采用机器学习模型,特别是LightGBM,它简化了数据预处理的步骤。
-
使用机器学习方法的主要步骤
- 探索性数据分析
- 数据预处理
- 提取特征
- 切分训练集与验证集
- 训练模型
- 预测结果
-
基础概念入门
- GBDT:Gradient Boosting Decision Tree,是一种常用的机器学习模型,通过迭代训练多个弱分类器(决策树)来构建强分类器。
- LightGBM:高效实现GBDT算法的框架,支持并行训练,具有快速训练速度、低内存消耗和高准确率。
-
特征工程
- 构建历史平移特征和窗口统计特征,前者捕捉历史信息,后者反映近期数据变化趋势。
- 实现代码包括数据合并、排序、历史平移和窗口统计特征的创建。
-
模型训练与测试集预测
- 使用LightGBM模型,构建训练集和验证集,严格遵循时序切分。
- 设置LightGBM参数并训练模型,预测验证集和测试集结果,评估模型性能。
代码概览
- 导入模块:numpy, pandas, lightgbm等。
- EDA:读取数据,基本数据展示和可视化。
- 特征工程:历史平移特征与窗口统计特征构建。
- 模型训练与预测:LightGBM模型参数设置,训练,预测并评估模型,保存预测结果。
导入模块
Python
1import numpy as np
2import pandas as pd
3import lightgbm as lgb
4from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error
5import matplotlib.pyplot as plt
探索性数据分析(EDA)
读取数据
Python
1train = pd.read_csv('./data/train.csv')
2test = pd.read_csv('./data/test.csv')
可视化分析
不同类型房屋平均电力消耗的柱状图
Python
1type_target_df = train.groupby('type')['target'].mean().reset_index()
2plt.figure(figsize=(8, 4))
3plt.bar(type_target_df['type'], type_target_df['target'], color=['blue', 'green'])
4plt.xlabel('Type')
5plt.ylabel('Average Target Value')
6plt.title('Bar Chart of Target by Type')
7plt.show()
单个房屋随时间变化的电力消耗折线图
Python
1specific_id_df = train[train['id'] == '00037f39cf']
2plt.figure(figsize=(10, 5))
3plt.plot(specific_id_df['dt'], specific_id_df['target'], marker='o', linestyle='-')
4plt.xlabel('DateTime')
5plt.ylabel('Target Value')
6plt.title("Line Chart of Target for ID '00037f39cf'")
7plt.show()
特征工程
Python
1# 合并训练数据和测试数据,并进行排序
2data = pd.concat([test, train], axis=0, ignore_index=True)
3data = data.sort_values(['id','dt'], ascending=False).reset_index(drop=True)
4
5# 历史平移特征
6for i in range(10,30):
7 data[f'last{i}_target'] = data.groupby(['id'])['target'].shift(i)
8
9# 窗口统计特征
10data['win3_mean_target'] = (data['last10_target'] + data['last11_target'] + data['last12_target']) / 3
11
12# 切分训练集和测试集
13train = data[data.target.notnull()].reset_index(drop=True)
14test = data[data.target.isnull()].reset_index(drop=True)
15
16# 确定输入特征
17train_cols = [f for f in data.columns if f not in ['id','target']]
模型训练与测试集预测
Python
1def time_model(lgb, train_df, test_df, cols):
2 # 训练集和验证集切分
3 trn_x, trn_y = train_df[train_df.dt>=31][cols], train_df[train_df.dt>=31]['target']
4 val_x, val_y = train_df[train_df.dt<=30][cols], train_df[train_df.dt<=30]['target']
5
6 # 构建模型输入数据
7 train_matrix = lgb.Dataset(trn_x, label=trn_y)
8 valid_matrix = lgb.Dataset(val_x, label=val_y)
9
10 # LightGBM参数
11 lgb_params = {
12 'boosting_type': 'gbdt',
13 'objective': 'regression',
14 'metric': 'mse',
15 'min_child_weight': 5,
16 'num_leaves': 2 ** 5,
17 'lambda_l2': 10,
18 'feature_fraction': 0.8,
19 'bagging_fraction': 0.8,
20 'bagging_freq': 4,
21 'learning_rate': 0.05,
22 'seed': 2024,
23 'nthread': 16,
24 'verbose': -1,
25 }
26
27 # 训练模型
28 model = lgb.train(lgb_params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix],
29 categorical_feature=[], verbose_eval=500, early_stopping_rounds=500)
30
31 # 验证集和测试集结果预测
32 val_pred = model.predict(val_x, num_iteration=model.best_iteration)
33 test_pred = model.predict(test_df[cols], num_iteration=model.best_iteration)
34
35 # 离线分数评估
36 score = mean_squared_error(val_pred, val_y)
37 print(score)
38
39 return val_pred, test_pred
40
41lgb_oof, lgb_test = time_model(lgb, train, test, train_cols)
42
43# 保存结果文件到本地
44test['target'] = lgb_test
45test[['id','dt','target']].to_csv('submit.csv', index=None)