2024 Datawhale 夏令营 第二期 从零入门机器学习竞赛

2024 Datawhale 夏令营 第二期 从零入门机器学习竞赛


#AI夏令营 #Datawhale
Datawhale第二期的“机器学习”方向是基于讯飞开放平台“电力需求预测挑战赛”开展的实践学习,本帖将记录一个AI小白在7天夏令营内外学习中所见所学所为,欢迎大家交流讨论。

TASK1

第一个任务就是根据Datawhale的给的文档跑通Baseline。在飞书上他们把每一步的步骤都列出来了,跟着做就好。

文档在这里 link1.

照着做完后就得到了自己的第一个分数。

图1

TASK2

第二个任务是使用进阶的机器学习模型lightgbm解决本次问题,以达到更好的预测效果。
一般的使用机器学习模型解决问题的主要步骤为探索性数据分析、数据预处理、提取特征、切分训练集与验证集、训练模型、预测结果。
官方文档link2.有讲的LightGBM等一些概念我不再赘述,我主要就第二次进阶的机器学习代码做注释
在此之前,我先讲一些准备工作:因为task1是在飞桨上跑的,感觉还挺好用,就沿用了。针对初学者,可以到飞桨的官方帮助文档link3.了解一下基本的使用方法,比如下载第三方库就是新建一个单元格如下图运行。
图二

代码和解释部分

# 首先就是导入一些七七八八的需要用到的库
import numpy as np
import pandas as pd
import lightgbm as lgb
import tqdm
import sys
import os
import gc
import argparse
import warnings
warnings.filterwarnings('ignore')
#以下几行和Datawhale文档有区别是因为lightgbm版本的原因,可以参考下这篇文章 
#https://blog.csdn.net/weixin_51723388/article/details/124578560
from lightgbm import log_evaluation, early_stopping
callbacks = [log_evaluation(period=100), early_stopping(stopping_rounds=30)]
from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error


# 读取训练集和测试集
train = pd.read_csv('./data/data283931/train.csv')
test = pd.read_csv('./data/data283931/test.csv')

# 合并训练数据和测试数据,并进行排序
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)
    model = lgb.train(lgb_params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix],   
                  categorical_feature=[], callbacks=callbacks)	#这里改了Datawhale文档的参数,版本问题

    # 验证集和测试集结果预测
    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学期的python,用得很少,忘得很快,比较熟悉的是C,会对着算法题写一堆的代码。但捡起python,我却有了不一样的感受,它在很多地方不用我们重复造轮子,挺好的(懒得写了()

贴出新的分数在这里插入图片描述

TASK3

最新给的代码是涉及深度学习的,直接放飞桨跑会报错,因为飞桨默认用paddlepaddle框架,而Datawhale给的baseline好像是tensorflow(存疑?)
因为之前水了都是在paddlepaddle(飞桨)上直接跑,这次得重新配置。
首先在比赛官网把数据集下下来
图4
解压然后拖到pycharm创建的一个项目里

图5
然后开始去anaconda powshell下第三方库,用pycharm运行,哪里报错就下什么
提醒一点,就是那个sklearn得下scikit-learn,代码不用改
最后贴上代码

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense, RepeatVector, TimeDistributed
from keras.optimizers import Adam

train = pd.read_csv('./数据集/train.csv')
test = pd.read_csv('./数据集/test.csv')


# 数据预处理
def preprocess_data(df, look_back=100):
    # 将数据按照id进行分组
    grouped = df.groupby('id')
    datasets = {}
    for id, group in grouped:
        datasets[id] = group.values

    # 准备训练数据集
    X, Y = [], []
    for id, data in datasets.items():
        for i in range(10, 15):  # 每个id构建5个序列
            a = data[i:(i + look_back), 3]
            a = np.append(a, np.array([0] * (100 - len(a))))
            X.append(a[::-1])
            Y.append(data[i - 10:i, 3][::-1])

    # 准备测试数据集
    OOT = []
    for id, data in datasets.items():
        a = data[:100, 3]
        a = np.append(a, np.array([0] * (100 - len(a))))
        OOT.append(a[::-1])

    return np.array(X, dtype=np.float64), np.array(Y, dtype=np.float64), np.array(OOT, dtype=np.float64)


# 定义模型
def build_model(look_back, n_features, n_output):
    model = Sequential()
    model.add(LSTM(50, input_shape=(look_back, n_features)))
    model.add(RepeatVector(n_output))
    model.add(LSTM(50, return_sequences=True))
    model.add(TimeDistributed(Dense(1)))
    model.compile(loss='mean_squared_error', optimizer=Adam(0.001))
    return model


# 构建和训练模型
look_back = 100  # 序列长度
n_features = 1  # 假设每个时间点只有一个特征
n_output = 10  # 预测未来10个时间单位的值

# 预处理数据
X, Y, OOT = preprocess_data(train, look_back=look_back)

# 构建模型
model = build_model(look_back, n_features, n_output)

# 训练模型
model.fit(X, Y, epochs=75, batch_size=64, verbose=1)

# 进行预测
predicted_values = model.predict(OOT)

print(predicted_values.shape)
print(OOT.shape)

# 由于最后一个维度是1,我们可以直接去掉它(使用 squeeze 方法或者索引)
predicted_values_squeezed = predicted_values.squeeze(axis=-1)  # 现在形状是 (5832, 10)

# 将每个 (10,) 数组展平成一个单独的数组,并将它们连接起来
flattened_predictions = predicted_values_squeezed.flatten()

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

咳咳,虽然用了新的深度学习的方法,但结果有些不如人意,调了好几次参数都没有好分数,可能是我最后写的展开不太合理(?)

图六

Epochs(训练轮次):
epochs决定了整个训练数据集将被遍历多少次。增加epochs可以提高模型的训练程度,但也可能导致过拟合。
如果模型在训练集上的表现持续提升,但在验证集上的表现开始下降,这可能是一个过拟合的信号,此时应减少epochs。
Batch Size(批大小):
batch_size决定了每次更新权重时使用的样本数量。较小的batch_size可以增加模型的训练速度和泛化能力,但也可能导致训练不稳定。
较大的batch_size可以减少训练过程中的噪声,但可能会消耗更多的内存,并可能导致模型泛化能力下降。

作为蒟蒻只会调这俩,就我试的这六次中,epochs=10,batch_size=64是最低的;epochs=75,batch_size=64是最高的。()()()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值