检测需求峰值

在这个示例中,我们将展示如何在ERCOT(德克萨斯州)市场上进行电力负荷预测,以检测每日峰值。

介绍

在不同市场中预测峰值是有用的。在电力市场中,在需求高峰时消费电力会因更高的费率而受到惩罚。当个人或公司在电力需求最高时消费电力,监管机构称之为同步峰值(CP)。

在德克萨斯电力市场(ERCOT)中,峰值指的是当ERCOT电网处于最高容量状态时的每月15分钟间隔。峰值是由所有消费者对电网的综合需求造成的。同步峰值需求是ERCOT用来确定最终电力消费账单的重要因素。ERCOT会记录每个客户在6月至9月的4个月内的CP需求,并用此调整电价。因此,客户可以通过减少同步峰值需求来节省电费。

在本示例中,我们将根据历史负荷数据训练一个LightGBM模型,以预测2022年9月的日前峰值。低采样电力数据中通常存在多个季节性。需求表现出每日和每周的季节性特征,特定时间段如下午6点与凌晨3点或特定日子如星期日与星期五都有明显的模式。

首先,我们将加载ERCOT历史需求数据,然后使用MLForecast.cross_validation方法来拟合LightGBM模型,并预测9月的每日负荷。最后,我们展示如何使用预测结果来检测同步峰值。

大纲

  1. 安装库
  2. 加载和探索数据
  3. 拟合LightGBM模型并进行预测
  4. 峰值检测
Tip

您可以使用 Colab 交互式运行此笔记本 在 Colab 中打开

我们假设您已经安装了 MLForecast。请查看本指南以获取 如何安装 MLForecast 的说明。

使用 pip install mlforecast 安装必要的软件包。

此外,我们还需要使用 pip install lightgbm 安装 LightGBM

加载数据

MLForecast 的输入总是一个 长格式 的数据框,包含三列:unique_iddsy

  • unique_id(字符串、整数或类别)表示系列的标识符。

  • ds(日期戳或整数)列应该是一个整数用于时间索引,或者是理想的日期格式 YYYY-MM-DD,或时间戳格式 YYYY-MM-DD HH:MM:SS。

  • y(数值)表示我们希望进行预测的测量值。 我们将重命名

首先,读取 2022 年 ERCOT 市场的历史总需求。我们处理了原始数据(可在 这里 获得),通过添加因夏令时缺失的小时,将日期解析为 datetime 格式,并筛选出感兴趣的列。

import numpy as np
import pandas as pd
from utilsforecast.plotting import plot_series
# 加载数据
Y_df = 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'")
fig = plot_series(Y_df)
fig.savefig('../../figs/electricity_peak_forecasting__eda.png', bbox_inches='tight')

我们观察到该时间序列呈现出季节性模式。此外,该时间序列包含 6,552 个观测值,因此有必要使用计算效率高的方法将其部署到生产环境中。

适配和预测LightGBM模型

导入MLForecast类和所需的模型。

import lightgbm as lgb

from mlforecast import MLForecast
from mlforecast.target_transforms import Differences

首先,实例化模型并定义参数。

Tip

在这个例子中,我们使用了lgb.LGBMRegressor模型的默认参数,但您可以更改它们以提高预测性能。

models = [
    lgb.LGBMRegressor(verbosity=-1) # 你可以在这里添加更多模型。
]

我们通过实例化一个MLForecast对象来拟合模型,并提供以下必需的参数:

  • models:一个类似于sklearn的模型列表(具有fit和predict方法)。

  • freq:一个字符串,表示数据的频率。(请参见pandas的可用频率。)

  • target_transforms:在计算特征之前应用于目标的变换。这些变换在预测步骤中被恢复。

  • lags:作为特征使用的目标滞后值。

# 实例化 MLForecast 类为 mlf
mlf = MLForecast(
    models=models,
    freq='H', 
    target_transforms=[Differences([24])],
    lags=range(1, 25)
)
Tip

在这个示例中,我们仅使用差异和滞后生成特征。请参阅完整文档以查看所有可用特征。

cross_validation 方法允许用户模拟多个历史预测,通过用 fitpredict 方法替换循环,大大简化了管道。此方法在每个窗口重新训练模型并进行预测。请参见 此教程 以获取窗口定义的动画。

使用 cross_validation 方法生成九月份的所有日常预测。要生成日常预测,请将预测范围 window_size 设置为 24。在这个例子中,我们模拟在九月部署管道,因此将窗口数量设置为 30(每天一个)。最后,窗口之间的步长设置为 24(等于 window_size)。这确保每天只产生一个预测。

此外,

  • id_col: 标识每个时间序列。
  • time_col: 标识时间序列的时间列。
  • target_col: 标识要建模的列。
crossvalidation_df = mlf.cross_validation(
    df=Y_df,
    h=24,
    n_windows=30,
)
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
Important

使用 cross_validation 时,请确保预测是在所需的时间戳上生成的。检查 cutoff 列,该列指定了预测窗口之前的最后一个时间戳。

峰值检测

最后,我们利用crossvaldation_df中的预测值来检测每日的需求高峰。对于每一天,我们将检测到的高峰设为最高的预测值。在这种情况下,我们想要预测一个高峰(npeaks);根据您的设置和目标,这个参数可能会有所变化。例如,高峰的数量可以对应于电池可以放电以减少需求的小时数。

npeaks = 1 # 峰值数量

对于ERCOT 4CP检测任务,我们的目标是正确预测最高的月负载。接下来,我们筛选出九月份中小时需求最高的那一天,并预测峰值。

crossvalidation_df = crossvalidation_df.reset_index()[['ds','y','LGBMRegressor']]
max_day = crossvalidation_df.iloc[crossvalidation_df['y'].argmax()].ds.day # 最大负荷日
cv_df_day = crossvalidation_df.query('ds.dt.day == @max_day')
max_hour = cv_df_day['y'].argmax()
peaks = cv_df_day['LGBMRegressor'].argsort().iloc[-npeaks:].values # 预测峰值

在以下图中,我们可以看到LightGBM模型能够正确地检测到2022年9月的重叠峰值。

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5))
ax.axvline(cv_df_day.iloc[max_hour]['ds'], color='black', label='True Peak')
ax.scatter(cv_df_day.iloc[peaks]['ds'], cv_df_day.iloc[peaks]['LGBMRegressor'], color='green', label=f'Predicted Top-{npeaks}')
ax.plot(cv_df_day['ds'], cv_df_day['y'], label='y', color='blue')
ax.plot(cv_df_day['ds'], cv_df_day['LGBMRegressor'], label='Forecast', color='red')
ax.set(xlabel='Time', ylabel='Load (MW)')
ax.grid()
ax.legend()
fig.savefig('../../figs/electricity_peak_forecasting__predicted_peak.png', bbox_inches='tight')
plt.close()

Important

在这个例子中,我们只包含了九月份。然而,MLForecast和LightGBM可以正确预测2022年四个月的峰值。您可以通过增加cross_validationn_windows参数或过滤Y_df数据集来尝试这一点。

下一步

MLForecast 和 LightGBM 特别适合作为峰值检测的基准模型。然而,进一步探索更新的预测算法或进行超参数优化可能会更有用。

Give us a ⭐ on Github