【打卡】Datawhale暑期实训ML赛事

文章目录

  • 赛题描述
    • 任务要求
    • 数据集介绍
    • 评估指标
  • 赛题分析
  • 基于LightGBM模型
  • Baseline详解
  • 改进baseline
    • 早停法
    • 添加特征

赛题描述

赛事地址:科大讯飞锂离子电池生产参数调控及生产温度预测挑战赛

任务要求

初赛任务:初赛提供了电炉17个温区的实际生产数据,分别是电炉上部17组加热棒设定温度T1-1 ~ T1-17,电炉下部17组加热棒设定温度T2-1~T2-17,底部17组进气口的设定进气流量V1-V17,选手需要根据提供的数据样本构建模型,预测电炉上下部空间17个测温点的测量温度值。

数据集介绍

初赛任务:初赛提供了电炉17个温区的实际生产数据,分别是电炉上部17组加热棒设定温度T1-1 ~ T1-17,电炉下部17组加热棒设定温度T2-1~T2-17,底部17组进气口的设定进气流量V1-V17,选手需要根据提供的数据样本构建模型,预测电炉上下部空间17个测温点的测量温度值。

评估指标

初赛考核办法采用测试集各行数据的加热棒上部温度设定值、加热棒下部温度设定值、进气流量3类数据作为输入,选手分别预测上部空间测量温度、下部空间测量温度。将选手预测的上部空间测量温度、下部空间测量温度与测试集数据的测量值进行比较。采用MAE平均绝对误差作为评价指标。

赛题分析

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

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

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

同时数据规模比较小,可以快速处理数据和搭建模型,对于机器要求8g内存即可。

本次为结构化赛题,包含电炉烧结每个时间段的流量、上下部设定温度,以及预测目标上下部测量温度值。

基于LightGBM模型

在处理这个问题时,我们主要考虑的是回归预测。一种常规的解决思路是运用机器学习技术,例如 LightGBM 或 XGBoost,或者借助深度学习方法进行实践。当我们选择自行搭建模型的路径时,我们将面临更为复杂的挑战,包括构建模型结构以及对数值数据进行标准化处理。

然而,一个简易的解决方案可能就在我们眼前,那就是直接使用现成的机器学习模型。这种方法具有明显的优势,其模型使用简单,数据预处理的需求也大大减少。

总的来说,我们需要经过以下步骤来解决本问题:

数据预处理
切分训练集与验证集
训练模型
生成最后的预测结果。
在实施这些步骤的过程中,我们需要根据模型的性质和数据的特点灵活调整,确保每一步的实施都能最大化模型的预测准确性,从而有效解决这个回归预测问题。

Baseline详解

导入需要的库:

import pandas as pd # 用于处理数据的工具
import lightgbm as lgb # 机器学习模型 LightGBM
from sklearn.metrics import mean_absolute_error # 评分 MAE 的计算函数
from sklearn.model_selection import train_test_split # 拆分训练集与验证集工具
from tqdm import 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() # 定义评分项。

查看数据:

train_dataset.head()

在这里插入图片描述
在这里插入图片描述

test_dataset.head()

在这里插入图片描述
在这里插入图片描述
设置lgb参数:

# 参数设置
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', #使用的提升方法,使用梯度提升决策树gbdt'objective': 'regression', #使用的最小化指标'metric': '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为不打印,0为打}no_info = lgb.callback.log_evaluation(period=-1) # 禁用训练日志输出。

进行特征工程,主要是时间文本转换为时间格式,生成年、日、小时、分钟等时间特征:

