您可以使用 TimeGPT 预测一组时间序列,例如零售中的产品需求。但如果您想评估该产品的不同定价方案怎么办?执行此类情景分析可以帮助您更好地了解定价如何影响产品需求,并有助于决策制定。

在本示例中,我们将向您展示:* 如何使用 TimeGPT 将价格作为外部变量预测产品需求 * 如何评估影响产品需求的不同定价方案

1. 导入包

首先,我们导入所需的包并初始化 Nixtla 客户端。

import pandas as pd
import os

from nixtla import NixtlaClient
from datasetsforecast.m5 import M5
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. 加载 M5 数据

让我们看看预测来自 M5 数据集 的产品销售量的示例。M5 数据集包含美国 10 家零售店的每日产品需求量(销售量)。

首先,我们使用 datasetsforecast 加载数据。这返回

  • Y_df,包含每个唯一产品(unique_id 列)在每个时间戳(ds 列)的销售量(y 列)。
  • X_df,包含每个唯一产品(unique_id 列)在每个时间戳(ds 列)的附加相关信息。

提示

您可以在此处找到有关在 TimeGPT 预测中包含外部变量的教程。

Y_df, X_df, S_df = M5.load(directory=os.getcwd())

Y_df.head(10)
100%|██████████| 50.2M/50.2M [00:00<00:00, 58.1MiB/s]
INFO:datasetsforecast.utils:Successfully downloaded m5.zip, 50219189, bytes.
INFO:datasetsforecast.utils:Decompressing zip file...
INFO:datasetsforecast.utils:Successfully decompressed c:\Users\ospra\OneDrive\Nixtla\Repositories\nixtla\m5\datasets\m5.zip
c:\Users\ospra\miniconda3\envs\nixtla\lib\site-packages\datasetsforecast\m5.py:143: FutureWarning: The default of observed=False is deprecated and will be changed to True in a future version of pandas. Pass observed=False to retain current behavior or observed=True to adopt the future default and silence this warning.
  keep_mask = long.groupby('id')['y'].transform(first_nz_mask, engine='numba')
unique_iddsy
0FOODS_1_001_CA_12011-01-293.0
1FOODS_1_001_CA_12011-01-300.0
2FOODS_1_001_CA_12011-01-310.0
3FOODS_1_001_CA_12011-02-011.0
4FOODS_1_001_CA_12011-02-024.0
5FOODS_1_001_CA_12011-02-032.0
6FOODS_1_001_CA_12011-02-040.0
7FOODS_1_001_CA_12011-02-052.0
8FOODS_1_001_CA_12011-02-060.0
9FOODS_1_001_CA_12011-02-070.0

在本示例中,我们将仅保留 sell_price 列中的附加相关信息。此列显示产品的销售价格,我们预计在不同销售价格下需求会波动。

X_df = X_df[['unique_id', 'ds', 'sell_price']]

X_df.head(10)
unique_iddssell_price
0FOODS_1_001_CA_12011-01-292.0
1FOODS_1_001_CA_12011-01-302.0
2FOODS_1_001_CA_12011-01-312.0
3FOODS_1_001_CA_12011-02-012.0
4FOODS_1_001_CA_12011-02-022.0
5FOODS_1_001_CA_12011-02-032.0
6FOODS_1_001_CA_12011-02-042.0
7FOODS_1_001_CA_12011-02-052.0
8FOODS_1_001_CA_12011-02-062.0
9FOODS_1_001_CA_12011-02-072.0

3. 使用价格作为外部变量预测需求

我们将仅预测一个产品在数据集中所有 10 家零售店的需求。我们选择一个价格变化很多、由 FOODS_1_129_ 标识的食品产品。

products = [
            'FOODS_1_129_CA_1', 
            'FOODS_1_129_CA_2', 
            'FOODS_1_129_CA_3', 
            'FOODS_1_129_CA_4', 
            'FOODS_1_129_TX_1', 
            'FOODS_1_129_TX_2', 
            'FOODS_1_129_TX_3',
            'FOODS_1_129_WI_1',
            'FOODS_1_129_WI_2',
            'FOODS_1_129_WI_3'
            ]
Y_df_product = Y_df.query('unique_id in @products')
X_df_product = X_df.query('unique_id in @products')

