2024年Datawhale AI夏令营第二期-“机器学习”方向

#AI夏令营 #Datawhale #夏令营

笔记按照学习顺序进行整理

Task1: 跑通baseline

一、赛题介绍

1.背景

题目:训练时序预测模型助力电力需求预测

电力需求的准确预测对于电网的稳定运行、能源的有效管理以及可再生能源的整合至关重要。

2.赛题任务

给定多个房屋对应电力消耗历史N天的相关序列数据等信息,预测房屋对应电力的消耗。

3.赛题数据简介

赛题数据由训练集和测试集组成,为了保证比赛的公平性,将每日日期进行脱敏,用1-N进行标识。

即1为数据集最近一天,其中1-10为测试集数据。

数据集由字段id(房屋id)、 dt(日标识)、type(房屋类型)、target(实际电力消耗)组成。

二、数据展示

1.train.csv训练数据展示

2.test.csv测试数据展示

3.baseline运行结果(submit.csv)

第一次跑baseline,得分为373.89846

三、对代码的理解

(一)代码展示

import pandas as pd
import numpy as np

train = pd.read_csv('./data/data283931/train.csv')
test = pd.read_csv('./data/data283931/test.csv')

target_mean = train[train['dt']<=20].groupby(['id'])['target'].mean().reset_index()

test = test.merge(target_mean, on=['id'], how='left')

test[['id','dt','target']].to_csv('submit.csv', index=None)

(二)理解

