在预测中,我们经常希望确保预测结果保持在一定范围内。例如,在预测产品的销量时,我们可能要求所有预测结果都为正数。因此,预测结果可能需要有边界。

使用 TimeGPT,您可以通过在调用预测函数之前对数据进行转换来创建边界预测。

1. 导入包

首先,我们安装并导入所需的包

import pandas as pd
import numpy as np

from nixtla import NixtlaClient
nixtla_client = NixtlaClient(
    # defaults to os.environ.get("NIXTLA_API_KEY")
    api_key = 'my_api_key_provided_by_nixtla'
)

👍 使用 Azure AI 端点

要使用 Azure AI 端点,请设置 base_url 参数

nixtla_client = NixtlaClient(base_url="you azure ai endpoint", api_key="your api_key")

2. 加载数据

我们使用来自 《预测:原理与实践》年度鸡蛋价格 数据集。我们期望鸡蛋价格严格为正,因此我们希望将预测值限制为正。

注意

您可以使用 pip 安装 pyreadr

pip install pyreadr
import pyreadr
from pathlib import Path

# Download and store the dataset
url = 'https://github.com/robjhyndman/fpp3package/raw/master/data/prices.rda'
dst_path = str(Path.cwd().joinpath('prices.rda'))
result = pyreadr.read_r(pyreadr.download_file(url, dst_path), dst_path)
# Perform some preprocessing
df = result['prices'][['year', 'eggs']]
df = df.dropna().reset_index(drop=True)
df = df.rename(columns={'year':'ds', 'eggs':'y'})
df['ds'] = pd.to_datetime(df['ds'], format='%Y')
df['unique_id'] = 'eggs'

df.tail(10)
dsyunique_id
841984-01-01100.58eggs
851985-01-0176.84eggs
861986-01-0181.10eggs
871987-01-0169.60eggs
881988-01-0164.55eggs
891989-01-0180.36eggs
901990-01-0179.79eggs
911991-01-0174.79eggs
921992-01-0164.86eggs
931993-01-0162.27eggs

我们可以看看价格在 20 世纪是如何演变的,这表明价格呈下降趋势。

nixtla_client.plot(df)

3. 使用 TimeGPT 进行边界预测

首先,我们转换目标数据。在这种情况下,我们将在预测之前对数据进行对数变换,以便我们只能预测正价格。

df_transformed = df.copy()
df_transformed['y'] = np.log(df_transformed['y'])

我们将创建未来 10 年的预测,并包含预测分布的 80、90 和 99.5 百分位数。

timegpt_fcst_with_transform = nixtla_client.forecast(df=df_transformed, h=10, freq='Y', level=[80, 90, 99.5])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: AS-JAN
INFO:nixtla.nixtla_client:Restricting input...
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...

📘 Azure AI 中的可用模型

如果您正在使用 Azure AI 端点,请务必设置 model="azureai"

nixtla_client.forecast(..., model="azureai")

对于公共 API,我们支持两种模型:timegpt-1timegpt-1-long-horizon

默认情况下使用 timegpt-1。关于如何以及何时使用 timegpt-1-long-horizon,请参阅本教程

创建预测后,我们需要反转之前应用的转换。对于对数变换,这意味着我们需要对预测进行指数化

cols_to_transform = [col for col in timegpt_fcst_with_transform if col not in ['unique_id', 'ds']]
for col in cols_to_transform:
    timegpt_fcst_with_transform[col] = np.exp(timegpt_fcst_with_transform[col])

现在,我们可以绘制预测图。我们包含了多个预测区间,表示预测分布的 80、90 和 99.5 百分位数。

nixtla_client.plot(
    df, 
    timegpt_fcst_with_transform, 
    level=[80, 90, 99.5],
    max_insample_length=20
)

预测和预测区间看起来是合理的。

让我们将这些预测与未应用转换的情况进行比较。在这种情况下,可能会预测出负价格。

timegpt_fcst_without_transform = nixtla_client.forecast(df=df, h=10, freq='Y', level=[80, 90, 99.5])
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: AS-JAN
INFO:nixtla.nixtla_client:Restricting input...
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...

事实上,我们现在观察到预测区间变为负值

nixtla_client.plot(
    df, 
    timegpt_fcst_without_transform, 
    level=[80, 90, 99.5],
    max_insample_length=20
)

例如,在 1995 年

timegpt_fcst_without_transform
unique_iddsTimeGPTTimeGPT-lo-99.5TimeGPT-lo-90TimeGPT-lo-80TimeGPT-hi-80TimeGPT-hi-90TimeGPT-hi-99.5
0eggs1994-01-0166.85975643.10324046.13144849.31903484.40047987.58806590.616273
1eggs1995-01-0164.993477-20.924112-4.75004112.275298117.711656134.736995150.911066
2eggs1996-01-0166.6958086.4991708.29115010.177444123.214173125.100467126.892446
3eggs1997-01-0166.10332517.30428224.96693933.03289499.173756107.239711114.902368
4eggs1998-01-0167.9065174.99537112.34964820.090992115.722042123.463386130.817663
5eggs1999-01-0166.14757529.16220731.80446034.58577997.709372100.490691103.132943
6eggs2000-01-0166.06263714.67193219.30582224.183601107.941673112.819453117.453343
7eggs2001-01-0168.0457693.91528213.18896422.950736113.140802122.902573132.176256
8eggs2002-01-0166.718903-42.212631-30.583703-18.342726151.780531164.021508175.650436
9eggs2003-01-0167.344078-86.239911-44.959745-1.506939136.195095179.647901220.928067

这证明了对数变换在使用 TimeGPT 获取边界预测方面的价值,它使我们能够获得校准更佳的预测区间。

参考资料