锂离子电池生产参数调控及生产温度项目学习

本文记录了一次数据挖掘比赛的实战经历,涉及工业场景中电炉温度预测问题。作者使用Pandas进行数据预处理,LightGBM进行模型训练,scikit-learn进行评估,通过时间序列特征工程提升模型性能。尽管当前模型精度不高,但作者期望通过实践持续提升。
摘要由CSDN通过智能技术生成

项目笔记打卡Day1

———前情提要:本次比赛为数据挖掘类型的比赛,聚焦于工业场景。本赛题实质上为回归任务,其中会涉及到时序预测相关的知识。

参加本次实践主要为了:

  • 快速掌握数据挖掘任务基本流程,为后续更多比赛的实践打下基础
  • 在实践中还可以学习到如果构建时间序列预测相关问题的特征提取技巧,以及模型使用方法。

题目再现

通过电炉空间温度推测产品内部温度,设计烧结过程的温度场和浓度场的最优控制律:

  • 任务输入:电炉对应17个温区的实际生产数据,分别是电炉上部17组加热棒设定温度T1-1T1-17,电炉下部17组加热棒设定温度T2-1T2-17,底部17组进气口的设定进气流量V1-V17;
  • 任务输出:电炉对应17个温区上部空间和下部空间17个测温点的测量温度值。 值得注意的是预测目标为34个,所以需要我们进行34次模型训练和预测。

在简单熟悉云环境后,我进行了本地环境的部署,初步满足比赛项目要求,通过项目方给出的示例代码,我进行了复现并且尝试运行直到跑通,目前的模型精度不高,这是我第一次接触机器学习,希望未来的日子里会有所提升。

需要用到的第三方库

PandasLightGBMscikit-learn tqdm
Pandas是一个功能强大且灵活的Python库,用于数据处理和分析。它提供了高性能的数据结构,特别是DataFrame(类似于Excel中的表格),使得数据操作变得简单且高效。Pandas能够轻松地处理大型数据集,支持数据的读取、写入、清洗、过滤、聚合、合并、重塑等操作,为数据科学家和分析师提供了强大的工具,用于数据预处理和数据分析任务。LightGBM是一个高效且快速的梯度提升树(Gradient Boosting Decision Tree)框架,由微软开发。它是一种基于树的机器学习算法,可用于分类和回归问题。LightGBM的特点是采用了基于直方图的决策树算法,在保持准确性的同时大大减少了内存使用和计算时间。它通过并行计算和特征并行技术,能够高效地处理大规模数据集和高维特征数据,广泛应用于比赛和工业实践中。scikit-learn是Python中最流行的机器学习库之一,简称为sklearn。它提供了丰富的机器学习算法,包括分类、回归、聚类、降维、模型选择和预处理等。sklearn的设计目标是提供一致而简单的API接口,使得机器学习的实验变得易于上手和快速实现。sklearn还包含用于模型评估和调优的工具,以及对数据的预处理、特征选择、特征工程等功能。这使得sklearn成为学习和实践机器学习算法的首选库。 tqdm是一个Python库,用于在循环中添加进度条,以便在终端中显示循环的执行进度。它的名称"tqdm"代表"taqaddum",意为"进步"。tqdm简单易用,只需将可迭代对象传递给它,即可在循环过程中显示进度条。进度条显示了已经完成的迭代次数,总共的迭代次数,以及估计的剩余时间。这对于处理大规模数据或耗时的任务,特别是数据处理、模型训练等,有很大的帮助,让用户可以时刻了解任务的进展情况。

Baseline代码精读

导入所需的库

import pandas as pd  # 导入 pandas 库并使用别名 pd,用于处理数据的工具
import lightgbm as lgb  # 导入 lightgbm 库并使用别名 lgb,用于机器学习模型 LightGBM
from sklearn.metrics import mean_absolute_error  # 导入 mean_absolute_error 函数,用于评分 MAE 的计算
from sklearn.model_selection import train_test_split  # 导入 train_test_split 函数,用于拆分训练集与验证集
from tqdm import tqdm  # 导入 tqdm 函数,用于显示循环的进度条工具
train_dataset = pd.read_csv("./data/train.csv") # 原始训练数据。
test_dataset = pd.read_csv("./data/test.csv") # 原始测试数据(用于提交)。

submit = pd.DataFrame() # 定义提交的最终数据。
submit["序号"] = test_dataset["序号"] # 对齐测试数据的序号。

MAE_scores = dict() # 定义评分项。

这段代码读取两个 CSV 文件,“train.csv” 和 “test.csv”,分别包含原始的训练数据和用于提交的测试数据。使用 Pandas 库 (pd) 读取这些 CSV 文件,并将它们分别存储为名为 train_dataset 和 test_dataset 的 DataFrame。接着创建一个名为 submit 的新 DataFrame,用于存储最终的提交数据,这将用于提交预测结果。将 test_dataset 中的“序号”(索引)列提取出来,并将其赋值给 submit DataFrame 的“序号”列。这样做是为了将测试数据的索引与预测结果进行对应。