1. 导入需要用到的相关库
# 导入 pandas 库,用于数据处理和分析
import pandas as pd
# 导入 numpy 库,用于科学计算和多维数组操作
import numpy as np
2. 读取训练集和测试集
# 使用 read_csv() 函数从文件中读取训练集数据,文件名为 'train.csv'
train = pd.read_csv('./data/data283931/train.csv')
# 使用 read_csv() 函数从文件中读取测试集数据,文件名为 'train.csv'
test = pd.read_csv('./data/data283931/test.csv')
3. 计算训练数据小于20单位时间内对应id的目标均值(原代码这步解释不太完善
target_mean = train[train['dt']<=20].groupby(['id'])['target'].mean().reset_index()

这一行代码执行以下操作:

  • 首先,筛选出训练数据中 dt 小于等于 20 的记录。

  • 然后,对这些记录按 id 进行分组。

  • 计算每个 id 对应的 target 列的均值。

  • 最后,将分组后的结果重置索引,生成一个新的数据框 target_mean,包含 id 和对应的 target 均值。

4. 将target_mean作为测试集结果进行合并
test = test.merge(target_mean, on=['id'], how='left')

这一行代码将 target_mean 数据框与 test 数据框合并:

  • 使用 id 列作为合并的键。

  • 使用 left 合并方式,即保留 test 数据框中的所有记录,并在匹配到 id 时合并 target_mean 中的 target 均值。

5. 保存结果文件到本地
test[['id','dt','target']].to_csv('submit.csv', index=None)

这一行代码将合并后的 test 数据框中的 iddttarget 列保存到名为 'submit.csv' 的文件中,不保存索引。

6.总结

这段baseline虽然有读取train.csv和test.csv文件,但是后面并没有对各个房屋对应电力的消耗进行预测和验证,只是简单的进行了均值处理,即:

  • 筛选出训练集数据中 dt 小于等于 20 的记录,计算每个 idtarget 均值。

  • 将计算得到的均值与测试集数据按 id 进行合并。

可以参照这个简单的格式,在3步对数据进行预测,后面加一步对预测结果的验证来评估模型的好坏,必要时可加入可视化帮助理解数据分布和训练测试情况,还可对数据进行预处理,排除异常数据、填补缺失数据等。

(三)代码修改测试

1.修改后的代码
# 1. 导入需要用到的相关库
# 导入 pandas 库,用于数据处理和分析
import pandas as pd
# 导入 numpy 库,用于科学计算和多维数组操作
import numpy as np

# 2. 读取训练集和测试集
# 使用 read_csv() 函数从文件中读取训练集数据,文件名为 'train.csv'
train = pd.read_csv('train.csv')
# 使用 read_csv() 函数从文件中读取测试集数据,文件名为 'test.csv'
test = pd.read_csv('test.csv')

# 3. 计算训练数据最近11-20单位时间内对应id的目标均值
# 筛选出 dt 在 11 到 20 之间的记录
filtered_train = train[(train['dt'] >= 11) & (train['dt'] <= 20)]
# 按 id 分组并计算 target 均值
target_mean = filtered_train.groupby(['id'])['target'].mean().reset_index()

# 4. 将target_mean作为测试集结果进行合并
test = test.merge(target_mean, on=['id'], how='left')

# 5. 保存结果文件到本地
test[['id','dt','target']].to_csv('submit.csv', index=None)

2.预测结果

3.评分

四、收获

熟悉了baseline的运行流程,熟悉了代码逻辑,为后面运行测试打下了基础。

Task2:入门lightgbm,开始特征工程

一、LightGBM和GBDT介绍

(一)LightGBM

1.原理概述

LightGBM基于梯度提升决策树(GBDT),它通过构建多个弱学习器(通常是决策树)来提升模型的性能。每棵树都是在前一棵树的基础上建立的,通过最小化残差(实际值与预测值的差异)来提高模型的精度。

2.特性
2.1 高效性
  • 快速训练:LightGBM使用基于直方图的方法来加速训练过程。它将连续特征离散化为直方图,并在离散化后的值上进行分裂,减少计算量。

  • 支持大规模数据:LightGBM在处理大规模数据时表现优异,尤其适用于高维数据集和大数据量场景。

2.2 准确性
  • Leaf-wise生长策略:与按层生长的策略不同,LightGBM采用按叶子生长的策略,每次选择叶子节点分裂,可以更好地降低损失,提高模型的准确性。

  • 支持多种损失函数:LightGBM支持多种损失函数,如均方误差(MSE)、交叉熵损失(Cross-Entropy Loss)等,适用于不同类型的任务。

2.3 灵活性
  • 支持类别特征:LightGBM可以直接处理类别特征,不需要预处理。

  • 多线程支持:LightGBM可以利用多核CPU进行并行计算,加速训练过程。

3.优缺点
3.1 优点
  • 高效的训练速度和内存使用。

  • 可以处理大规模数据和高维数据。

  • 支持并行和分布式训练。

  • 提供多种调优参数,灵活性高。

3.2 缺点
  • 对数据噪声较敏感,需要进行特征选择和预处理。

  • 参数调优复杂,需要较多经验。

4.代码示例
import lightgbm as lgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载数据集
data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2, random_state=42)

# 创建LightGBM数据集
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 设置参数
params = {
    'objective': 'multiclass',
    'num_class': 3,
    'metric': 'multi_logloss',
    'boosting_type': 'gbdt',
    'num_leaves': 31,
    'learning_rate': 0.05,
    'feature_fraction': 0.9
}

# 训练模型
gbm = lgb.train(params, train_data, num_boost_round=100, valid_sets=[test_data], early_stopping_rounds=10)

# 预测
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
y_pred_max = [list(x).index(max(x)) for x in y_pred]

# 计算准确率
accuracy = accuracy_score(y_test, y_pred_max)
print(f'Accuracy: {accuracy:.2f}')

(二)GBDT

GBDT梯度提升决策树(Gradient Boosting Decision Tree,简称GBDT)是本次测试使用到的模型,它是一种广泛使用的机器学习方法,特别适用于回归和分类任务。它结合了决策树模型和梯度提升算法的优势,能够在各种任务中提供高精度的预测。GBDT广泛应用于各种领域,如金融风险预测、广告点击率预测、推荐系统等。其高效性和灵活性使其成为解决复杂机器学习问题的强大工具。

二、数据可视化

(一)不同房屋类型对应的实际电力消耗

1.图像(使用柱状图)