我们合并两个数据框以创建将在 TimeGPT 中使用的数据集。

df = Y_df_product.merge(X_df_product)

df.head(10)
unique_iddsysell_price
0FOODS_1_129_CA_12011-02-011.06.22
1FOODS_1_129_CA_12011-02-020.06.22
2FOODS_1_129_CA_12011-02-030.06.22
3FOODS_1_129_CA_12011-02-040.06.22
4FOODS_1_129_CA_12011-02-051.06.22
5FOODS_1_129_CA_12011-02-060.06.22
6FOODS_1_129_CA_12011-02-070.06.22
7FOODS_1_129_CA_12011-02-080.06.22
8FOODS_1_129_CA_12011-02-090.06.22
9FOODS_1_129_CA_12011-02-103.06.22

让我们研究一下这些产品在数据最后一年中的需求(我们的目标 y)如何演变。我们看到,在加利福尼亚州的商店(带有 CA_ 后缀)中,该产品销售是间歇性的,而在其他地区(TXWY)销售则不那么间歇。请注意,该图仅显示了 8 家商店(共 10 家)。

nixtla_client.plot(df, 
                   unique_ids=products,
                   max_insample_length=365)

接下来,我们查看这些产品在整个可用数据中的 sell_price。我们发现在 2011 年至 2016 年期间价格变化相对较少——总共约 20 次。请注意,该图仅显示了 8 家商店(共 10 家)。

nixtla_client.plot(df, 
                   unique_ids=products,
                   target_col='sell_price')

接下来转向我们的预测任务。我们将预测数据集的最后 28 天。

要在 TimeGPT 中使用 sell_price 外部变量,我们必须将其添加为未来值。因此,我们创建一个包含 unique_id、时间戳 dssell_price 的未来值数据框。

future_ex_vars_df = df.drop(columns = ['y'])
future_ex_vars_df = future_ex_vars_df.query("ds >= '2016-05-23'")

future_ex_vars_df.head(10)
unique_iddssell_price
1938FOODS_1_129_CA_12016-05-235.74
1939FOODS_1_129_CA_12016-05-245.74
1940FOODS_1_129_CA_12016-05-255.74
1941FOODS_1_129_CA_12016-05-265.74
1942FOODS_1_129_CA_12016-05-275.74
1943FOODS_1_129_CA_12016-05-285.74
1944FOODS_1_129_CA_12016-05-295.74
1945FOODS_1_129_CA_12016-05-305.74
1946FOODS_1_129_CA_12016-05-315.74
1947FOODS_1_129_CA_12016-06-015.74

接下来,我们将输入数据框限制为除预测期最后 28 天之外的所有数据

df_train = df.query("ds < '2016-05-23'")

df_train.tail(10)
unique_iddsysell_price
19640FOODS_1_129_WI_32016-05-133.07.23
19641FOODS_1_129_WI_32016-05-141.07.23
19642FOODS_1_129_WI_32016-05-152.07.23
19643FOODS_1_129_WI_32016-05-163.07.23
19644FOODS_1_129_WI_32016-05-171.07.23
19645FOODS_1_129_WI_32016-05-182.07.23
19646FOODS_1_129_WI_32016-05-193.07.23
19647FOODS_1_129_WI_32016-05-201.07.23
19648FOODS_1_129_WI_32016-05-210.07.23
19649FOODS_1_129_WI_32016-05-220.07.23

让我们调用 TimeGPT 的 forecast 方法

timegpt_fcst_df = nixtla_client.forecast(df=df_train, X_df=future_ex_vars_df, h=28)
timegpt_fcst_df.head()
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: D
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon. This may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Using the following exogenous variables: sell_price
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
unique_iddsTimeGPT
0FOODS_1_129_CA_12016-05-230.875594
1FOODS_1_129_CA_12016-05-240.777731
2FOODS_1_129_CA_12016-05-250.786871
3FOODS_1_129_CA_12016-05-260.828223
4FOODS_1_129_CA_12016-05-270.791228

📘 Azure AI 中可用的模型

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

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

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

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

我们绘制预测值、实际值以及预测期前的最后 28 天数据

nixtla_client.plot(
    df[['unique_id', 'ds', 'y']], 
    timegpt_fcst_df, 
    max_insample_length=56, 
)

