引言

预测不同市场的峰值很有用。在电力市场中,在需求高峰时段用电会被处以更高的费率。当个人或公司在电力需求最高时消耗电力,监管机构称之为同步峰值 (CP)。

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

在本例中,我们将使用历史负荷数据训练一个 NHITS 模型,以预测 2022 年 9 月的次日峰值。低采样率的电力数据中传统上存在多重季节性。需求表现出每日和每周的季节性,一天中的特定时段(如晚上 6:00 与凌晨 3:00)或一周中的特定日期(如周日与周五)具有明显的模式。

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

概要

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

提示

您可以使用 Colab 交互式运行此 Notebook

我们假设您已经安装了 NeuralForecast。请查看此指南了解 如何安装 NeuralForecast

使用 pip install neuralforecast 安装必要的包

加载数据

NeuralForecast 模型的输入始终是一个 长格式 数据帧,包含三列:unique_id, dsy

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

  • ds(日期戳或整数)列应为索引时间的整数或日期戳,日期格式最好为 YYYY-MM-DD,时间戳格式最好为 YYYY-MM-DD HH:MM:SS。

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

首先,下载并读取 ERCOT 市场的 2022 年历史总需求数据,可在此处获取。数据处理包括添加因夏令时缺失的小时、将日期解析为日期时间格式以及筛选感兴趣的列。

import numpy as np
import pandas as pd
# Load data
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'")
Y_df.plot(x='ds', y='y', figsize=(20, 7))

使用 NHITS 进行拟合和预测

导入 NeuralForecast 类和您需要的模型。

from neuralforecast.core import NeuralForecast
from neuralforecast.auto import AutoNHITS

首先,实例化模型并定义参数。要实例化 AutoNHITS,您需要定义

  • h:预测范围
  • loss:训练损失。使用 DistributionLoss 生成概率预测。默认值:MAE
  • config:超参数搜索空间。如果为 NoneAutoNHITS 类将使用预定义的建议超参数空间。
  • num_samples:探索的配置数量。
models = [AutoNHITS(h=24,
                    config=None, # Uses default config
                    num_samples=10
                   )
         ]

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

  • models:模型列表。从模型中选择您想要的模型并导入它们。

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

# Instantiate StatsForecast class as sf
nf = NeuralForecast(
    models=models,
    freq='h', 
)

cross_validation 方法允许用户模拟多个历史预测,通过用 fitpredict 方法替换 for 循环,极大地简化了流程。此方法会重新训练模型并预测每个窗口。请参阅此教程,了解窗口如何定义的动画演示。

使用 cross_validation 方法生成 9 月份的所有每日预测。要生成每日预测,将预测范围 h 设置为 24。在本例中,我们模拟在 9 月部署管道,因此将窗口数量设置为 30(每天一个)。最后,将窗口之间的步长设置为 24,以便每天只生成一个预测。

crossvalidation_df = nf.cross_validation(
    df=Y_df,
    step_size=24,
    n_windows=30
  )
crossvalidation_df.head()
unique_iddscutoffAutoNHITSy
0ERCOT2022-09-01 00:00:002022-08-31 23:00:0045841.60156245482.471757
1ERCOT2022-09-01 01:00:002022-08-31 23:00:0043613.39453143602.658043
2ERCOT2022-09-01 02:00:002022-08-31 23:00:0041968.94531242284.817342
3ERCOT2022-09-01 03:00:002022-08-31 23:00:0041038.53906241663.156771
4ERCOT2022-09-01 04:00:002022-08-31 23:00:0041237.20312541710.621904

重要提示

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

峰值检测

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

npeaks = 1 # Number of peaks

对于 ERCOT 4CP 检测任务,我们感兴趣的是正确预测最高的月负荷。接下来,我们筛选出 9 月份小时需求最高的那天并预测峰值。

crossvalidation_df = crossvalidation_df[['ds','y','AutoNHITS']]
max_day = crossvalidation_df.iloc[crossvalidation_df['y'].argmax()].ds.day # Day with maximum load
cv_df_day = crossvalidation_df.query('ds.dt.day == @max_day')
max_hour = cv_df_day['y'].argmax()
peaks = cv_df_day['AutoNHITS'].argsort().iloc[-npeaks:].values # Predicted peaks

在下面的图中,我们可以看到模型如何能够正确检测到 2022 年 9 月的同步峰值。

import matplotlib.pyplot as plt
plt.figure(figsize=(10, 5))
plt.axvline(cv_df_day.iloc[max_hour]['ds'], color='black', label='True Peak')
plt.scatter(cv_df_day.iloc[peaks]['ds'], cv_df_day.iloc[peaks]['AutoNHITS'], color='green', label=f'Predicted Top-{npeaks}')
plt.plot(cv_df_day['ds'], cv_df_day['y'], label='y', color='blue')
plt.plot(cv_df_day['ds'], cv_df_day['AutoNHITS'], label='Forecast', color='red')
plt.xlabel('Time')
plt.ylabel('Load (MW)')
plt.grid()
plt.legend()

重要提示

在本例中,我们只包含了 9 月份的数据。然而,NHITS 可以正确预测 2022 年 4 个月的峰值。您可以通过增加 cross_validationnwindows 参数或过滤 Y_df 数据集来尝试。运行所有月份的数据只需 10 分钟。

参考资料