2.代码
import matplotlib.pyplot as plt
# 不同type类型对应target的柱状图
type_target_df = train.groupby('type')['target'].mean().reset_index()
plt.figure(figsize=(8, 4))
plt.bar(type_target_df['type'], type_target_df['target'], color=['blue', 'green'])
plt.xlabel('Type')
plt.ylabel('Average Target Value')
plt.title('Bar Chart of Target by Type')
plt.show()

(二)某个房屋每天对应的实际电力消耗

本次可视化测试选取的是id为00037f39cf的房屋

1.图像(使用折线图)

2.代码
specific_id_df = train[train['id'] == '00037f39cf']
plt.figure(figsize=(10, 5))
plt.plot(specific_id_df['dt'], specific_id_df['target'], marker='o', linestyle='-')
plt.xlabel('DateTime')
plt.ylabel('Target Value')
plt.title("Line Chart of Target for ID '00037f39cf'")
plt.show()

三、特征工程

1.历史平移特征

通过历史平移获取上个阶段的信息;如下图所示,可以将d-1时间的信息给到d时间,d时间信息给到d+1时间,这样就实现了平移一个单位的特征构建。

2.窗口统计特征

窗口统计可以构建不同的窗口大小,然后基于窗口范围进统计均值、最大值、最小值、中位数、方差的信息,可以反映最近阶段数据的变化情况。如下图所示,可以将d时刻之前的三个时间单位的信息进行统计构建特征给我d时刻。

3.代码

# 合并训练数据和测试数据,并进行排序
data = pd.concat([test, train], axis=0, ignore_index=True)
data = data.sort_values(['id','dt'], ascending=False).reset_index(drop=True)

# 历史平移
for i in range(10,30):
    data[f'last{i}_target'] = data.groupby(['id'])['target'].shift(i)
    
# 窗口统计
data[f'win3_mean_target'] = (data['last10_target'] + data['last11_target'] + data['last12_target']) / 3

# 进行数据切分
train = data[data.target.notnull()].reset_index(drop=True)
test = data[data.target.isnull()].reset_index(drop=True)

# 确定输入特征
train_cols = [f for f in data.columns if f not in ['id','target']]

四、模型训练和测试代码理解

(一)代码

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)

(二)理解

1.lgb.train()

lgb_params:

  • 类型:字典

  • 含义:包含LightGBM模型的超参数设置。超参数决定了模型的具体行为和性能,例如学习率、最大深度等。常用参数包括:

    • 'objective':定义目标函数,例如'regression''binary''multiclass'等。

    • 'metric':定义评估指标,例如'rmse''logloss''error'等。

    • 'boosting_type':提升方法,例如'gbdt''dart''goss'等。

    • 'num_leaves':控制树的复杂度,叶子节点数。

    • 'learning_rate':学习率,控制每次更新的步长。

    • 'feature_fraction':每次分裂使用的特征比例。

train_matrix:

  • 类型:lgb.Dataset

  • 含义:训练数据集,包含特征和标签,已经转换为LightGBM的数据格式。通常使用lgb.Dataset来创建。

num_boost_round:

  • 类型:整数

  • 含义:训练的迭代次数(即树的数量)。在每一轮迭代中,模型都会训练一棵新的树并添加到现有的模型中。

valid_sets:

  • 类型:列表

  • 含义:包含验证数据集的列表,用于在训练过程中评估模型的性能。通常包含训练集和验证集,以便可以监控模型在训练数据和验证数据上的表现。

categorical_feature:

  • 类型:列表

  • 含义:指定哪些特征是类别特征。类别特征会被特殊处理,可以直接用于分裂而不需要编码。

verbose_eval:

  • 类型:整数或布尔值

  • 含义:控制训练过程中日志输出的频率。例如,设置为500表示每500次迭代输出一次训练和验证结果。如果设置为True,则每轮迭代都输出日志。

early_stopping_rounds:

  • 类型:整数

  • 含义:早停的轮数。如果在指定轮数内验证集的指标没有改善,训练将提前停止,避免过拟合。