4. 如果?在预测需求时改变价格

当我们在预测期改变产品的价格时会发生什么?让我们看看当我们增加或减少 sell_price 5% 时,我们的预测如何变化。

price_change = 0.05

# Plus 
future_ex_vars_df_plus= future_ex_vars_df.copy()
future_ex_vars_df_plus["sell_price"] = future_ex_vars_df_plus["sell_price"] * (1 + price_change)
# Minus
future_ex_vars_df_minus = future_ex_vars_df.copy()
future_ex_vars_df_minus["sell_price"] = future_ex_vars_df_minus["sell_price"] * (1 - price_change)

让我们使用 TimeGPT 创建一组新的预测。

timegpt_fcst_df_plus = nixtla_client.forecast(df=df_train, X_df=future_ex_vars_df_plus, h=28)
timegpt_fcst_df_minus = nixtla_client.forecast(df=df_train, X_df=future_ex_vars_df_minus, h=28)
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: D
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon. This may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Using the following exogenous variables: sell_price
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: D
WARNING:nixtla.nixtla_client:The specified horizon "h" exceeds the model horizon. This may lead to less accurate forecasts. Please consider using a smaller horizon.
INFO:nixtla.nixtla_client:Using the following exogenous variables: sell_price
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

让我们结合我们的三个预测。我们看到,正如我们所预期的,如果降低(增加)价格,需求预计会略有增加(减少)。换句话说,更便宜的产品会带来更高的销售量,反之亦然。

注意

价格弹性是衡量(产品)需求对价格变化的敏感程度的指标。在此阅读更多信息

timegpt_fcst_df_plus = timegpt_fcst_df_plus.rename(columns={'TimeGPT':f'TimeGPT-sell_price_plus_{price_change * 100:.0f}%'})
timegpt_fcst_df_minus = timegpt_fcst_df_minus.rename(columns={'TimeGPT':f'TimeGPT-sell_price_minus_{price_change * 100:.0f}%'})

timegpt_fcst_df = pd.concat([timegpt_fcst_df, 
                             timegpt_fcst_df_plus[f'TimeGPT-sell_price_plus_{price_change * 100:.0f}%'], 
                             timegpt_fcst_df_minus[f'TimeGPT-sell_price_minus_{price_change * 100:.0f}%']], axis=1)

timegpt_fcst_df.head(10)
unique_iddsTimeGPTTimeGPT-sell_price_plus_5%TimeGPT-sell_price_minus_5%
0FOODS_1_129_CA_12016-05-230.8755940.8470061.370029
1FOODS_1_129_CA_12016-05-240.7777310.7491421.272166
2FOODS_1_129_CA_12016-05-250.7868710.7582831.281306
3FOODS_1_129_CA_12016-05-260.8282230.7996351.322658
4FOODS_1_129_CA_12016-05-270.7912280.7626401.285663
5FOODS_1_129_CA_12016-05-280.8191330.7905451.313568
6FOODS_1_129_CA_12016-05-290.8399920.8114041.334427
7FOODS_1_129_CA_12016-05-300.8430700.8144811.337505
8FOODS_1_129_CA_12016-05-310.8330890.8045001.327524
9FOODS_1_129_CA_12016-06-010.8550320.8264431.349467

最后,让我们绘制不同定价方案下的预测,展示 TimeGPT 在一组产品价格变化时如何预测不同的需求。在图表中,我们可以看到,对于特定产品在某些时期,折扣增加了预期需求,而在其他时期和对于其他产品,价格变化对总需求的影响较小。

nixtla_client.plot(
    df[['unique_id', 'ds', 'y']], 
    timegpt_fcst_df, 
    max_insample_length=56, 
)

在本示例中,我们向您展示了:* 如何使用 TimeGPT 将价格作为外部变量预测产品需求 * 如何评估影响产品需求的不同定价方案

重要提示

  • 此方法假设历史需求和价格行为对未来需求具有预测作用,并忽略了影响需求的其他因素。要包含这些其他因素,请使用额外的外部变量,为模型提供更多关于影响需求的因素的背景信息。
  • 此方法对影响需求的未建模事件(例如突发市场变化)很敏感。要包含这些事件,如果过去也观察到此类突发变化,请使用指示此类变化的额外外部变量。