学习笔记:电力现货市场预测及ABM模型应

电价数据分析笔记

基本信息

在电价数据分析中,我们首先需要了解数据的基本信息,包括数据的时间范围、数据的分辨率(如小时、天、月等)、包含的变量(如电价、总负荷、发电类型等)。这些基本信息为后续的分析奠定基础。

统计指标分析

对数据进行统计指标分析可以帮助我们了解数据的总体特征。常见的统计指标包括:

从总负荷和出清价格的数值分布来看,可以发现以下几个特点:

  • 数据的集聚趋势

    • 均值:df[feature].mean()

    • 中位数 df[feature].median()

    • 最大值 df[feature].max()

    • 最小值 df[feature].min()

    • 众数 df[feature].mode()

  • 数据的变异程度

    • 标准差 df[feature].std()

    • 极差 df[feature].apply(lambda x: x.max() - x.min())

    • 四分位数 df[feature].quantile([0.25, 0.5, 0.75])

    • 变异系数 df[feature].std()/df[feature].mean()

    • 偏度和峰度 df[feature].skew(), df[feature].kurtosis()

  • 变化率:df[feature].pct_change() 计算公式为 (x2-x1)/x1

  • 总负荷基本服从正态分布,符合现实中的耗电规律

  • 出清价格中有大量的异常负价格

  • 1-100之间的低价格较多,表明这些时候火电有一定的异常高价(800以上)

不同小时的总负荷和电价

分析不同小时的总负荷和电价,可以帮助我们了解电价和负荷的日内波动规律。通常情况下,不同小时的电价和负荷会呈现出一定的规律性:

  • 高峰时段:通常在早上和傍晚,电价和负荷较高。
  • 低谷时段:通常在深夜和午后,电价和负荷较低。

鸭子曲线:由于火电和光伏发电互为替代品,当一天太阳出来后,太阳能逐渐开始替代火电,并在14点达到最大,进而导致火电受光伏发电竞争而降价。而在傍晚时太阳落山,光伏机组迅速减小发电,此时火电开始集中发电,价格迅速上升,形成了一天中典型的“两高峰,一低谷”的态势。

通过绘制24小时的电价和负荷曲线,可以直观地看到这些变化规律。

负电价与高电价形成原因分析

在数据分析过程中,我们发现了负电价和异常高电价的现象。为了更好地理解这些现象的形成原因,我们需要进行详细的探索和分析。

负电价

  • 出现频数:低谷期的负电价较为明显,可能是受市场竞争导致电价中标失败,只能亏本售出。
  • 假期影响:例如,2022年的五一假期和春节假期期间,负电价出现频繁。这可能是由于假期期间火力发电量下降,导致负电价。

高电价

  • 时间分布:高电价主要集中在日落后,此时光伏发电下降,火电有较大的竞价空间。
  • 外部因素:例如,2022年8月3日-8月6日的高电价可能受到了外部因素的影响,如天气状况。

通过对比不同时间段的电价和负荷数据,以及结合外部数据(如天气数据),可以更深入地理解负电价和高电价的形成原因。

总结

综合以上分析,我们可以总结出以下几点:

  1. 气象状况对出清价格有较大影响
  2. 节假日对出清价格有较大影响,易于出现负值
  3. 总负荷与出清价格线性关系很高,但总体呈现分段线性的特征
  4. 不同月份/小时下的出清价格受市场竞争影响较大
  5. 随着碳中和不断发展,火电价格有总体下降的趋势

本次案例中的EDA(探索性数据分析)只是一部分,旨在提供探索性数据分析的一般步骤。可以自行尝试使用 seabornplotly 等Python库做进一步的可视化,挖掘序列的更多信息,从而指导后续的特征构造。

下面是随机森林模型,但是结果不如线性回归模型:

import numpy as np
import pandas as pd
from pathlib import Path
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split

# 设置数据路径
base_path = Path("data")

# 读取市场数据
electricity_price = pd.read_csv(base_path / "electricity price.csv")

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

# 准备示例提交数据sample_submit
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)"]]

# 准备训练数据
train_length = 55392
features = ['demand']  # 这里只使用'demand'作为特征,可以加入更多特征
X = electricity_price[features][:train_length]
y = electricity_price["clearing price (CNY/MWh)"].iloc[:train_length]

# 将数据分成训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

# 定义和训练模型
gbr_model = GradientBoostingRegressor(random_state=42)
gbr_model.fit(X_train, y_train)

# 验证模型
y_val_pred = gbr_model.predict(X_val)
print("Validation R^2: ", gbr_model.score(X_val, y_val))

# 准备测试数据
X_test = electricity_price[features][train_length:]

# 进行预测
y_test_pred = gbr_model.predict(X_test)

# 填充预测结果
sample_submit["clearing price (CNY/MWh)"] = y_test_pred

# 保存提交文件
sample_submit.to_csv("submit.csv", index=False)
  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值