2.lgb_params

boosting_type:

  • 类型:字符串

  • 含义:指定提升方法(boosting method)。

  • 选项:

    • 'gbdt'(梯度提升决策树):常用的提升方法。

    • 'rf'(随机森林):一种特殊的提升方法。

    • 'dart'(Dropouts meet Multiple Additive Regression Trees):改进的GBDT,添加了dropout。

    • 'goss'(Gradient-based One-Side Sampling):通过采样减少计算量。

objective:

  • 类型:字符串

  • 含义:指定目标函数。

  • 选项:

    • 'regression':回归任务。

    • 'binary':二分类任务。

    • 'multiclass':多分类任务。

metric:

  • 类型:字符串

  • 含义:指定评估指标。

  • 选项:

    • 'mse'(均方误差):回归任务中常用的评估指标。

    • 'rmse'(均方根误差):回归任务中常用的评估指标。

    • 'logloss':分类任务中的对数损失。

    • 'error':分类错误率。

min_child_weight:

  • 类型:整数

  • 含义:指定子节点中最小的样本权重和。用于控制过拟合。较大的值可以避免模型学习到局部的噪音。

num_leaves:

  • 类型:整数

  • 含义:每棵树的叶子节点数。值越大,模型的复杂度越高。计算量和内存消耗也会增加。

lambda_l2:

  • 类型:浮点数

  • 含义:L2正则化项的权重。用于控制模型的复杂度,防止过拟合。

feature_fraction:

  • 类型:浮点数

  • 含义:每次分裂时随机选择的特征比例。用于防止过拟合。值在0到1之间。

bagging_fraction:

  • 类型:浮点数

  • 含义:每次迭代时随机选择的样本比例。用于防止过拟合。值在0到1之间。

bagging_freq:

  • 类型:整数

  • 含义:bagging的频率,即每隔多少次迭代进行一次bagging。0表示禁用bagging。

learning_rate:

  • 类型:浮点数

  • 含义:学习率,控制每次更新的步长。较小的学习率通常需要更多的树(num_boost_round)。

seed:

  • 类型:整数

  • 含义:随机种子,确保实验的可重复性。

nthread:

  • 类型:整数

  • 含义:用于训练的线程数。指定为多线程可以加速训练过程。

verbose:

  • 类型:整数

  • 含义:控制日志输出的详细程度。-1表示不输出日志。

3.model.predict()

val_x(test_df[cols]):

  • 类型:numpy数组或pandas DataFrame

  • 含义:要进行预测的数据集。每一行代表一个样本,每一列代表一个特征。val_x即为验证集(或测试集)的特征矩阵。

num_iteration:

  • 类型:整数

  • 含义:指定使用多少次迭代训练的模型来进行预测。可以通过model.best_iteration来获得最佳迭代次数。

  • 默认值:如果未指定,使用全部迭代次数训练的模型进行预测。

4.mean_squared_error

用于计算均方误差

五、结果

(一)20000轮

1.训练和测试过程

开始训练:

结束训练:

当选取的训练轮次为20000轮,可以看到最后训练的损失还在一直下降,但是验证的损失趋于稳定甚至有上升的趋势,可以初步估计模型训练次数太多导致了过拟合。

2.结果

(二)8888轮

1.训练和测试过程

2.结果

(三)1888轮

1.训练和测试过程

2.结果

六、收获

本次task让我了解了LightGBM框架和GBDT模型,让我第一次感受到了LightGBM框架的便捷,可以直接传入参数对模型直接定义然后进行训练即可,不用重新搭建网络训练检验。还让我再次学习到了数据可视化的其他方法,让我更加直观的看到数据的分布,从而对数据有个大致的了解。对于特征工程,先前我并不了解时序预测的方法,本次学习让我更加深刻的了解了历史平移特征和窗口统计特征,收获颇多。训练数据时,我也感受到了微调模型的乐趣,逐步修改训练轮次,观察训练损失和验证损失等。

  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值