pred_labels = list(train_dataset.columns[-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',
        'objective': 'regression',
        'metric': 'mae',
        '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': 2023,
        'nthread' : 16,
        'verbose' : -1,
    }

no_info = lgb.callback.log_evaluation(period=-1) # 禁用训练日志输出。

1.pred_labels 是一个包含需要预测的标签列名的列表。在这段代码中,train_dataset.columns[-34:] 表示选取 train_dataset 的倒数第34列到最后一列的所有列名,这些列名即为需要预测的标签列名。
2.train_set 和 valid_set 分别是训练集和验证集的 DataFrame。train_test_split 函数将 train_dataset 拆分为两个部分,其中 test_size=0.2 表示拆分比例为80%的训练集和20%的验证集。
3.lgb_params 是 LightGBM 训练的参数设置。这里使用字典类型来存储这些参数,包括 boosting_type(梯度提升类型)、objective(优化目标,这里是回归问题)、metric(评估指标,这里是平均绝对误差 MAE)、min_child_weight(子节点的最小权重和)、num_leaves(树的叶子节点数目)、lambda_l2(L2 正则化项的权重)、feature_fraction(每次迭代时选择的特征比例)、bagging_fraction(每次迭代时用于训练的数据比例)、bagging_freq(bagging 的频率)、learning_rate(学习率)、seed(随机种子)、nthread(线程数)、verbose(是否输出训练过程的日志)等参数。
4.no_info 是一个 LightGBM 回调函数,用于禁用训练过程的日志输出。

def time_feature(data: pd.DataFrame, pred_labels: list=None) -> pd.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 # 返回最后处理的数据。

此函数的作用是将原始数据集中的时间列进行处理,并生成新的时间特征,例如月份、日期、小时、分钟、周数、年中第几天和周中第几天等。这些时间特征有助于模型更好地理解数据并提高预测性能。如果提供了预测标签列表 pred_labels,则还会将这些标签从数据集中删除,以便将数据集划分为特征和标签。最后,函数返回处理后的数据集。

test_features = time_feature(test_dataset) # 处理测试集的时间特征,无需 pred_labels。
# 从所有待预测特征中依次取出标签进行训练与预测。
for pred_label in tqdm(pred_labels):
    train_features = time_feature(train_set, pred_labels=pred_labels) # 处理训练集的时间特征。
    train_labels = train_set[pred_label] # 训练集的标签数据。
    train_data = lgb.Dataset(train_features, label=train_labels) # 将训练集转换为 LightGBM 可处理的类型。

    valid_features = time_feature(valid_set, pred_labels=pred_labels) # 处理验证集的时间特征。
    valid_labels = valid_set[pred_label] # 验证集的标签数据。
    valid_data = lgb.Dataset(valid_features, label=valid_labels) # 将验证集转换为 LightGBM 可处理的类型。

    # 训练模型,参数依次为:导入模型设定参数、导入训练集、设定模型迭代次数(5000)、导入验证集、禁止输出日志
    model = lgb.train(lgb_params, train_data, 5000, valid_sets=valid_data, callbacks=[no_info])

    valid_pred = model.predict(valid_features, num_iteration=model.best_iteration) # 选择效果最好的模型进行验证集预测。
    test_pred = model.predict(test_features, num_iteration=model.best_iteration) # 选择效果最好的模型进行测试集预测。
    MAE_score = mean_absolute_error(valid_pred, valid_labels) # 计算验证集预测数据与真实数据的 MAE。
    MAE_scores[pred_label] = MAE_score # 将对应标签的 MAE 值 存入评分项中。

    submit[pred_label] = test_pred # 将测试集预测数据存入最终提交数据中。
在这段代码中: 1.首先使用 time_feature 函数对测试集 test_dataset 进行处理,生成包含时间特征的测试集 test_features。 2.然后,使用一个循环来处理每个待预测的标签(pred_label)。循环中的步骤如下: 使用 time_feature 函数处理训练集 train_set,并将其中的待预测标签列表 pred_labels 传递给该函数,得到训练集特征 train_features。 3.从 train_set 中取出当前待预测的标签 pred_label,作为训练集的标签数据 train_labels。 将训练集特征 train_features 和训练集标签 train_labels 转换为 LightGBM 可处理的数据类型 lgb.Dataset,存储在 train_data 中。 4.使用 time_feature 函数处理验证集 valid_set,并将其中的待预测标签列表 pred_labels 传递给该函数,得到验证集特征 valid_features。 5.从 valid_set 中取出当前待预测的标签 pred_label,作为验证集的标签数据 valid_labels。 将验证集特征 valid_features 和验证集标签 valid_labels 转换为 LightGBM 可处理的数据类型 lgb.Dataset,存储在 valid_data 中。 6.使用 LightGBM 模型,根据给定的参数 lgb_params 对训练集 train_data 进行训练,设定模型迭代次数为 5000,同时传入验证集 valid_data,并禁用输出日志,得到训练好的模型 model。 7.使用训练好的模型 model 对验证集特征 valid_features 进行预测,得到验证集的预测结果 valid_pred。 8.使用训练好的模型 model 对测试集特征 test_features 进行预测,得到测试集的预测结果 test_pred。 9.计算验证集预测数据 valid_pred 与真实数据 valid_labels 的平均绝对误差 (MAE),将其存储在字典 MAE_scores 中,以标签 pred_label 为键。将测试集的预测结果 test_pred 存储在最终提交数据 submit 中,以标签 pred_label 为列名。 这样,循环执行后,MAE_scores 字典中包含了每个待预测标签的 MAE 值,而 submit DataFrame 包含了测试集的预测结果,可以用于提交。

运行结果:
在这里插入图片描述
在这里插入图片描述
文章开篇来源: https://datawhaler.feishu.cn/docx/PB2nd23zyoPtvYxEfxncBwJBnDf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值