初赛任务:初赛提供了电炉17个温区的实际生产数据,分别是电炉上部17组加热棒设定温度T1-1~T1-17,电炉下部17组加热棒设定温度T2-1~T2-17,底部17组进气口的设定进气流量V1-V17,选手需要根据提供的数据样本构建模型,预测电炉上下部空间17个测温点的测量温度值。
初赛为参赛选手提供了5类数据:1)加热棒上部温度设定值、2)加热棒下部温度设定值、3)进气流量、4)上部空间测量温度、5)下部空间测量温度。出于数据安全保证的考虑,所有数据均为脱敏处理后的数据。训练集及测试集每行均含有5类数据。选手需要建立上部加热棒设定温度、下部加热棒设定温度、进气流量与上部空间测量温度、下部空间测量温度之间的模型。
初赛考核办法采用测试集各行数据的加热棒上部温度设定值、加热棒下部温度设定值、进气流量3类数据作为输入,选手分别预测上部空间测量温度、下部空间测量温度。将选手预测的上部空间测量温度、下部空间测量温度与测试集数据的测量值进行比较。采用MAE平均绝对误差作为评价指标。
LightGBM模型是一个基于梯度提升决策树(GBDT)的机器学习框架,它可以用于回归、分类、排序等任务。
科大讯飞锂离子电池生产参数调控及生产温度预测挑战赛_Baseline - 飞桨AI Studio本项目为科大讯飞锂离子电池温度预测赛道Baseline,可一键运行~~ - 飞桨AI Studiohttps://aistudio.baidu.com/aistudio/projectdetail/6512066?sUid=2554132&shared=1&ts=1689841007106
# 导入所需的库
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 # 拆分训练集与验证集工具
# 用于将数据集拆分为训练集和验证集,以便进行模型训练和评估
# sklearn.model_selection对机器学习模型进行参数调优、数据集拆分、交叉验证和性能评估等任务
# 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() # 定义评分项。
# 模型训练
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',
'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) # 回调函数no_info,禁用训练日志输出。
# LightGBM通常会输出一些训练过程的信息,通过回调函数可以避免输出这些信息,使得训练过程更简洁
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 无法处理。
# 转换成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。
# 从所有待预测特征中依次取出标签进行训练与预测。
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 可处理的类型。
# 训练模型,参数依次为:导入模型设定参数、导入训练集、设定模型迭代次数(200)、导入验证集、禁止输出日志
model = lgb.train(lgb_params, train_data, 200, 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。
print(MAE_scores) # 查看各项的 MAE 值。
from sklearn.metrics import mean_absolute_error # 评分 MAE 的计算函数
from sklearn.model_selection import train_test_split # 拆分训练集与验证集工具
from tqdm import tqdm # 显示循环的进度条工具
pip install scikit-learn
【sklearn模块的导入】
pred_labels
是一个列表,包含了 34 个需要预测的标签的列名,这些标签可能是分类或者回归的目标变量。train_test_split
是一个函数,用来将数据集随机分成两部分,一部分作为训练集,一部分作为验证集。test_size=0.2
表示验证集占总数据集的 20%。train_set
和 valid_set
是两个数据框,分别存储了训练集和验证集的数据,包括特征和标签。train_dataset.columns
是一个索引对象,包含了数据框的所有列名。[-34:]
是一个切片操作,表示从倒数第 34 列开始到最后一列结束的所有列。list()
是一个函数,用来将索引对象转换成一个列表,方便后续操作。train_test_split
是一个函数,来自于 sklearn.model_selection
模块,用于数据集的拆分。train_dataset
是一个数据框,作为函数的第一个参数,表示要拆分的数据集。test_size=0.2
是一个关键字参数,表示验证集占总数据集的比例,可以是一个浮点数或者一个整数。num_leaves
、learning_rate
、feature_fraction
等,观察模型的表现,然后再细化调整其他参数。传统集成学习中,两类典型的集成学习框架:
集成学习的本质将若干个学习器组合起来,进行投票
提升集成学习模型的性能
误差优化:给定一个数据分布的情况下,无论多么好的函数或者模型去进行拟合,总会产生一个误差
,以往是让预测值
不断逼近
,但可以考虑对残差
进行优化,将其看作一个凸优化问题,求最小值
回归与误差本质可以相互转化
梯度与偏导、导数本质上是互通的
XGBoost是机器学习的一个里程碑:
造成数据稀疏原因:
XGBoost优点:【以层为单位】
XGBoost问题:
LightGBM主要优化点:【以节点为单位】
LightGBM主要方法:
先对特征值做装箱处理,本质上是一个分段函数(对每个特征的取值做个分段函数,将所有样板在该特征上的取值划分到某一段bin中)。最终把特征取值从连续值转化成了离散值。遍历数据时,根据离散化后的值作为索引在直方图中累计统计量。当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点【连续值变离散,模糊化的处理】
例如,一列0~1的浮点数,将其分段,[0,0.3)0,[0,3,1)
1,即将连续值改写成离散值0和1,即为装箱
行数乘以列数优化到区段数乘以特征数
数据决定上限,模型逼近上限,特征往往不会冗余,数据会冗余
不论是决策树还是集成学习,或者梯度提升的框架,一颗树的节点表示的是分割的规则,阈值划分,给出规则形式,以及叶子节点的权重分数(本质上贪心过程)