通过DataWhale的ai夏令营,完成我的ML代码的日记以及对该部分自己的些许心得。
1.赛题解读
初赛任务:初赛提供了电炉17个温区的实际生产数据,分别是电炉上部17组加热棒设定温度T1-1~T1-17,电炉下部17组加热棒设定温度T2-1~T2-17,底部17组进气口的设定进气流量V1-V17,选手需要根据提供的数据样本构建模型,预测电炉上下部空间17个测温点的测量温度值。
学习记录:
(1)给出上下部的设定温度以及气流量,初赛中该两影响因素导致最终的实际温度不同,故需要我们对于实际温度进行预测。
(2)通过观察训练集与测试集发现,赛题训练集中给出了X与Y,测试集给出X需要预测Y,故可以考虑建立相关预测的数学公式。
(3)在处理这个问题时,我们主要考虑的是回归预测。一种常规的解决思路是运用机器学习技术,例如 LightGBM 或 XGBoost,或者借助深度学习方法进行实践。当我们选择自行搭建模型的路径时,我们将面临更为复杂的挑战,包括构建模型结构以及对数值数据进行标准化处理。
值得注意的是预测目标为34个,所以需要我们进行34次模型训练和预测。
复赛任务:电炉加热棒温度设定一段时间后,其设定温度才能在电炉内部空间中稳定,加热棒温度设定具有滞后性。同时,电炉内部空间温度稳定测量值与产品内部的稳定温度值之间也存在一定的关系。复赛任务分为两个子任务,首先在初赛的基础上,在考虑时滞性因素的数据下对电炉内部空间温度进行预测,其次对电炉内的上下层产品内部温度进行预测。针对第一个子任务,通过考虑了时滞性因素的上部加热棒设定温度、下部加热棒设定温度、进气流量3类数据预测上部空间测量温度、下部空间测量温度,然后通过预测得到的空间测量温度对产品内部温度进行预测。
复赛即为在初赛集基础上增加了变量(影响因素),需要大家重新寻找特征以及相关关系。
2.Baseline学习
2.1 下载lgb
# 更新lightGBM库&解压缩数据
!pip install -U lightgbm
!unzip data/data227148/data.zip
适合大规模的数据集,有较好的性能与训练预测速度。
2.2 导入相关库
# 导入所需的库
import pandas as pd # 读取和处理csv文件的数据
#用于处理数据的工具,常用于数据加载、数据清洗和数据预处理。
import lightgbm as lgb # 机器学习模型 LightGBM
#构建梯度提升树模型,是一种高效的机器学习算法。
from sklearn.metrics import mean_absolute_error # 评分 MAE 的计算函数
#从sklearn.metrics模块中导入评分函数
#平均绝对误差(MAE),是用于回归问题的一个评价指标。
from sklearn.model_selection import train_test_split # 拆分训练集与验证集工具
#用于将数据集拆分为训练集和验证集,以便进行模型训练和评估。
from tqdm import tqdm # 显示循环的进度条工具
#循环过程中显示进度条,方便查看代码执行进度。
sklearn.model_selection:对机器学习模型进行参数调优、数据集拆分、交叉验证和性能评估等任务。 train_test_split函数:将数据集划分为训练集和测试集,并且可以灵活地设置拆分比例和随机种子。
2.3 数据导入
train_dataset = pd.read_csv("./dataset_v1/train_v1.csv") # 原始训练数据。
valid_dataset = pd.read_csv("./dataset_v1/valid_v1.csv") # 原始训练数据。
test_dataset = pd.read_csv("./dataset_v1/test_v1.csv") # 原始测试数据
注意自己的路径!文件地址复制之后,‘\’单个斜杠换为‘\\’双斜杠
2.4 参数设置
# 模型参数设置
pred_labels = list(train_dataset.columns[-34:]) #训练数据集的最后34列是需要预测的目标变量。
train_set, valid_set = train_test_split(train_dataset, test_size=0.2) # 拆分数据集。
# 设定 LightGBM 训练参,查阅参数意义:https://lightgbm.readthedocs.io/en/latest/Parameters.html
lgb_params = {
'boosting_type': 'gbdt', #使用的提升方法,使用梯度提升决策树gbdt。
'objective': 'regression', #优化目标,这里设置为'regression',表示使用回归任务进行优化。
'metric': 'mae', #评估指标,使用MAE,表示使用平均绝对误差作为评估指标。
'min_child_weight': 5, #子节点中样本权重的最小和,用于控制过拟合。
'num_leaves': 2 ** 5, #每棵树上的叶子节点数,影响模型的复杂度。
'lambda_l2': 10, #L2正则化项的权重,用于控制模型的复杂度。
'feature_fraction': 0.8, #随机选择特征的比例,用于防止过拟合。
'bagging_fraction': 0.8, #随机选择数据的比例,用于防止过拟合。
'bagging_freq': 4, # 随机选择数据的频率,用于防止过拟合。
'learning_rate': 0.05, #学习率,控制每次迭代的步长。
'seed': 2023, #随机种子,用于产生随机性,保持结果的可重复性。
'nthread' : 16, #并行线程数,用于加速模型训练。
'verbose' : -1, #控制训练日志输出,-1表示禁用输出。
}
通过调参能够得到较好的成绩,通常可以用调参来使得成绩比baseline高。
2.5 特征提取
# 接收数据集DataFrame和可选参数pred_labels,返回处理后的DataFrame
data = data.copy() # 复制数据,避免后续影响原始数据。
data = data.drop(columns=["序号"]) # 去掉”序号“特征。
data["时间"] = pd.to_datetime(data["时间"]) # 将”时间“特征的文本内容转换为 Pandas 可处理的格式。
data["month"] = data["时间"].dt.month # 添加新特征“month”,代表”当前月份“。
data["day"] = data["时间"].dt.day # 添加新特征“day”,代表”当前日期“。
data["hour"] = data["时间"].dt.hour # 添加新特征“hour”,代表”当前小时“。
data["minute"] = data["时间"].dt.minute # 添加新特征“minute”,代表”当前分钟“。
data["weekofyear"] = data["时间"].dt.isocalendar().week.astype(int) # 添加新特征“weekofyear”,代表”当年第几周“,
# 并转换成 int整数类型,否则 LightGBM 无法处理。
data["dayofyear"] = data["时间"].dt.dayofyear # 添加新特征“dayofyear”,代表”当年第几日“。
data["dayofweek"] = data["时间"].dt.dayofweek # 添加新特征“dayofweek”,代表”当周第几日“。
data["is_weekend"] = data["时间"].dt.dayofweek // 6 # 添加新特征“is_weekend”,代表”是否是周末“,1 代表是周末,0 代表不是周末。
data = data.drop(columns=["时间"]) # LightGBM 无法处理这个特征,它已体现在其他特征中,故丢弃。
if pred_labels: # 如果提供了 pred_labels 参数,则执行该代码块。
data = data.drop(columns=[*pred_labels]) # 去掉所有待预测的标签。在模型训练时不使用这些标签。
return data # 返回最后处理的数据。
对于特征的选取也会导致成绩的涨幅,好的特征可以使得模型训练的更加出色!
2.6 训练输出
# 训练模型,参数依次为:导入模型设定参数、导入训练集、设定模型迭代次数(5000)、导入验证集、禁止输出日志
model = lgb.train(lgb_params, train_data, 5000, valid_sets=valid_data, callbacks=[no_info])
在baseline中除了特征的选取,个人认为这部分能够更改的只有模型的迭代次数,这也会决定了训练的速度与训练的效果。可以通过绘制出损失函数的图来寻找最优的迭代次数。
3. 未来的上分规划
通过baseline最高能够取得6.15+的成绩,但是我调整参数过后发现其他参数组合并没有对成绩提高多少。后来我们队伍的大神就给出了相关的思路:数据!!!
对滴,数据方面通过绘图与观察后发现有较大的改进方向,具体的等完成后再来续。
数据处理完后打算融合一波,结合其他模型,感觉还能有效果再上一波分。