基于集成学习GBDT模型(Gradient Boosting Decision Tree)的电力市场博弈与价格预测#AI夏令营 #Datawhale #夏令营

#AI夏令营 #Datawhale #夏令营

       本次比赛是通过发电供给数据与市场需求数据预测市场出清价格,本质上是一个回归问题。既然是回归问题,除了简单的线性回归预测外,我第一个想到的就是机器学习中的GBDT模型(当时还没用接触ABM模型),即通过构建多个弱预测模型(通常是决策树)来最小化损失函数。GBDT模型可以在市场出清价格预测当中处理复杂的数据特征和非线性关系。得出的预测结果分数下降了一些(模拟更接近),这里与大家分享我的心得。

 一、模型搭建

1.下载相关库并读取数据

     这里的numpy、pandas、sklearn都是回归预测中常用的,使用pd库让计算机读取比赛给出的发电供给数据和市场需求数据。

#下载对应的包
import numpy as np
import pandas as pd
from pathlib import Path
from sklearn.ensemble import GradientBoostingRegressor

base_path = Path("data")  # 确保数据都放在同级的data目录下

# 读取市场数据
electricity_price = pd.read_csv(r'D:\pycharm\pythonProject1\算法大赛\data\electricity_price.csv')
# 读取市场主体(各发电机组)数据
unit = pd.read_csv(r'D:\pycharm\pythonProject1\算法大赛\data\unit.csv')

2.数据清洗

    数据清洗是对数据进行处理前必须要做的。我们首先对原始数据的缺失值进行处理。接着对数据中的时间做进一步处理。为了便于提取时间戳特征,我们将day和time列合并成新的时间戳列。采用24小时制。同时,为了方便计算机理解和避免产生歧义,我们这样要将24:00:00改成00:00:00(一天最早的时刻)。在合并成新的时间戳后,要将原本无用的day列和time列删除。

这里还需要注意的一点是,由于市场博弈是发电供给与市场需求量的匹配机制,我们需要按照边际成本(额外生产一单位电所需要的费用)重新排序,并提前计算好市场需求的电量总量。

# 准备示例提交数据sample_submit,选择出清价格为缺失值的行,并去除demand列
sample_submit = electricity_price[electricity_price["clearing price (CNY/MWh)"].isna()].drop(columns="demand")

# 将准备好的示例提交数据保存到CSV文件
sample_submit.to_csv(base_path / "sample_submit.csv", index=False)

# 将day和time列合并成timestamp列,便于提取时间戳特征
electricity_price["timestamp"] = pd.to_datetime(
    electricity_price["day"] + " " + electricity_price["time"].str.replace("24:00:00", "00:00"))

# 处理24:00:00的情况,即表示第二天的00:00:00
mask = electricity_price['timestamp'].dt.time == pd.Timestamp('00:00:00').time()
electricity_price.loc[mask, 'timestamp'] += pd.Timedelta(days=1)

# 设置列的顺序,同时去除day和time列
electricity_price = electricity_price[["timestamp", "demand", "clearing price (CNY/MWh)"]]

# 按照一度电的耗煤量(近似为边际成本)降序排序发电机组数据
sorted_unit = unit.sort_values("coal consumption (g coal/KWh)")

# 预先计算 sorted_unit 的累积和
sorted_unit['cumulative_capacity'] = sorted_unit['Capacity(MW)'].cumsum()

3.提取特征变量和目标变量

这时候需要根据发电和需求开始匹配和成交,为计算出清价格做好准备。

# 初始化一个空列表,用于存储每个需求对应的最后一个满足总需求的机组报价
prices = []

# 遍历每个需求,找到最后一个满足总需求的机组报价
for demand in electricity_price["demand"]:
    price = sorted_unit[sorted_unit['cumulative_capacity'] >= demand]["coal consumption (g coal/KWh)"].iloc[0]
    prices.append(price)

# 训练集长度
train_length = 55392

# 将prices列表转换为NumPy数组,并重塑为二维数组
prices = np.array(prices).reshape(-1, 1)

4.划分训练集和测试集

# 分割特征和目标变量,用于模型训练
X = prices[:train_length]
y = electricity_price["clearing price (CNY/MWh)"].iloc[:train_length].values.ravel()  # 确保y是一维数组

5.模型训练及搭建

我们使用训练集拟合GBDT模型,并使用拟合后的模型对测试数据进行预测。再将得到的预测的数组放到DataFrame表中,最后将表保存到CSV文件,即为我们得到的出清价格的预测成果。

# 初始化GBDT模型
model = GradientBoostingRegressor()

# 使用训练数据拟合GBDT模型
model.fit(X, y)

# 使用模型对测试数据进行预测
y_pred = model.predict(prices[train_length:])

# 确保预测结果是一维数组
y_pred = y_pred.ravel()

# 将预测结果添加到sample_submit DataFrame
sample_submit["clearing price (CNY/MWh)"] = y_pred

# 输出预测结果的前5行
print(sample_submit.head())

# 将预测结果保存到CSV文件
sample_submit.to_csv("submit.csv", index=False)

提交的成果果然比简单使用的线性回归拟合程度更高了。为什么会比普通的线性回归高呢,我在想是因为GBDT模型通过构建多个弱预测模型决策树最小化损失函数,并迭代地添加新的决策树来纠正前一轮的残差,逐步优化模型,不断优化的过程正是预测值不断接近实际值的一步。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值