# 时间特征函数
def time_feature(data: pd.DataFrame, pred_labels: list=None) -> pd.DataFrame:"""提取数据中的时间特征。输入: data: Pandas.DataFrame需要提取时间特征的数据。pred_labels: list, 默认值: None需要预测的标签的列表。如果是测试集,不需要填入。输出: data: Pandas.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 # 返回最后处理的数据。test_features = time_feature(test_dataset) # 处理测试集的时间特征,无需 pred_labels。
test_features.head(5)

在这里插入图片描述

训练模型并进行预测:

# 从所有待预测特征中依次取出标签进行训练与预测。
for pred_label in tqdm(pred_labels):# print("当前的pred_label是:", pred_label)train_features = time_feature(train_set, pred_labels=pred_labels) # 处理训练集的时间特征。# train_features = enhancement(train_features_raw)train_labels = train_set[pred_label] # 训练集的标签数据。# print("当前的train_labels是:", train_labels)train_data = lgb.Dataset(train_features, label=train_labels) # 将训练集转换为 LightGBM 可处理的类型。valid_features = time_feature(valid_set, pred_labels=pred_labels) # 处理验证集的时间特征。# valid_features = enhancement(valid_features_raw)valid_labels = valid_set[pred_label] # 验证集的标签数据。# print("当前的valid_labels是:", valid_labels)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 # 将测试集预测数据存入最终提交数据中。submit.to_csv('submit_result.csv', index=False) # 保存最后的预测结果到 submit_result.csv

保存文件:

# 保存文件并查看结果
submit.to_csv('submit_result.csv', index=False) # 保存最后的预测结果到 submit_result.csv。
print(MAE_scores) # 查看各项的 MAE 值。

最后结果是7.94826。

改进baseline

早停法

由于模型有过拟合的风险,所以可以通过早停来让模型在一段时间不能得到提升后提前结束训练。lgb中可以通过添加参数来实现。

lgb_params = {'boosting_type': 'gbdt', #使用的提升方法,使用梯度提升决策树gbdt'objective': 'regression', #使用的最小化指标'metric': 'mae', #使用的评价指标'early_stopping_round':20, #早停,如果20轮没有提升就停止训练'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为不打印,0为打}

添加特征

尝试提取更多特征,这里尝试添加交叉特征、历史平移特征、差分特征、和窗口统计特征;每种特征都是有理可据的,具体说明如下:
(1)交叉特征:主要提取流量、上部温度设定、下部温度设定之间的关系;
(2)历史平移特征:通过历史平移获取上个阶段的信息;
(3)差分特征:可以帮助获取相邻阶段的增长差异,描述数据的涨减变化情况。在此基础上还可以构建相邻数据比值变化、二阶差分等;
(4)窗口统计特征:窗口统计可以构建不同的窗口大小,然后基于窗口范围进统计均值、最大值、最小值、中位数、方差的信息,可以反映最近阶段数据的变化情况。

在时间特征函数中添加:

 # 交叉特征for i in range(1,18):data[f'流量{i}/上部温度设定{i}'] = data[f'流量{i}'] / data[f'上部温度设定{i}']data[f'流量{i}/下部温度设定{i}'] = data[f'流量{i}'] / data[f'下部温度设定{i}']data[f'上部温度设定{i}/下部温度设定{i}'] = data[f'上部温度设定{i}'] / data[f'下部温度设定{i}']# 历史平移for i in range(1,18):data[f'last1_流量{i}'] = data[f'流量{i}'].shift(1)data[f'last1_上部温度设定{i}'] = data[f'上部温度设定{i}'].shift(1)data[f'last1_下部温度设定{i}'] = data[f'下部温度设定{i}'].shift(1)# 差分特征for i in range(1,18):data[f'last1_diff_流量{i}'] = data[f'流量{i}'].diff(1)data[f'last1_diff_上部温度设定{i}'] = data[f'上部温度设定{i}'].diff(1)data[f'last1_diff_下部温度设定{i}'] = data[f'下部温度设定{i}'].diff(1)# 窗口统计for i in range(1,18):data[f'win3_mean_流量{i}'] = (data[f'流量{i}'].shift(1) + data[f'流量{i}'].shift(2) + data[f'流量{i}'].shift(3)) / 3data[f'win3_mean_上部温度设定{i}'] = (data[f'上部温度设定{i}'].shift(1) + data[f'上部温度设定{i}'].shift(2) + data[f'上部温度设定{i}'].shift(3)) / 3data[f'win3_mean_下部温度设定{i}'] = (data[f'下部温度设定{i}'].shift(1) + data[f'下部温度设定{i}'].shift(2) + data[f'下部温度设定{i}'].shift(3)) / 3# 对平移后的空值进行填充 data = data.fillna(method='bfill')

这里要注意在平移之后第一个值会变成nan(因为没有前一个值),包括窗口统计的前3个值,因此需要用后填充的方式将其填充。

经过这两个操作后分数变为7.51948。
由于时间关系,暂时只做这两个改进,后续会进行更多探索。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用win10专业版自带远程桌面公司内网电脑

在现代社会中,各类电子硬件已经遍布我们身边,除了应用在个人娱乐场景的消费类电子产品外,各项工作也离不开电脑的帮助,特别是涉及到数据采集和储存的场景(如安保监控、自动化流程等等),更是离不…

pytest自动化测试指定执行测试用例

1、在控制台执行 打开cmd,进入项目目录 指定执行某个模块 pytest testcases\Logistics\Platform\CarSource\test_CarSourceList.py 指定执行某个目录及其子目录的所有测试文件 pytest testcases\Logistics\Platform\CarSource 指定执行某个模块的某个类的某个测试用例 pyte…

Java_25_方法引用

方法引用 方法引用: 方法引用是为了进一步简化Lambda表达式的写法。 方法引用的格式:类型或者对象::引用的方法。 关键语法是:“::” 小结:方法引用可以进一步简化Lambda表达式的写法。关键语法是:“::”范例代码&…

音视频入门之音频采集、编码、播放

作者:花海blog 今天我们学习音频的采集、编码、生成文件、转码等操作,我们生成三种格式的文件格式,pcm、wav、aac 三种格式,并且我们用 AudioStack 来播放音频,最后我们播放这个音频。 使用 AudioRecord 实现录音生成…

前端JavaScript面试100问(上)

1、解释一下什么是闭包 ? 闭包:就是能够读取外层函数内部变量的函数。闭包需要满足三个条件: 访问所在作用域;函数嵌套;在所在作用域外被调用 。 优点: 可以重复使用变量,并且不会造成变量污染 。缺点&am…

文件系统总结

《本文件系统默认linux文件系统》 一、文件系统基本概念 文件系统是操作系统中负责存取和管理信息的模块,它用统一的方式管理用户和系统信息的存储、检索、更新、共享和保护,并为用户提供一整套方便有效的文件使用和操作方法文件系统是操作系统中管理文…

idea terminal npm指令无效

文章目录 一、修改setting二、修改启动方式 一、修改setting 菜单栏:File->Settings 二、修改启动方式 快捷方式->右键属性->兼容性->勾选管理员身份运行

unittest 数据驱动DDT应用

前言 一般进行接口测试时,每个接口的传参都不止一种情况,一般会考虑正向、逆向等多种组合。所以在测试一个接口时通常会编写多条case,而这些case除了传参不同外,其实并没什么区别。 这个时候就可以利用ddt来管理测试数据&#xf…

WEB APIs day4 (2)

三、M端事件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, …

6.修饰符

文章目录 6.1 在一个静态方法内调用一个非静态成员为什么是非法的?6.2 静态方法和实例方法有何不同 6.1 在一个静态方法内调用一个非静态成员为什么是非法的? 由于静态方法可以不通过对象进行调用&#xff0c;因此在静态方法里&#xff0c;不能调用其他非静态变量&#xff0…

下级平台级联安防视频汇聚融合EasyCVR平台,层级显示不正确是什么原因?

视频汇聚平台安防监控EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RTMP、FLV、HLS、WebRTC等…

算法练习-LeetCode1071. Greatest Common Divisor of Strings

题目地址&#xff1a;LeetCode - The Worlds Leading Online Programming Learning Platform Description: For two strings s and t, we say "t divides s" if and only if s t ... t (i.e., t is concatenated with itself one or more times). Given two strin…

Ubuntu 交叉编译openssl + pahomqtt

&#xff08;一&#xff09;交叉编译openssl 1 下载openssl 下载链接&#xff1a;/source/index.html 2 解压openssl tar -xzvf openssl-3.0.9.tar.gz 3 配置其config编译条件 ~/Downloads/openssl-3.0.9$ ./config no-asm -shared --prefix/home/cidi/Downloads/openss…

【华为OD机试】模拟消息队列【2023 B卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 让我们来模拟一个消息队列的运作,有一个发布者和若干消费者, 发布者会在给定的时刻向消息队列发送消息若此时消息队列有消费者订阅, 这个消息会被发送到订阅的消费者中优先级最高(输…

springboot 发送邮件,以及邮件工具类 并且解决spring-boot-starter-mail 发送邮件附件乱码或者文件错乱

1、设置系统值 System.setProperty(“mail.mime.splitlongparameters”, “false”); 2、 在创建对象的时候定义编码格式(utf-8)&#xff1a; MimeMessageHelper helper new MimeMessageHelper(mes, true, “utf-8”); 3、 其次&#xff0c;在添加附件的时候&#xff0c;附…

安全基础 --- html基础标签 + DNS工作原理

html基础标签 &#xff08;1&#xff09;id id属性是元素在网页内的唯一标识符。 比如&#xff0c;网页可能包含多个<p>标签&#xff0c;id属性可以指定每个<p>标签的唯一标识符。 <p id"p1"></p> <p id"p2"></p>…

React的hooks---useReducer

useReducer 作为 useState 的代替方案&#xff0c;在某些场景下使用更加适合&#xff0c;例如 state 逻辑较复杂且包含多个子值&#xff0c;或者下一个 state 依赖于之前的 state 等。 使用 useReducer 还能给那些会触发深更新的组件做性能优化&#xff0c;因为父组件可以向自…

linux terminal显示git分支

首先查看PS1&#xff1a; echo $PS1 在.bashrc中添加下面修改&#xff1a; function git_branch {branch"git branch 2>/dev/null | grep "^\*" | sed -e "s/^\*\ //""if [ "${branch}" ! "" ];thenif [[ $branch *&…

华为OD机考--阿里巴巴黄金箱

题目内容 贫如洗的樵夫阿里巴巴在去砍柴的路上&#xff0c;无意中发现了强盗集团的藏宝地&#xff0c;藏宝地有编号从0~N的箱子每个箱子上面贴有一个数字箱子中可能有一个黄金宝箱。 黄金宝箱满足排在它之前的所有箱子数字和等于排在它之后的所有箱子数字之和; 一个箱子左边部分…

Windows 11 22H2 中文版、英文版 (x64、ARM64) 下载 (updated Jul 2023)

Windows 11 22H2 中文版、英文版 (x64、ARM64) 下载 (updated Jul 2023) Windows 11, version 22H2 官方原版&#xff0c;2023 年 7 月 更新 请访问原文链接&#xff1a;https://sysin.org/blog/windows-11/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作…