【零基础】跑通一站式baseline task1

#datawhaler

#baseline

作为小白,在datawhaler的夏令营中学习baseline,获益匪浅。

1.导入依赖库和转换数据格式 

1.1.主要依赖库:

  1. numpy 用于矩阵运算
  2. pandas 用于表格处理
  3. pathlib 主要用于文件路径处理
  4. sklearn 用于机器学习算法,这里主要使用了线性回归LinearRegression

代码如下:

pip install numpy pandas scikit-learn matplotlib seaborn # 安装第三方库
Looking in indexes: https://mirrors.cloud.aliyuncs.com/pypi/simple
Requirement already satisfied: numpy in /usr/local/lib/python3.10/site-packages (1.26.4)
Requirement already satisfied: pandas in /usr/local/lib/python3.10/site-packages (2.2.2)
Requirement already satisfied: scikit-learn in /usr/local/lib/python3.10/site-packages (1.5.0)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/site-packages (3.9.0)
Requirement already satisfied: seaborn in /usr/local/lib/python3.10/site-packages (0.13.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/site-packages (from pandas) (2024.1)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/site-packages (from pandas) (2.9.0.post0)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/site-packages (from pandas) (2024.1)
Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.10/site-packages (from scikit-learn) (1.4.2)
Requirement already satisfied: scipy>=1.6.0 in /usr/local/lib/python3.10/site-packages (from scikit-learn) (1.12.0)
Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.10/site-packages (from scikit-learn) (3.5.0)
Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.10/site-packages (from matplotlib) (1.4.5)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/site-packages (from matplotlib) (1.2.1)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/site-packages (from matplotlib) (3.1.2)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/site-packages (from matplotlib) (0.12.1)
Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.10/site-packages (from matplotlib) (10.3.0)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/site-packages (from matplotlib) (24.0)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/site-packages (from matplotlib) (4.53.0)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/site-packages (from python-dateutil>=2.8.2->pandas) (1.16.0)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip is available: 23.0.1 -> 24.1.2
[notice] To update, run: pip install --upgrade pip
import numpy as np
import pandas as pd
from pathlib import Path
from sklearn.linear_model import LinearRegression

1.2.处理时间数据

这里我们做了几件事:

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

submit.csv提交格式

day,time,clearing price (CNY/MWh)
2024/4/1 , 0:15 , 352.334 
2024/4/1 , 0:30 , 355.536

在进行进一步编写代码前,有效的预处理能大量减少后续迭代方案的耗时

代码如下:

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)"]]

1.3.查看市场数据

我们可以查看一下市场数据,这里包含约55000个出清电价和电力负荷数据,市场每15分钟生成一次出清电价

  1. timestamp:时间戳
  2. demand:区域内电力总负荷(总需求),单位为MW
  3. clearing price (CNY/MWh):市场出清电价,单位为元/MW·h

其中MW为功率单位,MW·h为能量单位,表示1MW的电器运行一小时产生的能量(例如1度电就是1KW·h)

代码如下:

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

示例:

机组数据包含549个不同的火电机组

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

 示例:

2.使用ABM估计市场出清价格 

Agent-Based Modeling (ABM) 是一种模拟系统的复杂行为和动态的计算方法。它通过定义系统中的个体(称为“代理(Agent)”)及其相互作用规则来进行建模。每个代理具有独特的属性和行为。ABM 模型通过模拟代理之间的互动,观察宏观层面的模式和现象,帮助理解复杂系统的行为和演化。

在这里,市场的主体是各个发电机组,他们在电力现货市场中根据市场信息/其他机组信息进行报价,并以获得最大利润为目标

这里我们用边际成本定价法作为baseline,即每个机组都以其自身每生产一度电的成本进行报价,而不考虑市场信息和其他机组信息。

类比来说就是只会以成本价卖出商品(事实上这就是完全竞争市场的长期均衡状态)

随后,按报价从低到高排序,依次接受报价,直到累计的功率超过了总需求,市场达到出清状态,并以最后一个满足的报价作为市场出清价格的估计

 代码如下:

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]

示例:

 

2.2.转换耗煤量为机组报价

由于这里耗煤量单位是g,虽然和成本正相关但不能等同于报价(事实上应该考虑煤价和其他固定资产开销成本)。由于我们不知道如何将耗煤量转为报价,因此我们简单地使用线性回归,拟合估计价格到真实市场出清价格。

例如A集合[1,2,3]可通过乘以2转为B集合[2,4,6],假如我们无法知道计算方法,可以用一个函数拟合这样的映射关系。在这里A集合就是耗煤量,B集合为实际报价

代码如下:

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)

 可以看出我们的拟合方程式是:P=11.26*N-2763.16,其中N为耗煤量,P为机组报价

model.coef_, model.intercept_

使用边际成本定价的机组报价为出清价格估计

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

示例:

这就是baseline入门学习的全部内容啦,虽然还有一些似懂非懂的地方,但datawhaler提供的教程非常适合小白学习,在摸索的过程中逐渐理解baseline的运作流程。而且写笔记的过程也加深了我对知识的印象,绝赞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值