Datawhale AI 夏令营 市场博弈和价格预测 ABM

前言

参加夏令营,其中用 ABM 模拟
捕食者-被捕食者(Predator-Prey)模型
的神奇构造着实吸引到我。

本篇记录了 ABM 基础概念,
以及挑战赛“市场博弈和价格预测”的赛题分析。

1 学习ABM基础概念

在这里插入图片描述

典型的ABM模型

代理(Agent)

  • 系统中的基本个体,每个代理都有自己的属性和行为规则。

环境(Environment)

  • 代理活动的空间或网络,可能影响代理的行为。

交互规则(Interaction Rules)

  • 代理之间、代理与环境之间的相互作用规则。

时间步(Time Steps)

  • 系统按离散的时间步推进,模拟出系统的动态变化过程
eg. 捕食者-被捕食者(Predator-Prey)模型

在ABM中实现模拟结果,只需要三个规则

  • 每个智能体有初始的能量,
    移动会消耗能量,进食会增加能量
  • 当能量过低,智能体死亡;
    当能量足够高,智能体会繁育
  • 如果移动后遇到食物,则吃下它
    (对于羊来说是青草,捕食者来说是羊)

在这里插入图片描述

2 分析、理解赛题

市场博弈和价格预测
赛事链接:http://competition.sais.com.cn/competitionDetail/532232/format

在这里插入图片描述

electricity price.csv

在这里插入图片描述

电力市场的市场出清价格,市场需求等信息

  • Day/Time:交易时间,中国电力现货市场15分钟结算一次,一天共96个交易点
  • demand:区域内电力总负荷(总需求),单位为MW
  • clearing price (CNY/MWh):市场出清电价,单位为元/MW·h
unit.csv

在这里插入图片描述

  • unit ID:每个机组唯一的ID
  • Capacity(MW):机组的额定容量(额定功率),越高机组的发电能力越强
  • utilization hour (h) :电厂的年平均运行小时数,
    需要注意多个机组可能共同属于一个电厂,有相同的值
  • coal consumption (g coal/KWh):每发一度电需要耗费多少煤炭,为成本参数
  • power consumption rate:电厂单位时间内耗电量与发电量的百分比,
    例如单位时间耗电量为500度电,发电量为10000度电,利用率就是500/10000=5%。

3 代码 baseline

在jupyter notebook运行
或者使用**魔搭ModelScope**的云上CPU环境

导库

!pip install numpy pandas scikit-learn matplotlib seaborn
import numpy as np
import pandas as pd
from pathlib import Path
from sklearn.linear_model import LinearRegression

转换数据格式

  1. 合并市场数据的日期和时间,
    便于利用pandas高效的时间序列处理能力
    (例如我们能直接用大小于号取一段时间序列)
  2. 处理市场数据以符合最终的提交格式,保存到本地便于后续直接使用
  3. 设置市场数据的列顺序,并去除合并前的时间列

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

# 读取市场数据
electricity_price = pd.read_csv(base_path / "electricity price.csv")
# 读取市场主体(各发电机组)数据
unit = pd.read_csv(base_path / "unit.csv")

"""
准备示例提交数据sample_submit
1. electricity_price["clearing price (CNY/MWh)"].isna()找到出清价格为缺失值的行,即要预测的目标
2. 去除demand列,符合最后的提交格式 
"""

sample_submit = electricity_price[electricity_price["clearing price (CNY/MWh)"].isna()].drop(columns="demand")
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)"]]

electricity_price.head()  # 显示前5行数据
unit.head()

使用ABM估计市场出清价格

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

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

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)

print(len(prices))
prices[:5]

转换耗煤量为机组报价

model = LinearRegression()
# 55392为训练集的长度
train_length = 55392
prices = np.array(prices).reshape(-1, 1)
X = prices[:train_length]
y = electricity_price["clearing price (CNY/MWh)"].iloc[:train_length].values.reshape(-1, 1)
model.fit(X, y)

model.coef_, model.intercept_

y_pred = model.predict(prices[train_length:])
y_pred = y_pred.flatten()  # 2维矩阵转为1维
y_pred[:5]

保存结果

sample_submit["clearing price (CNY/MWh)"] = y_pred
sample_submit.head()

sample_submit.to_csv("submit.csv", index=False)

Read more

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机动人心

解密未来,一文解锁一周动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值