import numpy as np
import pandas as pd
from utilsforecast.plotting import plot_series
检测需求峰值
在这个示例中,我们将展示如何在ERCOT(德克萨斯州)市场上进行电力负荷预测,以检测每日峰值。
介绍
在不同市场中预测峰值是有用的。在电力市场中,在需求高峰时消费电力会因更高的费率而受到惩罚。当个人或公司在电力需求最高时消费电力,监管机构称之为同步峰值(CP)。
在德克萨斯电力市场(ERCOT)中,峰值指的是当ERCOT电网处于最高容量状态时的每月15分钟间隔。峰值是由所有消费者对电网的综合需求造成的。同步峰值需求是ERCOT用来确定最终电力消费账单的重要因素。ERCOT会记录每个客户在6月至9月的4个月内的CP需求,并用此调整电价。因此,客户可以通过减少同步峰值需求来节省电费。
在本示例中,我们将根据历史负荷数据训练一个LightGBM
模型,以预测2022年9月的日前峰值。低采样电力数据中通常存在多个季节性。需求表现出每日和每周的季节性特征,特定时间段如下午6点与凌晨3点或特定日子如星期日与星期五都有明显的模式。
首先,我们将加载ERCOT历史需求数据,然后使用MLForecast.cross_validation
方法来拟合LightGBM
模型,并预测9月的每日负荷。最后,我们展示如何使用预测结果来检测同步峰值。
大纲
- 安装库
- 加载和探索数据
- 拟合LightGBM模型并进行预测
- 峰值检测
库
我们假设您已经安装了 MLForecast。请查看本指南以获取 如何安装 MLForecast 的说明。
使用 pip install mlforecast
安装必要的软件包。
此外,我们还需要使用 pip install lightgbm
安装 LightGBM
。
加载数据
MLForecast 的输入总是一个 长格式 的数据框,包含三列:unique_id
、ds
和 y
:
unique_id
(字符串、整数或类别)表示系列的标识符。ds
(日期戳或整数)列应该是一个整数用于时间索引,或者是理想的日期格式 YYYY-MM-DD,或时间戳格式 YYYY-MM-DD HH:MM:SS。y
(数值)表示我们希望进行预测的测量值。 我们将重命名
首先,读取 2022 年 ERCOT 市场的历史总需求。我们处理了原始数据(可在 这里 获得),通过添加因夏令时缺失的小时,将日期解析为 datetime 格式,并筛选出感兴趣的列。
# 加载数据
= pd.read_csv('https://datasets-nixtla.s3.amazonaws.com/ERCOT-clean.csv', parse_dates=['ds'])
Y_df = Y_df.query("ds >= '2022-01-01' & ds <= '2022-10-01'") Y_df
= plot_series(Y_df) fig
'../../figs/electricity_peak_forecasting__eda.png', bbox_inches='tight') fig.savefig(
我们观察到该时间序列呈现出季节性模式。此外,该时间序列包含 6,552
个观测值,因此有必要使用计算效率高的方法将其部署到生产环境中。
适配和预测LightGBM模型
导入MLForecast
类和所需的模型。
import lightgbm as lgb
from mlforecast import MLForecast
from mlforecast.target_transforms import Differences
首先,实例化模型并定义参数。
在这个例子中,我们使用了lgb.LGBMRegressor
模型的默认参数,但您可以更改它们以提高预测性能。
= [
models =-1) # 你可以在这里添加更多模型。
lgb.LGBMRegressor(verbosity ]
我们通过实例化一个MLForecast
对象来拟合模型,并提供以下必需的参数:
models
:一个类似于sklearn的模型列表(具有fit和predict方法)。freq
:一个字符串,表示数据的频率。(请参见pandas的可用频率。)target_transforms
:在计算特征之前应用于目标的变换。这些变换在预测步骤中被恢复。lags
:作为特征使用的目标滞后值。
# 实例化 MLForecast 类为 mlf
= MLForecast(
mlf =models,
models='H',
freq=[Differences([24])],
target_transforms=range(1, 25)
lags )
在这个示例中,我们仅使用差异和滞后生成特征。请参阅完整文档以查看所有可用特征。
cross_validation
方法允许用户模拟多个历史预测,通过用 fit
和 predict
方法替换循环,大大简化了管道。此方法在每个窗口重新训练模型并进行预测。请参见 此教程 以获取窗口定义的动画。
使用 cross_validation
方法生成九月份的所有日常预测。要生成日常预测,请将预测范围 window_size
设置为 24。在这个例子中,我们模拟在九月部署管道,因此将窗口数量设置为 30(每天一个)。最后,窗口之间的步长设置为 24(等于 window_size
)。这确保每天只产生一个预测。
此外,
id_col
: 标识每个时间序列。time_col
: 标识时间序列的时间列。target_col
: 标识要建模的列。
= mlf.cross_validation(
crossvalidation_df =Y_df,
df=24,
h=30,
n_windows )
crossvalidation_df.head()
unique_id | ds | cutoff | y | LGBMRegressor | |
---|---|---|---|---|---|
0 | ERCOT | 2022-09-01 00:00:00 | 2022-08-31 23:00:00 | 45482.471757 | 45685.265537 |
1 | ERCOT | 2022-09-01 01:00:00 | 2022-08-31 23:00:00 | 43602.658043 | 43779.819515 |
2 | ERCOT | 2022-09-01 02:00:00 | 2022-08-31 23:00:00 | 42284.817342 | 42672.470923 |
3 | ERCOT | 2022-09-01 03:00:00 | 2022-08-31 23:00:00 | 41663.156771 | 42091.768192 |
4 | ERCOT | 2022-09-01 04:00:00 | 2022-08-31 23:00:00 | 41710.621904 | 42481.403168 |
使用 cross_validation
时,请确保预测是在所需的时间戳上生成的。检查 cutoff
列,该列指定了预测窗口之前的最后一个时间戳。
峰值检测
最后,我们利用crossvaldation_df
中的预测值来检测每日的需求高峰。对于每一天,我们将检测到的高峰设为最高的预测值。在这种情况下,我们想要预测一个高峰(npeaks
);根据您的设置和目标,这个参数可能会有所变化。例如,高峰的数量可以对应于电池可以放电以减少需求的小时数。
= 1 # 峰值数量 npeaks
对于ERCOT 4CP检测任务,我们的目标是正确预测最高的月负载。接下来,我们筛选出九月份中小时需求最高的那一天,并预测峰值。
= crossvalidation_df.reset_index()[['ds','y','LGBMRegressor']]
crossvalidation_df = crossvalidation_df.iloc[crossvalidation_df['y'].argmax()].ds.day # 最大负荷日
max_day = crossvalidation_df.query('ds.dt.day == @max_day')
cv_df_day = cv_df_day['y'].argmax()
max_hour = cv_df_day['LGBMRegressor'].argsort().iloc[-npeaks:].values # 预测峰值 peaks
在以下图中,我们可以看到LightGBM模型能够正确地检测到2022年9月的重叠峰值。
import matplotlib.pyplot as plt
= plt.subplots(figsize=(10, 5))
fig, ax 'ds'], color='black', label='True Peak')
ax.axvline(cv_df_day.iloc[max_hour]['ds'], cv_df_day.iloc[peaks]['LGBMRegressor'], color='green', label=f'Predicted Top-{npeaks}')
ax.scatter(cv_df_day.iloc[peaks]['ds'], cv_df_day['y'], label='y', color='blue')
ax.plot(cv_df_day['ds'], cv_df_day['LGBMRegressor'], label='Forecast', color='red')
ax.plot(cv_df_day[set(xlabel='Time', ylabel='Load (MW)')
ax.
ax.grid()
ax.legend()'../../figs/electricity_peak_forecasting__predicted_peak.png', bbox_inches='tight')
fig.savefig( plt.close()
在这个例子中,我们只包含了九月份。然而,MLForecast和LightGBM可以正确预测2022年四个月的峰值。您可以通过增加cross_validation
的n_windows
参数或过滤Y_df
数据集来尝试这一点。
下一步
MLForecast 和 LightGBM 特别适合作为峰值检测的基准模型。然而,进一步探索更新的预测算法或进行超参数优化可能会更有用。
Give us a ⭐ on Github