Commit f42429f6 authored by bailuo's avatar bailuo
Browse files

readme

parents
---
title: "Date Features"
description: "Use holidays flags and special dates to improve your accuracy"
icon: "calendar"
---
<Info>
Date features are an essential part of time series analysis. This document introduces helpful classes (CountryHolidays and SpecialDates) for generating holiday flags, custom date markers, and adding them to TimeGPT.
</Info>
## Overview
<CardGroup>
<Card title="CountryHolidays">
Easily attach holiday flags for multiple countries based on a list of countries.
</Card>
<Card title="SpecialDates">
Add flags for custom events or significant dates you define.
</Card>
</CardGroup>
These classes help you enrich your time series datasets with relevant date-based signals. Use them alongside standard data preprocessing techniques to enhance your model's understanding of seasonality and special events.
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/date_features.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
#### CountryHolidays
> ``` text
> CountryHolidays (countries:list[str])
> ```
*Given a list of countries, returns a dataframe with holidays for each
country.*
```python
import pandas as pd
```
| | US_New Year's Day | US_Memorial Day | US_Independence Day | US_Labor Day | US_Veterans Day | US_Veterans Day (observed) | US_Thanksgiving | US_Christmas Day | US_Martin Luther King Jr. Day | US_Washington's Birthday | ... | US_Juneteenth National Independence Day (observed) | US_Christmas Day (observed) | MX_Año Nuevo | MX_Día de la Constitución | MX_Natalicio de Benito Juárez | MX_Día del Trabajo | MX_Día de la Independencia | MX_Día de la Revolución | MX_Transmisión del Poder Ejecutivo Federal | MX_Navidad |
|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|
| 2018-09-03 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2018-09-04 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2018-09-05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2018-09-06 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2018-09-07 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
```python
c_holidays = CountryHolidays(countries=['US', 'MX'])
periods = 365 * 5
dates = pd.date_range(end='2023-09-01', periods=periods)
holidays_df = c_holidays(dates)
holidays_df.head()
```
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/date_features.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
#### SpecialDates
> ``` text
> SpecialDates (special_dates:dict[str,list[str]])
> ```
*Given a dictionary of categories and dates, returns a dataframe with
the special dates.*
```python
special_dates = SpecialDates(
special_dates={
'Important Dates': ['2021-02-26', '2020-02-26'],
'Very Important Dates': ['2021-01-26', '2020-01-26', '2019-01-26']
}
)
periods = 365 * 5
dates = pd.date_range(end='2023-09-01', periods=periods)
holidays_df = special_dates(dates)
holidays_df.head()
```
| | Important Dates | Very Important Dates |
|------------|-----------------|----------------------|
| 2018-09-03 | 0 | 0 |
| 2018-09-04 | 0 | 0 |
| 2018-09-05 | 0 | 0 |
| 2018-09-06 | 0 | 0 |
| 2018-09-07 | 0 | 0 |
---
output-file: nixtla_client.html
title: SDK Reference
icon: 'code'
---
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient
> ``` text
> NixtlaClient (api_key:Optional[str]=None, base_url:Optional[str]=None,
> timeout:Optional[int]=60, max_retries:int=6,
> retry_interval:int=10, max_wait_time:int=360)
> ```
*Client to interact with the Nixtla API.*
| | **Type** | **Default** | **Details** |
|------|------------------|-------------------------|-------------------------|
| api_key | Optional | None | The authorization api_key interacts with the Nixtla API.<br/>If not provided, will use the NIXTLA_API_KEY environment variable. |
| base_url | Optional | None | Custom base_url.<br/>If not provided, will use the NIXTLA_BASE_URL environment variable. |
| timeout | Optional | 60 | Request timeout in seconds. Set this to `None` to disable it. |
| max_retries | int | 6 | The maximum number of attempts to make when calling the API before giving up.<br/>It defines how many times the client will retry the API call if it fails.<br/>Default value is 6, indicating the client will attempt the API call up to 6 times in total |
| retry_interval | int | 10 | The interval in seconds between consecutive retry attempts.<br/>This is the waiting period before the client tries to call the API again after a failed attempt.<br/>Default value is 10 seconds, meaning the client waits for 10 seconds between retries. |
| max_wait_time | int | 360 | The maximum total time in seconds that the client will spend on all retry attempts before giving up.<br/>This sets an upper limit on the cumulative waiting time for all retry attempts.<br/>If this time is exceeded, the client will stop retrying and raise an exception.<br/>Default value is 360 seconds, meaning the client will cease retrying if the total time<br/>spent on retries exceeds 360 seconds.<br/>The client throws a ReadTimeout error after 60 seconds of inactivity. If you want to<br/>catch these errors, use max_wait_time \>\> 60. |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.validate_api_key
> ``` text
> NixtlaClient.validate_api_key (log:bool=True)
> ```
*Check API key status.*
| | **Type** | **Default** | **Details** |
|-------------|----------|-------------|-------------------------------|
| log | bool | True | Show the endpoint’s response. |
| **Returns** | **bool** | | **Whether API key is valid.** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.forecast
> ``` text
> NixtlaClient.forecast (df:~AnyDFType, h:typing.Annotated[int,Gt(gt=0)],
> freq:Union[str,int,pandas._libs.tslibs.offsets.Bas
> eOffset,NoneType]=None, id_col:str='unique_id',
> time_col:str='ds', target_col:str='y',
> X_df:Optional[~AnyDFType]=None,
> level:Optional[list[Union[int,float]]]=None,
> quantiles:Optional[list[float]]=None,
> finetune_steps:typing.Annotated[int,Ge(ge=0)]=0,
> finetune_depth:Literal[1,2,3,4,5]=1, finetune_loss
> :Literal['default','mae','mse','rmse','mape','smap
> e']='default',
> finetuned_model_id:Optional[str]=None,
> clean_ex_first:bool=True,
> hist_exog_list:Optional[list[str]]=None,
> validate_api_key:bool=False,
> add_history:bool=False, date_features:Union[bool,l
> ist[Union[str,Callable]]]=False, date_features_to_
> one_hot:Union[bool,list[str]]=False, model:Literal
> ['azureai','timegpt-1','timegpt-1-long-
> horizon']='timegpt-1', num_partitions:Optional[Ann
> otated[int,Gt(gt=0)]]=None,
> feature_contributions:bool=False)
> ```
*Forecast your time series using TimeGPT.*
| | **Type** | **Default** | **Details** |
|------|------------------|-------------------------|-------------------------|
| df | AnyDFType | | The DataFrame on which the function will operate. Expected to contain at least the following columns:<br/>- time_col:<br/> Column name in `df` that contains the time indices of the time series. This is typically a datetime<br/> column with regular intervals, e.g., hourly, daily, monthly data points.<br/>- target_col:<br/> Column name in `df` that contains the target variable of the time series, i.e., the variable we<br/> wish to predict or analyze.<br/>Additionally, you can pass multiple time series (stacked in the dataframe) considering an additional column:<br/>- id_col:<br/> Column name in `df` that identifies unique time series. Each unique value in this column<br/> corresponds to a unique time series. |
| h | Annotated | | Forecast horizon. |
| freq | Union | None | Frequency of the timestamps. If `None`, it will be inferred automatically.<br/>See [pandas’ available frequencies](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases). |
| id_col | str | unique_id | Column that identifies each series. |
| time_col | str | ds | Column that identifies each timestep, its values can be timestamps or integers. |
| target_col | str | y | Column that contains the target. |
| X_df | Optional | None | DataFrame with \[`unique_id`, `ds`\] columns and `df`’s future exogenous. |
| level | Optional | None | Confidence levels between 0 and 100 for prediction intervals. |
| quantiles | Optional | None | Quantiles to forecast, list between (0, 1).<br/>`level` and `quantiles` should not be used simultaneously.<br/>The output dataframe will have the quantile columns<br/>formatted as TimeGPT-q-(100 \* q) for each q.<br/>100 \* q represents percentiles but we choose this notation<br/>to avoid having dots in column names. |
| finetune_steps | Annotated | 0 | Number of steps used to finetune learning TimeGPT in the<br/>new data. |
| finetune_depth | Literal | 1 | The depth of the finetuning. Uses a scale from 1 to 5, where 1 means little finetuning,<br/>and 5 means that the entire model is finetuned. |
| finetune_loss | Literal | default | Loss function to use for finetuning. Options are: `default`, `mae`, `mse`, `rmse`, `mape`, and `smape`. |
| finetuned_model_id | Optional | None | ID of previously fine-tuned model to use. |
| clean_ex_first | bool | True | Clean exogenous signal before making forecasts using TimeGPT. |
| hist_exog_list | Optional | None | Column names of the historical exogenous features. |
| validate_api_key | bool | False | If True, validates api_key before sending requests. |
| add_history | bool | False | Return fitted values of the model. |
| date_features | Union | False | Features computed from the dates.<br/>Can be pandas date attributes or functions that will take the dates as input.<br/>If True automatically adds most used date features for the<br/>frequency of `df`. |
| date_features_to_one_hot | Union | False | Apply one-hot encoding to these date features.<br/>If `date_features=True`, then all date features are<br/>one-hot encoded by default. |
| model | Literal | timegpt-1 | Model to use as a string. Options are: `timegpt-1`, and `timegpt-1-long-horizon`.<br/>We recommend using `timegpt-1-long-horizon` for forecasting<br/>if you want to predict more than one seasonal<br/>period given the frequency of your data. |
| num_partitions | Optional | None | Number of partitions to use.<br/>If None, the number of partitions will be equal<br/>to the available parallel resources in distributed environments. |
| feature_contributions | bool | False | |
| **Returns** | **AnyDFType** | | **DataFrame with TimeGPT forecasts for point predictions and probabilistic<br/>predictions (if level is not None).** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.cross_validation
> ``` text
> NixtlaClient.cross_validation (df:~AnyDFType,
> h:typing.Annotated[int,Gt(gt=0)], freq:Uni
> on[str,int,pandas._libs.tslibs.offsets.Bas
> eOffset,NoneType]=None,
> id_col:str='unique_id', time_col:str='ds',
> target_col:str='y', level:Optional[list[Un
> ion[int,float]]]=None,
> quantiles:Optional[list[float]]=None,
> validate_api_key:bool=False, n_windows:typ
> ing.Annotated[int,Gt(gt=0)]=1, step_size:O
> ptional[Annotated[int,Gt(gt=0)]]=None, fin
> etune_steps:typing.Annotated[int,Ge(ge=0)]
> =0, finetune_depth:Literal[1,2,3,4,5]=1, f
> inetune_loss:Literal['default','mae','mse'
> ,'rmse','mape','smape']='default',
> finetuned_model_id:Optional[str]=None,
> refit:bool=True, clean_ex_first:bool=True,
> hist_exog_list:Optional[list[str]]=None,
> date_features:Union[bool,list[str]]=False,
> date_features_to_one_hot:Union[bool,list[s
> tr]]=False, model:Literal['azureai','timeg
> pt-1','timegpt-1-long-
> horizon']='timegpt-1', num_partitions:Opti
> onal[Annotated[int,Gt(gt=0)]]=None)
> ```
*Perform cross validation in your time series using TimeGPT.*
| | **Type** | **Default** | **Details** |
|------|------------------|-------------------------|-------------------------|
| df | AnyDFType | | The DataFrame on which the function will operate. Expected to contain at least the following columns:<br/>- time_col:<br/> Column name in `df` that contains the time indices of the time series. This is typically a datetime<br/> column with regular intervals, e.g., hourly, daily, monthly data points.<br/>- target_col:<br/> Column name in `df` that contains the target variable of the time series, i.e., the variable we<br/> wish to predict or analyze.<br/>Additionally, you can pass multiple time series (stacked in the dataframe) considering an additional column:<br/>- id_col:<br/> Column name in `df` that identifies unique time series. Each unique value in this column<br/> corresponds to a unique time series. |
| h | Annotated | | Forecast horizon. |
| freq | Union | None | Frequency of the timestamps. If `None`, it will be inferred automatically.<br/>See [pandas’ available frequencies](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases). |
| id_col | str | unique_id | Column that identifies each series. |
| time_col | str | ds | Column that identifies each timestep, its values can be timestamps or integers. |
| target_col | str | y | Column that contains the target. |
| level | Optional | None | Confidence level between 0 and 100 for prediction intervals. |
| quantiles | Optional | None | Quantiles to forecast, list between (0, 1).<br/>`level` and `quantiles` should not be used simultaneously.<br/>The output dataframe will have the quantile columns<br/>formatted as TimeGPT-q-(100 \* q) for each q.<br/>100 \* q represents percentiles but we choose this notation<br/>to avoid having dots in column names. |
| validate_api_key | bool | False | If True, validates api_key before sending requests. |
| n_windows | Annotated | 1 | Number of windows to evaluate. |
| step_size | Optional | None | Step size between each cross validation window. If None it will be equal to `h`. |
| finetune_steps | Annotated | 0 | Number of steps used to finetune TimeGPT in the<br/>new data. |
| finetune_depth | Literal | 1 | The depth of the finetuning. Uses a scale from 1 to 5, where 1 means little finetuning,<br/>and 5 means that the entire model is finetuned. |
| finetune_loss | Literal | default | Loss function to use for finetuning. Options are: `default`, `mae`, `mse`, `rmse`, `mape`, and `smape`. |
| finetuned_model_id | Optional | None | ID of previously fine-tuned model to use. |
| refit | bool | True | Fine-tune the model in each window. If `False`, only fine-tunes on the first window.<br/>Only used if `finetune_steps` \> 0. |
| clean_ex_first | bool | True | Clean exogenous signal before making forecasts using TimeGPT. |
| hist_exog_list | Optional | None | Column names of the historical exogenous features. |
| date_features | Union | False | Features computed from the dates.<br/>Can be pandas date attributes or functions that will take the dates as input.<br/>If True automatically adds most used date features for the<br/>frequency of `df`. |
| date_features_to_one_hot | Union | False | Apply one-hot encoding to these date features.<br/>If `date_features=True`, then all date features are<br/>one-hot encoded by default. |
| model | Literal | timegpt-1 | Model to use as a string. Options are: `timegpt-1`, and `timegpt-1-long-horizon`.<br/>We recommend using `timegpt-1-long-horizon` for forecasting<br/>if you want to predict more than one seasonal<br/>period given the frequency of your data. |
| num_partitions | Optional | None | Number of partitions to use.<br/>If None, the number of partitions will be equal<br/>to the available parallel resources in distributed environments. |
| **Returns** | **AnyDFType** | | **DataFrame with cross validation forecasts.** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.detect_anomalies
> ``` text
> NixtlaClient.detect_anomalies (df:~AnyDFType,
> freq:Union[str,int,pandas._libs.tslibs.off
> sets.BaseOffset,NoneType]=None,
> id_col:str='unique_id', time_col:str='ds',
> target_col:str='y',
> level:Union[int,float]=99,
> finetuned_model_id:Optional[str]=None,
> clean_ex_first:bool=True,
> validate_api_key:bool=False,
> date_features:Union[bool,list[str]]=False,
> date_features_to_one_hot:Union[bool,list[s
> tr]]=False, model:Literal['azureai','timeg
> pt-1','timegpt-1-long-
> horizon']='timegpt-1', num_partitions:Opti
> onal[Annotated[int,Gt(gt=0)]]=None)
> ```
*Detect anomalies in your time series using TimeGPT.*
| | **Type** | **Default** | **Details** |
|------|------------------|-------------------------|-------------------------|
| df | AnyDFType | | The DataFrame on which the function will operate. Expected to contain at least the following columns:<br/>- time_col:<br/> Column name in `df` that contains the time indices of the time series. This is typically a datetime<br/> column with regular intervals, e.g., hourly, daily, monthly data points.<br/>- target_col:<br/> Column name in `df` that contains the target variable of the time series, i.e., the variable we<br/> wish to predict or analyze.<br/>Additionally, you can pass multiple time series (stacked in the dataframe) considering an additional column:<br/>- id_col:<br/> Column name in `df` that identifies unique time series. Each unique value in this column<br/> corresponds to a unique time series. |
| freq | Union | None | Frequency of the timestamps. If `None`, it will be inferred automatically.<br/>See [pandas’ available frequencies](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases). |
| id_col | str | unique_id | Column that identifies each series. |
| time_col | str | ds | Column that identifies each timestep, its values can be timestamps or integers. |
| target_col | str | y | Column that contains the target. |
| level | Union | 99 | Confidence level between 0 and 100 for detecting the anomalies. |
| finetuned_model_id | Optional | None | ID of previously fine-tuned model to use. |
| clean_ex_first | bool | True | Clean exogenous signal before making forecasts<br/>using TimeGPT. |
| validate_api_key | bool | False | If True, validates api_key before sending requests. |
| date_features | Union | False | Features computed from the dates.<br/>Can be pandas date attributes or functions that will take the dates as input.<br/>If True automatically adds most used date features for the<br/>frequency of `df`. |
| date_features_to_one_hot | Union | False | Apply one-hot encoding to these date features.<br/>If `date_features=True`, then all date features are<br/>one-hot encoded by default. |
| model | Literal | timegpt-1 | Model to use as a string. Options are: `timegpt-1`, and `timegpt-1-long-horizon`.<br/>We recommend using `timegpt-1-long-horizon` for forecasting<br/>if you want to predict more than one seasonal<br/>period given the frequency of your data. |
| num_partitions | Optional | None | Number of partitions to use.<br/>If None, the number of partitions will be equal<br/>to the available parallel resources in distributed environments. |
| **Returns** | **AnyDFType** | | **DataFrame with anomalies flagged by TimeGPT.** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.usage
> ``` text
> NixtlaClient.usage ()
> ```
*Query consumed requests and limits*
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.finetune
> ``` text
> NixtlaClient.finetune
> (df:Union[pandas.core.frame.DataFrame,polars.dataf
> rame.frame.DataFrame], freq:Union[str,int,pandas._
> libs.tslibs.offsets.BaseOffset,NoneType]=None,
> id_col:str='unique_id', time_col:str='ds',
> target_col:str='y',
> finetune_steps:typing.Annotated[int,Ge(ge=0)]=10,
> finetune_depth:Literal[1,2,3,4,5]=1, finetune_loss
> :Literal['default','mae','mse','rmse','mape','smap
> e']='default', output_model_id:Optional[str]=None,
> finetuned_model_id:Optional[str]=None, model:Liter
> al['azureai','timegpt-1','timegpt-1-long-
> horizon']='timegpt-1')
> ```
*Fine-tune TimeGPT to your series.*
| | **Type** | **Default** | **Details** |
|------|------------------|-------------------------|-------------------------|
| df | Union | | The DataFrame on which the function will operate. Expected to contain at least the following columns:<br/>- time_col:<br/> Column name in `df` that contains the time indices of the time series. This is typically a datetime<br/> column with regular intervals, e.g., hourly, daily, monthly data points.<br/>- target_col:<br/> Column name in `df` that contains the target variable of the time series, i.e., the variable we<br/> wish to predict or analyze.<br/>Additionally, you can pass multiple time series (stacked in the dataframe) considering an additional column:<br/>- id_col:<br/> Column name in `df` that identifies unique time series. Each unique value in this column<br/> corresponds to a unique time series. |
| freq | Union | None | Frequency of the timestamps. If `None`, it will be inferred automatically.<br/>See [pandas’ available frequencies](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases). |
| id_col | str | unique_id | Column that identifies each series. |
| time_col | str | ds | Column that identifies each timestep, its values can be timestamps or integers. |
| target_col | str | y | Column that contains the target. |
| finetune_steps | Annotated | 10 | Number of steps used to finetune learning TimeGPT in the new data. |
| finetune_depth | Literal | 1 | The depth of the finetuning. Uses a scale from 1 to 5, where 1 means little finetuning,<br/>and 5 means that the entire model is finetuned. |
| finetune_loss | Literal | default | Loss function to use for finetuning. Options are: `default`, `mae`, `mse`, `rmse`, `mape`, and `smape`. |
| output_model_id | Optional | None | ID to assign to the fine-tuned model. If `None`, an UUID is used. |
| finetuned_model_id | Optional | None | ID of previously fine-tuned model to use as base. |
| model | Literal | timegpt-1 | Model to use as a string. Options are: `timegpt-1`, and `timegpt-1-long-horizon`.<br/>We recommend using `timegpt-1-long-horizon` for forecasting<br/>if you want to predict more than one seasonal<br/>period given the frequency of your data. |
| **Returns** | **str** | | **ID of the fine-tuned model** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.finetuned_models
> ``` text
> NixtlaClient.finetuned_models (as_df:bool=False)
> ```
*List fine-tuned models*
| | **Type** | **Default** | **Details** |
|------|------------------|-------------------------|-------------------------|
| as_df | bool | False | Return the fine-tuned models as a pandas dataframe |
| **Returns** | **Union** | | **List of available fine-tuned models.** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.finetuned_model
> ``` text
> NixtlaClient.finetuned_model (finetuned_model_id:str)
> ```
*Get fine-tuned model metadata*
| | **Type** | **Details** |
|--------|---------------------------|-------------------------------------|
| finetuned_model_id | str | ID of the fine-tuned model to get metadata from. |
| **Returns** | **FinetunedModel** | **Fine-tuned model metadata.** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.delete_finetuned_model
> ``` text
> NixtlaClient.delete_finetuned_model (finetuned_model_id:str)
> ```
*Delete a previously fine-tuned model*
| | **Type** | **Details** |
|--------------------|----------|-------------------------------------------|
| finetuned_model_id | str | ID of the fine-tuned model to be deleted. |
| **Returns** | **bool** | **Whether delete was successful.** |
------------------------------------------------------------------------
<a
href="https://github.com/Nixtla/nixtla/blob/main/nixtla/nixtla_client.py#LNone"
target="_blank" style={{ float: "right", fontSize: "smaller" }}>source</a>
## NixtlaClient.plot
> ``` text
> NixtlaClient.plot (df:Union[pandas.core.frame.DataFrame,polars.dataframe.
> frame.DataFrame,NoneType]=None, forecasts_df:Union[pan
> das.core.frame.DataFrame,polars.dataframe.frame.DataFr
> ame,NoneType]=None, id_col:str='unique_id',
> time_col:str='ds', target_col:str='y', unique_ids:Unio
> n[list[str],NoneType,numpy.ndarray]=None,
> plot_random:bool=True, max_ids:int=8,
> models:Optional[list[str]]=None,
> level:Optional[list[Union[int,float]]]=None,
> max_insample_length:Optional[int]=None,
> plot_anomalies:bool=False,
> engine:Literal['matplotlib','plotly','plotly-
> resampler']='matplotlib',
> resampler_kwargs:Optional[dict]=None, ax:Union[Forward
> Ref('plt.Axes'),numpy.ndarray,ForwardRef('plotly.graph
> _objects.Figure'),NoneType]=None)
> ```
*Plot forecasts and insample values.*
| | **Type** | **Default** | **Details** |
|------|------------------|-------------------------|-------------------------|
| df | Union | None | The DataFrame on which the function will operate. Expected to contain at least the following columns:<br/>- time_col:<br/> Column name in `df` that contains the time indices of the time series. This is typically a datetime<br/> column with regular intervals, e.g., hourly, daily, monthly data points.<br/>- target_col:<br/> Column name in `df` that contains the target variable of the time series, i.e., the variable we<br/> wish to predict or analyze.<br/>Additionally, you can pass multiple time series (stacked in the dataframe) considering an additional column:<br/>- id_col:<br/> Column name in `df` that identifies unique time series. Each unique value in this column<br/> corresponds to a unique time series. |
| forecasts_df | Union | None | DataFrame with columns \[`unique_id`, `ds`\] and models. |
| id_col | str | unique_id | Column that identifies each series. |
| time_col | str | ds | Column that identifies each timestep, its values can be timestamps or integers. |
| target_col | str | y | Column that contains the target. |
| unique_ids | Union | None | Time Series to plot.<br/>If None, time series are selected randomly. |
| plot_random | bool | True | Select time series to plot randomly. |
| max_ids | int | 8 | Maximum number of ids to plot. |
| models | Optional | None | list of models to plot. |
| level | Optional | None | list of prediction intervals to plot if paseed. |
| max_insample_length | Optional | None | Max number of train/insample observations to be plotted. |
| plot_anomalies | bool | False | Plot anomalies for each prediction interval. |
| engine | Literal | matplotlib | Library used to plot. ‘matplotlib’, ‘plotly’ or ‘plotly-resampler’. |
| resampler_kwargs | Optional | None | Kwargs to be passed to plotly-resampler constructor.<br/>For further custumization (“show_dash”) call the method,<br/>store the plotting object and add the extra arguments to<br/>its `show_dash` method. |
| ax | Union | None | Object where plots will be added. |
---
title: TimeGPT Excel Add-in (Beta)
description: Use TimeGPT from Microsoft Excel
icon: file
---
## Installation
Head to the [TimeGTP excel add-in page in Microsoft
Appsource](https://appsource.microsoft.com/en-us/product/office/WA200006429?tab=Overview)
and click on “Get it now”
## Usage
<Info title="Access token">
The TimeGPT Excel Add-in requires an access token. Get your API Key on
the [Nixtla Dashboard](http://dashboard.nixtla.io).
</Info>
## Support
If you have questions or need support, please email `support@nixtla.io`.
## How-to
### Settings
If this is your first time using Excel add-ins, find information on how
to add Excel add-ins with your version of Excel. In the Office Add-ins
Store, you’ll search for “TimeGPT”.
Once you have installed the TimeGPT add-in, the add-in comes up in a
sidebar task pane. \* Read through the Welcome screen. \* Click on the
**‘Get Started’** button. \* The API URL is already set to:
https://api.nixtla.io. \* Copy your API key from [Nixtla
Dashboard](http://dashboard.nixtla.io). Paste it into the box that say
**API Key, Bearer**. \* Click the gray arrow next to that box on the
right. \* You’ll get to a screen with options for ‘Forecast’ and
‘Anomaly Detection’.
To access the settings later, click the gear icon in the top left.
### Data Requirements
- Put your dates in one column and your values in another.
- Ensure your date format is recognized as a valid date by excel.
- Ensure your values are recognized as valid number by excel.
- All data inputs must exist in the same worksheet. The add-in does
not support forecasting using multiple worksheets.
- Do not include headers
Example:
| dates | values |
|:--------------|:-------|
| 12/1/16 0:00 | 72 |
| 12/1/16 1:00 | 65.8 |
| 12/1/16 2:00 | 59.99 |
| 12/1/16 3:00 | 50.69 |
| 12/1/16 4:00 | 52.58 |
| 12/1/16 5:00 | 65.05 |
| 12/1/16 6:00 | 80.4 |
| 12/1/16 7:00 | 200 |
| 12/1/16 8:00 | 200.63 |
| 12/1/16 9:00 | 155.47 |
| 12/1/16 10:00 | 150.91 |
#### Forecasting
Once you’ve configured your token and formatted your input data then
you’re all ready to forecast!
With the add-in open, configure the forecasting settings by selecting
the column for each input.
- **Frequency** - The frequency of the data (hourly / daily / weekly /
monthly)
- **Horizon** - The forecasting horizon. This represents the number of
time steps into the future that the forecast should predict.
- **Dates Range** - The column and range of the timeseries timestamps.
Must not include header data, and should be formatted as a range,
e.g. A2:A145.
- **Values Range** - The column and range of the timeseries values for
each point in time. Must not include header data, and should be
formatted as a range, e.g. B2:B145.
When you’re ready, click **Make Prediction** to generate the predicted
values. The add-in will generate a plot and append the forecasted data
to the end of the column of your existing data and highlight them in
green. So, scroll to the end of your data to see the predicted values.
#### Anomaly Detection
The requirements are the same as for the forecasting functionality, so
if you already tried it you are ready to run the anomaly detection one.
Go to the main page in the add-in and select “Anomaly Detection”, then
choose your dates and values cell ranges and click on submit. We’ll run
the model and mark the anomalies cells in yellow while adding a third
column for expected values with a green background.
---
title: "TimeGPT in R"
description: "Using TimeGPT for time series forecasting in the R programming language"
icon: "code"
---
<div className="flex justify-center">
<img src="https://github.com/Nixtla/nixtla/blob/main/nbs/img/logo_nixtlar.png?raw=true" alt="Logo for nixtlar" width="150" />
</div>
## Introduction
**TimeGPT-1**: The first foundation model for time series forecasting and anomaly detection.
The `nixtlar` package is the R interface to TimeGPT, allowing you to perform state-of-the-art time series forecasting directly from R. TimeGPT is a production-ready, generative pretrained transformer for time series forecasting, developed by Nixtla. It is capable of accurately predicting various domains such as retail, electricity, finance, and IoT, with just a few lines of code. Additionally, it can detect anomalies in time series data.
<Note>
Version 0.6.2 of nixtlar is now available on CRAN! This version introduces support for TimeGEN-1, TimeGPT optimized for Azure, along with enhanced date support, business-day frequency inference, and various bug fixes.
</Note>
## How to use
To learn how to use `nixtlar`, please refer to the
[documentation](https://nixtla.github.io/nixtlar/).
To view directly on CRAN, please use this
[link](https://cloud.r-project.org/web/packages/nixtlar/index.html).
<Note title="API key required">
The `nixtlar` package requires an API key. Get yours on the [Nixtla Dashboard](http://dashboard.nixtla.io).
</Note>
## Installation
```r
# Install nixtlar from CRAN
install.packages("nixtlar")
# Then load it
library(nixtlar)
# Set your API key
nixtla_set_api_key(api_key = "Your API key here")
```
## Quick Example
```r
# Load sample data
df <- nixtlar::electricity
head(df)
# Forecast the next 8 steps ahead
nixtla_client_fcst <- nixtla_client_forecast(df, h = 8, level = c(80,95))
# Optionally, plot the results
nixtla_client_plot(df, nixtla_client_fcst, max_insample_length = 200)
```
## Anomaly Detection Example
```r
# Detect anomalies
nixtla_client_anomalies <- nixtlar::nixtla_client_detect_anomalies(df)
# Plot with anomalies highlighted
nixtlar::nixtla_client_plot(df, nixtla_client_anomalies, plot_anomalies = TRUE)
```
## Features and Capabilities
TimeGPT through the `nixtlar` package provides:
- **Zero-shot Inference**: Generate forecasts and detect anomalies with no prior training
- **Fine-tuning**: Enhance model performance for your specific datasets
- **Add Exogenous Variables**: Incorporate additional variables like special dates or events to improve accuracy
- **Multiple Series Forecasting**: Simultaneously forecast multiple time series
- **Custom Loss Function**: Tailor the fine-tuning process with specific performance metrics
- **Cross Validation**: Implement out-of-the-box validation techniques
- **Prediction Intervals**: Quantify uncertainty in your predictions
- **Irregular Timestamps**: Handle data with non-uniform intervals
## How to Cite
If you find TimeGPT useful for your research, please consider citing:
```
Garza, A., Challu, C., & Mergenthaler-Canseco, M. (2024). TimeGPT-1.
arXiv preprint arXiv:2310.03589. Available at
https://arxiv.org/abs/2310.03589
```
## Support
If you have questions or need support, please email `support@nixtla.io`.
TimeGPT is closed source. However, this SDK is open source and available under the Apache 2.0 License.
---
title: "TimeGEN-1 Quickstart (Azure)"
description: "Quickstart guide to deploy and use TimeGEN-1 on Azure with the Nixtla Python SDK for time series forecasting."
icon: "rocket"
---
<Info>
TimeGEN-1 is TimeGPT optimized for Azure infrastructure. It is a production-ready generative pretrained transformer for time series, capable of accurately predicting domains such as retail, electricity, finance, and IoT with minimal code.
</Info>
<CardGroup cols={2}>
<Card title="Key Benefit">
Azure-native generative forecasting with TimeGEN-1 for streamlined deployments.
</Card>
<Card title="Use Cases">
• Demand forecasting\
• Electricity load prediction\
• Financial time series\
• IoT data analysis
</Card>
</CardGroup>
<Steps>
<Step title="Step 1: Set up a TimeGEN-1 endpoint on Azure and generate an API key">
1. Visit [ml.azure.com](https://ml.azure.com) and sign in (or create a Microsoft account if needed).
2. Click **Models** in the sidebar.
3. Search for **TimeGEN** in the catalog and select **TimeGEN-1**.
4. Click **Deploy** to create an endpoint.
<Frame caption="TimeGEN-1 model catalog deployment option.">
![TimeGEN-1 model catalog deployment option](https://github.com/Nixtla/nixtla/blob/main/nbs/img/azure-deploy.png?raw=true)
</Frame>
5. Click **Endpoint** in the sidebar.
6. Copy the **base URL** and **API Key** shown for your TimeGEN-1 endpoint.
<Frame caption="Endpoint URL and API key for TimeGEN-1.">
![Endpoint URL and API key](https://github.com/Nixtla/nixtla/blob/main/nbs/img/azure-endpoint.png?raw=true)
</Frame>
</Step>
<Step title="Step 2: Install Nixtla Python SDK">
Install the **nixtla** package using pip:
```shell Install nixtla SDK
pip install nixtla
```
</Step>
<Step title="Step 3: Import and instantiate the Nixtla client">
Import the Nixtla client into your Python environment:
```python Import NixtlaClient
from nixtla import NixtlaClient
```
Then create a client instance using your TimeGEN-1 endpoint credentials:
```python Instantiate NixtlaClient
nixtla_client = NixtlaClient(
base_url="YOUR_BASE_URL",
api_key="YOUR_API_KEY"
)
```
</Step>
<Step title="Step 4: Load your time series data">
In this example, we'll use the classic **AirPassengers** dataset to demonstrate forecasting. The dataset shows monthly passenger counts in Australia between 1949 and 1960.
```python Load AirPassengers dataset
import pandas as pd
df = pd.read_csv(
'https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/air_passengers.csv'
)
df.head()
```
Use the Nixtla client to quickly visualize your data:
```python Visualize time series
nixtla_client.plot(df, time_col='timestamp', target_col='value')
```
<Frame caption="AirPassengers time series sample visualized.">
![AirPassengers time series visualization](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/getting-started/22_azure_quickstart_files/figure-markdown_strict/cell-12-output-1.png)
</Frame>
<AccordionGroup>
<Accordion title="Data Requirements">
<Info>
• Ensure the target column has no missing or non-numeric values.\
• Avoid gaps in date stamps (for the specific frequency) from the initial to final timestamp—missing dates are not automatically imputed.\
• Datestamps must be in a pandas-readable format. ([See Pandas reference](https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html))
</Info>
See [Data Requirements](/data_requirements/data_requirements) for details.
</Accordion>
<Accordion title="Saving Figures">
<Check>
In most notebook environments, figures display automatically. To save a figure locally, run:
</Check>
```python Save plot figure
fig = nixtla_client.plot(df, time_col='timestamp', target_col='value')
fig.savefig('plot.png', bbox_inches='tight')
```
</Accordion>
</AccordionGroup>
</Step>
<Step title="Step 5: Generate forecasts">
Use the `forecast` method from the Nixtla client to forecast the next 12 months.
<Card title="Parameters">
• `df`: Pandas DataFrame with time series data\
• `h`: Forecast horizon (number of steps ahead)\
• `freq`: Time series frequency ([pandas frequency aliases](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases))\
• `time_col`: Name of timestamp column\
• `target_col`: Name of forecast variable
</Card>
```python Generate 12-month forecast
timegen_fcst_df = nixtla_client.forecast(
df=df,
h=12,
freq='MS',
time_col='timestamp',
target_col='value'
)
timegen_fcst_df.head()
```
<Info>
Forecast endpoint call logs will be displayed for validation and preprocessing steps.
</Info>
<Accordion title="Forecast API Call Log">
```bash Forecast API call logs
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: MS
INFO:nixtla.nixtla_client:Restricting input...
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
```
</Accordion>
Example output:
| | timestamp | TimeGPT |
| --- | ---------- | ---------- |
| 0 | 1961-01-01 | 437.837921 |
| 1 | 1961-02-01 | 426.062714 |
| 2 | 1961-03-01 | 463.116547 |
| 3 | 1961-04-01 | 478.244507 |
| 4 | 1961-05-01 | 505.646484 |
Visualize the forecast results:
```python Visualize forecast results
nixtla_client.plot(df, timegen_fcst_df, time_col='timestamp', target_col='value')
```
<Frame caption="Forecast visualization for the AirPassengers dataset.">
![Forecast visualization AirPassengers](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/getting-started/22_azure_quickstart_files/figure-markdown_strict/cell-14-output-1.png)
</Frame>
</Step>
</Steps>
\ No newline at end of file
---
title: "Docker Image for TimeGPT"
description: "Learn how to access TimeGPT via a Docker image"
icon: "docker"
---
You can deploy TimeGPT in your own local infrastructure using our provided Docker image.
This solution is ideal for enterprise customers who wish to keep their data secure and give access to TimeGPT to everyone in the organization through their own cloud provider or local infrastructure.
Benefits of using the Docker image are:
- Cloud-agnostic installation
- Full control over the server's hardware (CPU only or with GPU), maintenance and uptime
- Data is secure as per your own guidelines
The Docker image is available for entreprise customers. To request access to TimeGPT and deploy it on your own local infrastructure, [book a call with us](https://meetings.hubspot.com/cristian-challu/enterprise-contact-us?uuid=7a3723cd-153e-4901-a81c-f6cee9d6a6a3&utm_source=documentation&utm_medium=setup-docs&utm_campaign=docker-timegpt).
\ No newline at end of file
---
title: "Python Wheel for TimeGPT"
description: "Learn how to access TimeGPT via a Python wheel"
icon: "tire"
---
Using TimeGPT through API calls might not be the optimal solution for your organization, as it implies sending data to external servers.
One way of respecting data security requirements is to use a Python wheel.
We can send you a custom Python wheel for your own needs, allowing you to locally install TimeGPT. That way, you can make forecasts and perform anomaly detection locally, without the need of a server.
Benefits of using a Python wheel include:
- Local installation so there is no need of a dedicated server
- Lower latency as there is no data transfer
- Data is secure as it never leaves your local machine
The Python wheel is available for enterprise clients. To request access via a Python wheel, [book a call with us](https://meetings.hubspot.com/cristian-challu/enterprise-contact-us?uuid=7a3723cd-153e-4901-a81c-f6cee9d6a6a3&utm_source=documentation&utm_medium=setup-docs&utm_campaign=python-wheel-timegpt).
Once access is granted, we will send a Python wheel as well as all the necessary instructions to install and use TimeGPT locally.
\ No newline at end of file
---
title: "Setting up your API key"
description: "Learn how to securely configure your Nixtla SDK API key using direct code or environment variables."
icon: "key"
---
<Info>
This tutorial explains how to set up your API key when using the Nixtla SDK. It covers both quick and secure methods to configure your API key directly in code or using environment variables. If you haven't done so yet, create an API Key in your [Nixtla Dashboard](https://dashboard.nixtla.io/).
</Info>
<Frame caption="Diagram of the API Key configuration process">
![Diagram of the API Key configuration process](https://github.com/Nixtla/nixtla/blob/main/nbs/img/dashboard.png?raw=true)
</Frame>
## Overview
<CardGroup cols={2}>
<Card title="Why secure your API key?">
Your API key grants access to your Nixtla account and should be treated like a password. By securing it, you prevent unauthorized usage and protect your usage credits.
</Card>
<Card title="Where to find your key">
Your API key can be generated from your Nixtla Dashboard under the **API Keys** section. Make sure you copy the entire key with no extra spaces.
</Card>
</CardGroup>
## How to configure your API key
<Steps>
<Step title="Option 1: Copy & Paste into Python">
<Warning>
This approach is simple but not secure. Your API key will be stored in your source code, visible to anyone with access to it.
</Warning>
**Step 1:** Copy your key from the [Nixtla Dashboard](https://dashboard.nixtla.io/).
**Step 2:** Paste the key into your Python code, for example:
```python NixtlaClient Initialization with API Key
from nixtla import NixtlaClient
nixtla_client = NixtlaClient(api_key='your_api_key_here')
```
</Step>
<Step title="Option 2: Secure Method with Environment Variables">
<Info>
Storing your API key in an environment variable is the recommended approach for security and ease of sharing code without exposing credentials.
</Info>
This method requires setting an environment variable named `NIXTLA_API_KEY`. The Nixtla SDK automatically detects this environment variable without needing to manually pass it into `NixtlaClient`.
<AccordionGroup>
<Accordion title="Temporary (Terminal Session)">
<Tabs>
<Tab title="Linux / Mac">
Open your terminal and use the `export` command:
```bash Setting Environment Variable Temporarily on Linux/Mac
export NIXTLA_API_KEY=your_api_key
```
</Tab>
<Tab title="Windows (PowerShell)">
Open a PowerShell session and set the environment variable:
```powershell Setting Environment Variable Temporarily on Windows PowerShell
$env:NIXTLA_API_KEY = "your_api_key"
```
</Tab>
</Tabs>
After setting the variable, instantiate the `NixtlaClient` without specifying the key:
```python NixtlaClient Initialization Using Environment Variable
from nixtla import NixtlaClient
nixtla_client = NixtlaClient()
```
</Accordion>
<Accordion title="Permanent (.env file)">
Create a file named `.env` in the same directory as your Python script with the following content:
```env .env File Content
NIXTLA_API_KEY=your_api_key
```
Then, in your Python script, load it with the `dotenv` package:
```python Load Environment Variables with dotenv
from dotenv import load_dotenv
load_dotenv()
from nixtla import NixtlaClient
nixtla_client = NixtlaClient()
```
<Warning>
Be sure not to commit your `.env` file to public repositories. Your API key grants access to your Nixtla account.
</Warning>
</Accordion>
</AccordionGroup>
</Step>
</Steps>
## Validate your API key
Use the `validate_api_key` method of `NixtlaClient` to confirm that you have correctly configured your API key. This method returns `True` if your API key is valid, or `False` otherwise:
```python Validate API Key Method
nixtla_client.validate_api_key()
```
<Info>
You do not need to validate your API key before every request. This method is a convenience function. To fully access **TimeGPT** functionality, ensure you have adequate credits by checking your [Nixtla Dashboard](https://dashboard.nixtla.io/).
</Info>
<Card title="Summary">
You've now learned how to configure your Nixtla API key through multiple methods, ranging from the simplest copy-and-paste approach to more secure environment variable setups. Remember to keep your API key confidential to prevent unauthorized usage.
</Card>
\ No newline at end of file
@font-face {
font-family: "PPNeueMontreal";
src: url("./fonts/ppneuemontreal-medium.otf") format("otf");
}
@font-face {
font-family: "SupplyMono";
src: url("./fonts/Supply-Regular.otf") format("otf");
}
:root {
--primary-light: #fff;
--primary-dark: #161616;
--gray: #f0f0f0;
}
html,
body {
background-color: var(--gray);
font-family: "PPNeueMontreal", sans-serif;
}
.eyebrow {
font-family: "SupplyMono", monospace;
@apply text-red-300;
}
#navbar img {
height: 20px;
}
.bg-gradient-to-b {
background-color: transparent;
background-image: none;
}
a {
border-radius: 0.125rem !important;
border: 1px solid transparent;
}
a.font-semibold {
background: var(--primary-light);
border: 1px solid var(--primary-dark);
font-weight: 500;
color: var(--primary-dark);
}
a.font-semibold svg {
background: var(--primary-dark);
}
.rounded-md {
border-radius: 0.125rem !important;
}
.rounded-xl {
border-radius: 0.125rem !important;
}
.rounded-2xl,
.rounded-search {
border-radius: 0.25rem !important;
}
#navbar-transition {
background: var(--gray);
}
#topbar-cta-button a span {
background: var(--primary-dark);
border-radius: 0.125rem;
}
#content-side-layout a {
border: none;
}
#content-side-layout a.font-medium {
color: var(--primary);
font-weight: 600;
}
a.card svg {
background: var(--primary-dark);
opacity: 0.8;
}
/* Banner styling for theme support */
#banner {
/* background-color: var(--primary-light); # original */
background-color: wheat;
border-color: var(--primary-light);
color: var(--primary-dark);
border-bottom: 1px solid var(--primary-dark) !important;
}
#banner a {
color: var(--primary-dark);
}
#banner a:hover {
opacity: 0.8;
}
#banner p {
color: var(--primary-dark);
margin: 0;
font-size: medium;
}
#banner strong {
color: #000;
font-size: medium;
}
/* dark mode */
html.dark > body {
background-color: #161616;
}
html.dark #navbar-transition {
background: var(--primary-dark);
}
html.dark a.font-semibold {
background: #000;
border: 1px solid var(--gray);
outline-color: var(--gray);
color: #fff;
}
html.dark a.font-semibold svg {
background: #fff;
}
html.dark #topbar-cta-button a span {
background: #fff;
color: #000;
}
html.dark #topbar-cta-button svg {
color: #000;
}
html.dark a.card svg {
background: var(--primary-light);
}
/* Dark mode banner */
html.dark #banner {
background-color: wheat;
border-color: #000;
color: #000;
border-bottom: 1px solid #000 !important;
}
html.dark #banner a {
color: #000;
}
html.dark #banner a:hover {
opacity: 0.8;
}
html.dark #banner p {
color: #000;
font-size: medium;
}
html.dark #banner strong {
color: #000;
font-size: medium;
}
---
title: "Forecasting Bitcoin Prices"
description: "Master Bitcoin price forecasting with TimeGPT. Complete Python tutorial covering cryptocurrency prediction, anomaly detection, uncertainty quantification, and risk management strategies."
icon: "bitcoin"
---
## Introduction
[Time series forecasting](/forecasting/timegpt_quickstart) is essential in finance for trading, risk management, and strategic planning. However, predicting financial asset prices remains challenging due to market volatility.
Whether you believe financial forecasting is possible or your role requires it, [TimeGPT](/introduction/about_timegpt) simplifies the process.
This tutorial demonstrates how to use TimeGPT for Bitcoin price prediction and uncertainty quantification for risk management.
### Why Forecast Bitcoin Prices
Bitcoin (₿), the first decentralized cryptocurrency, records transactions on a blockchain. Bitcoins are mined by solving cryptographic tasks and can be used for payments, trading, or investment.
Bitcoin's volatility and popularity make price forecasting valuable for trading strategies and risk management.
### What You'll Learn
- How to load and prepare Bitcoin price data
- How to generate [short-term forecasts](/forecasting/timegpt_quickstart) with TimeGPT
- How to visualize and interpret forecast results
- How to [detect anomalies](/anomaly_detection/real-time/introduction) and add [exogenous variables](/forecasting/exogenous-variables/numeric_features)
The procedures in this tutorial apply to many [financial asset forecasting](/use_cases/forecasting_energy_demand) scenarios, not just Bitcoin.
## How to Forecast Bitcoin Prices with TimeGPT
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nixtla/nixtla/blob/main/nbs/docs/use-cases/2_bitcoin_price_prediction.ipynb)
### Step 1: Load Bitcoin Price Data
Start by loading the Bitcoin price data:
```python
import pandas as pd
# Load Bitcoin historical price data from 2020-2023
df = pd.read_csv(
'https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/bitcoin_price_usd.csv',
sep=','
)
df.head()
```
| | Date | Close |
|---|------------|--------------|
| 0 | 2020-01-01 | 7200.174316 |
| 1 | 2020-01-02 | 6985.470215 |
| 2 | 2020-01-03 | 7344.884277 |
| 3 | 2020-01-04 | 7410.656738 |
| 4 | 2020-01-05 | 7411.317383 |
This dataset includes daily Bitcoin closing prices (in USD) from 2020 to 2023. "Closing price" refers to the price at a specific daily time, not a traditional market close.
Next, rename the columns to match TimeGPT's expected `ds` (date) and `y` (target) format.
```python
# Rename columns to TimeGPT's expected format (ds=date, y=target value)
df.rename(columns={'Date': 'ds', 'Close': 'y'}, inplace=True)
```
### Step 2: Get Started with TimeGPT
Initialize the `NixtlaClient` with your Nixtla API key. To learn more about how to set up your API key, see [Setting up your API key](/setup/setting_up_your_api_key).
```python
from nixtla import NixtlaClient
# Initialize TimeGPT client with your API key
nixtla_client = NixtlaClient(
api_key='my_api_key_provided_by_nixtla'
)
```
### Step 3: Visualize the Data
Before attempting any forecasting, it is good practice to visualize the data we want to predict. The `NixtlaClient` class includes a `plot` method for this purpose.
The `plot` method has an `engine` argument that allows you to choose between different plotting libraries. Default is `matplotlib`, but you can also use `plotly` for interactive plots.
```python
# Visualize Bitcoin price history
nixtla_client.plot(df)
```
<Frame caption="Bitcoin historical price data from 2020-2023 showing price trends and volatility">
![Bitcoin historical price data from 2020-2023 showing upward trends and significant volatility patterns](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/2_bitcoin_price_prediction_files/figure-markdown_strict/cell-12-output-1.png)
</Frame>
If you did not rename the columns, specify them explicitly:
```python
nixtla_client.plot(
df,
time_col='Date Column',
target_col='Close Column'
)
```
### Step 4: Forecast with TimeGPT
Now we are ready to generate predictions with TimeGPT. To do this, we will use the `forecast` method from the `NixtlaClient` class.
The `forecast` method requires the following arguments:
- `df`: The DataFrame containing the time series data
- `h`: (int) The forecast horizon. In this case, we will forecast the next 7 days.
- `level`: (list) The confidence level for the prediction intervals. Given the inherent volatility of Bitcoin, we will use multiple confidence levels.
```python
# Generate 7-day forecast with 50%, 80%, and 90% prediction intervals
level = [50, 80, 90]
fcst = nixtla_client.forecast(
df,
h=7, # Forecast horizon: 7 days
level=level # Confidence intervals for uncertainty quantification
)
fcst.head()
```
| | ds | TimeGPT | TimeGPT-lo-90 | TimeGPT-lo-80 | TimeGPT-lo-50 | TimeGPT-hi-50 | TimeGPT-hi-80 | TimeGPT-hi-90 |
|---|------------|--------------|---------------|---------------|---------------|---------------|---------------|---------------|
| 0 | 2024-01-01 | 42269.460938 | 39567.209020 | 40429.953636 | 41380.654646 | 43158.267229 | 44108.968239 | 44971.712855 |
| 1 | 2024-01-02 | 42469.917969 | 39697.941669 | 40578.197049 | 41466.511361 | 43473.324576 | 44361.638888 | 45241.894268 |
| 2 | 2024-01-03 | 42864.078125 | 40538.871243 | 41586.252507 | 42284.316674 | 43443.839576 | 44141.903743 | 45189.285007 |
| 3 | 2024-01-04 | 42881.621094 | 40603.117448 | 41216.106493 | 42058.539392 | 43704.702795 | 44547.135694 | 45160.124739 |
| 4 | 2024-01-05 | 42773.457031 | 40213.699760 | 40665.384780 | 41489.812431 | 44057.101632 | 44881.529282 | 45333.214302 |
We can pass the forecasts we just generated to the `plot` method to visualize the predictions with the historical data.
```python
# Plot historical data with forecast and confidence intervals
nixtla_client.plot(df, fcst, level=level)
```
<Frame caption="Bitcoin price forecast with 7-day predictions and multiple confidence intervals">
![Bitcoin price forecast showing 7-day ahead predictions with 50%, 80%, and 90% confidence intervals using TimeGPT](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/2_bitcoin_price_prediction_files/figure-markdown_strict/cell-14-output-1.png)
</Frame>
To get a closer look at the predictions, we can zoom in on the plot or specify the maximum number of in-sample observations to be plotted using the `max_insample_length` argument. Note that setting `max_insample_length=60`, for instance, will display the last 60 historical values along with the complete forecast.
<Frame caption="Detailed view of Bitcoin 7-day forecast with multiple prediction intervals">
![Detailed zoom showing Bitcoin 7-day price forecast with 50%, 80%, and 90% prediction intervals for uncertainty quantification](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/2_bitcoin_price_prediction_files/figure-markdown_strict/cell-15-output-1.png)
</Frame>
### Step 5: Extend Bitcoin Price Analysis with TimeGPT
#### Anomaly Detection
Given Bitcoin's volatility, identifying anomalies can be valuable. Use TimeGPT's `detect_anomalies` method to evaluate each observation statistically within its series context. By default, it identifies anomalies using a 99% prediction interval, which you can adjust with the `level` argument.
```python
# Detect anomalies in Bitcoin price data
anomalies_df = nixtla_client.detect_anomalies(df)
# Visualize anomalies highlighted on the price chart
nixtla_client.plot(
df,
anomalies_df,
plot_anomalies=True
)
```
<Frame caption="Bitcoin price anomaly detection highlighting unusual market movements">
![Bitcoin price anomaly detection showing highlighted unusual price movements and volatility spikes identified by TimeGPT](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/2_bitcoin_price_prediction_files/figure-markdown_strict/cell-19-output-1.png)
</Frame>
To learn how to incorporate exogenous variables to TimeGPT, see [Real-time Anomaly Detection](/anomaly_detection/real-time/introduction).
#### Add Exogenous Variables
To improve forecasts, include relevant data as exogenous variables, such as other cryptocurrency prices, stock market indices, or Bitcoin network transaction volumes.
To learn how to incorporate exogenous variables to TimeGPT, see [Numeric Features Guide](/forecasting/exogenous-variables/numeric_features).
## Understand the Model Limitations
As stated in the introduction, predicting Bitcoin prices is challenging. The predictions here may appear accurate because they use recent data and update frequently, but the real test is forecasting future prices, not historical performance.
For those who need or want to try to forecast these assets, `TimeGPT` can be an option that simplifies the forecasting process. With just a couple of lines of code, `TimeGPT` can help you:
- Produce point forecasts
- Quantify the uncertainty of your predictions
- Produce in-sample forecasts
- Detect anomalies
- Incorporate exogenous variables
To learn more about TimeGPT capabilities, see the [TimeGPT Introduction](/introduction/introduction).
## Conclusion
TimeGPT simplifies Bitcoin price forecasting by providing:
- Accurate short-term predictions with quantified uncertainty
- Automated anomaly detection for risk management
- Support for exogenous variables to improve forecast accuracy
This approach applies to various cryptocurrency and financial asset forecasting scenarios, helping traders and analysts make data-driven decisions despite market volatility.
### Next Steps
- Explore [energy demand forecasting](/use_cases/forecasting_energy_demand) with TimeGPT
- Learn about [cross-validation](/forecasting/evaluation/cross_validation) for model evaluation
- Understand [fine-tuning](/forecasting/fine-tuning/steps) for improved accuracy
- Scale forecasts with [distributed computing](/forecasting/forecasting-at-scale/computing_at_scale)
## References and Additional Material
- [Joaquín Amat Rodrigo and Javier Escobar Ortiz (2022), "Bitcoin price prediction with Python, when the past does not repeat itself"](https://www.cienciadedatos.net/documentos/py41-forecasting-cryptocurrency-bitcoin-machine-learning-python.html)
---
title: "Forecasting Energy Demand"
description: "Energy demand forecasting tutorial using TimeGPT AI. Step-by-step Python guide for electricity consumption prediction with 90% faster predictions and superior accuracy."
icon: "bolt"
---
## Introduction
Energy demand forecasting is critical for grid operations, resource allocation, and infrastructure planning. Despite advances in methods, predicting consumption remains challenging due to weather, economic activity, and consumer behavior.
This tutorial demonstrates how TimeGPT simplifies in-zone electricity forecasting while delivering superior accuracy and speed. We will use the [PJM Hourly Energy Consumption dataset](https://www.pjm.com/) covering five regions from October 2023 to September 2024.
### What You'll Learn
- How to load and prepare energy consumption data
- How to generate 4-day ahead forecasts with TimeGPT
- How to evaluate forecast accuracy using MAE and sMAPE
- How TimeGPT compares to deep learning models like N-HiTS
The procedures in this tutorial apply to many time series forecasting scenarios beyond energy demand.
## How to Use TimeGPT to Forecast Energy Demand
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nixtla/nixtla/blob/main/nbs/docs/use-cases/3_electricity_demand.ipynb)
### Step 1: Initial Setup
Install and import required packages, then create a NixtlaClient instance to interact with TimeGPT.
```python
import time
import requests
import pandas as pd
from nixtla import NixtlaClient
from utilsforecast.losses import mae, smape
from utilsforecast.evaluation import evaluate
nixtla_client = NixtlaClient(
api_key='my_api_key_provided_by_nixtla' # Defaults to os.environ.get("NIXTLA_API_KEY")
)
```
### Step 2: Load Energy Consumption Data
Load the energy consumption dataset and convert datetime strings to timestamps.
```python
df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/refs/heads/main/datasets/pjm_in_zone.csv')
df['ds'] = pd.to_datetime(df['ds'])
# Examine the dataset
df.groupby('unique_id').head(2)
```
| | unique_id | ds | y |
| ----- | ----------- | --------------------------- | ---------- |
| 0 | AP-AP | 2023-10-01 04:00:00+00:00 | 4042.513 |
| 1 | AP-AP | 2023-10-01 05:00:00+00:00 | 3850.067 |
Plot the data series to visualize seasonal patterns.
```python
nixtla_client.plot(
df,
max_insample_length=365
)
```
<Frame caption="Seasonal patterns in energy consumption showing daily and weekly cycles in PJM electricity demand data">
![Seasonal patterns in energy consumption showing daily and weekly cycles in PJM electricity demand data](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/3_electricity_demand_files/figure-markdown_strict/cell-12-output-1.png)
</Frame>
### Step 3: Generate Energy Demand Forecasts with TimeGPT
We'll split our dataset into:
- A training/input set for model calibration
- A testing set (last 4 days) to validate performance
```python
# Prepare test (last 4 days) and input data
test_df = df.groupby('unique_id').tail(96)
input_df = df.groupby('unique_id').apply(lambda group: group.iloc[-1104:-96]).reset_index(drop=True)
# Make forecasts
start = time.time()
fcst_df = nixtla_client.forecast(
df=input_df,
h=96,
level=[90],
finetune_steps=10,
finetune_loss='mae',
model='timegpt-1-long-horizon',
time_col='ds',
target_col='y',
id_col='unique_id'
)
end = time.time()
timegpt_duration = end - start
print(f"Time (TimeGPT): {timegpt_duration}")
# Visualize forecasts against actual values
nixtla_client.plot(
test_df,
fcst_df,
models=['TimeGPT'],
level=[90],
time_col='ds',
target_col='y'
)
```
<Frame caption="TimeGPT energy demand forecast with 90% confidence intervals compared to actual electricity consumption">
![TimeGPT energy demand forecast with 90% confidence intervals compared to actual electricity consumption](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/3_electricity_demand_files/figure-markdown_strict/cell-15-output-1.png)
</Frame>
### Step 4: Evaluate Forecast Accuracy
Compute accuracy metrics (MAE and sMAPE) for TimeGPT.
```python
fcst_df['ds'] = pd.to_datetime(fcst_df['ds'])
test_df = pd.merge(test_df, fcst_df, 'left', ['unique_id', 'ds'])
evaluation = evaluate(test_df, [mae, smape], ["TimeGPT"], "y", "unique_id")
average_metrics = evaluation.groupby('metric')['TimeGPT'].mean()
average_metrics
```
### Step 5: Forecast with N-HiTS
For comparison, we train and forecast using the deep-learning model N-HiTS.
```python
from neuralforecast.core import NeuralForecast
from neuralforecast.models import NHITS
# Prepare training dataset by excluding the last 4 days
train_df = df.groupby('unique_id').apply(lambda group: group.iloc[:-96]).reset_index(drop=True)
models = [
NHITS(h=96, input_size=480, scaler_type='robust', batch_size=16, valid_batch_size=8)
]
nf = NeuralForecast(models=models, freq='H')
start = time.time()
nf.fit(df=train_df)
nhits_preds = nf.predict()
end = time.time()
print(f"Time (N-HiTS): {end - start}")
```
### Step 6: Evaluate N-HiTS
Compute accuracy metrics (MAE and sMAPE) for N-HiTS.
```python
preds_df = pd.merge(test_df, nhits_preds, 'left', ['unique_id', 'ds'])
evaluation = evaluate(preds_df, [mae, smape], ["NHITS"], "y", "unique_id")
average_metrics = evaluation.groupby('metric')['NHITS'].mean()
print(average_metrics)
```
## Conclusion
TimeGPT demonstrates substantial performance improvements over N-HiTS across key metrics:
- **Accuracy**: 18.6% lower MAE (882.6 vs 1084.7)
- **Error Rate**: 31.1% lower sMAPE
- **Speed**: 90% faster predictions (4.3 seconds vs 44 seconds)
These results make TimeGPT a powerful tool for forecasting energy consumption and other time-series tasks where both accuracy and speed are critical.
Experiment with the parameters to further optimize performance for your specific use case.
## Related Tutorials
Ready to explore more forecasting applications? Check out these guides:
- [Bitcoin Price Prediction with TimeGPT](/use_cases/bitcoin_price_prediction) - Financial time series forecasting
- [Exogenous Variables Guide](/forecasting/exogenous-variables/numeric_features) - Improve forecasts with external data
- [Long Horizon Forecasting](/forecasting/model-version/longhorizon_model) - Extended forecast periods
Learn more about [TimeGPT capabilities](/introduction/introduction) for time series prediction.
\ No newline at end of file
---
title: "Forecasting Intermittent Demand"
description: "Master intermittent demand forecasting with TimeGPT for inventory optimization. Achieve 14% better accuracy than specialized models using the M5 dataset with exogenous variables and log transforms."
icon: "box"
---
## Introduction
Intermittent demand occurs when products or services have irregular purchase patterns with frequent zero-value periods. This is common in retail, spare parts inventory, and specialty products where demand is irregular rather than continuous.
Forecasting these patterns accurately is essential for optimizing stock levels, reducing costs, and preventing stockouts. [TimeGPT](/introduction/about_timegpt) excels at intermittent demand forecasting by capturing complex patterns that traditional statistical methods miss.
This tutorial demonstrates TimeGPT's capabilities using the M5 dataset of food sales, including [exogenous variables](/forecasting/exogenous-variables/numeric_features) like pricing and promotional events that influence purchasing behavior.
### What You'll Learn
- How to prepare and analyze intermittent demand data
- How to leverage exogenous variables for better predictions
- How to use log transforms to ensure realistic forecasts
- How TimeGPT compares to specialized intermittent demand models
The methods shown here apply broadly to inventory management and retail forecasting challenges. For getting started with TimeGPT, see our [quickstart guide](/forecasting/timegpt_quickstart).
## How to Use TimeGPT to Forecast Intermittent Demand
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nixtla/nixtla/blob/main/nbs/docs/use-cases/4_intermittent_demand.ipynb)
### Step 1: Environment Setup
Start by importing the required packages for this tutorial and create an instance of `NixtlaClient`.
```python
import pandas as pd
import numpy as np
from nixtla import NixtlaClient
from utilsforecast.losses import mae
from utilsforecast.evaluation import evaluate
nixtla_client = NixtlaClient(api_key='my_api_key_provided_by_nixtla')
```
### Step 2: Load and Visualize the Dataset
Load the dataset from the M5 dataset and convert the `ds` column to a datetime object:
```python
df = pd.read_csv("https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/m5_sales_exog_small.csv")
df['ds'] = pd.to_datetime(df['ds'])
df.head()
```
| unique_id | ds | y | sell_price | event_type_Cultural | event_type_National | event_type_Religious | event_type_Sporting |
|-----------|------------|---|------------|---------------------|---------------------|----------------------|---------------------|
| FOODS_1_001 | 2011-01-29 | 3 | 2.0 | 0 | 0 | 0 | 0 |
| FOODS_1_001 | 2011-01-30 | 0 | 2.0 | 0 | 0 | 0 | 0 |
| FOODS_1_001 | 2011-01-31 | 0 | 2.0 | 0 | 0 | 0 | 0 |
| FOODS_1_001 | 2011-02-01 | 1 | 2.0 | 0 | 0 | 0 | 0 |
| FOODS_1_001 | 2011-02-02 | 4 | 2.0 | 0 | 0 | 0 | 0 |
Visualize the dataset using the `plot` method:
```python
nixtla_client.plot(
df,
max_insample_length=365,
)
```
<Frame caption="Figure 1: Visualization of intermittent demand data">
![Dataset Plot](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/4_intermittent_demand_files/figure-markdown_strict/cell-11-output-1.png)
</Frame>
In the figure above, we can see the intermittent nature of this dataset, with many periods with zero demand.
Now, let's use TimeGPT to forecast the demand of each product.
### Step 3: Transform the Data
To avoid getting negative predictions coming from the model, we use a log transformation on the data. That way, the model will be forced to predict only positive values.
Note that due to the presence of zeros in our dataset, we add one to all points before taking the log.
```python
df_transformed = df.copy()
df_transformed['y'] = np.log(df_transformed['y'] + 1)
```
Now, let's keep the last 28 time steps for the test set and use the rest as input to the model.
```python
test_df = df_transformed.groupby('unique_id').tail(28)
input_df = df_transformed.drop(test_df.index).reset_index(drop=True)
```
### Step 4: Forecast with TimeGPT
Forecast with TimeGPT using the `forecast` method:
```python
fcst_df = nixtla_client.forecast(
df=input_df,
h=28,
level=[80],
finetune_steps=10, # Learn more about fine-tuning: /forecasting/fine-tuning/steps
finetune_loss='mae',
model='timegpt-1-long-horizon', # For long-horizon forecasting: /forecasting/model-version/longhorizon_model
time_col='ds',
target_col='y',
id_col='unique_id'
)
```
```bash
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: D
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
```
Great! We now have predictions. However, those predictions are transformed, so we need to inverse the transformation to get back to the original scale. Therefore, we take the exponential and subtract one from each data point.
```python
cols = [col for col in fcst_df.columns if col not in ['ds', 'unique_id']]
fcst_df[cols] = np.exp(fcst_df[cols]) - 1
fcst_df.head()
```
| | unique_id | ds | TimeGPT | TimeGPT-lo-80 | TimeGPT-hi-80 |
|---|-------------|------------|----------|---------------|---------------|
| 0 | FOODS_1_001 | 2016-05-23 | 0.286841 | -0.267101 | 1.259465 |
| 1 | FOODS_1_001 | 2016-05-24 | 0.320482 | -0.241236 | 1.298046 |
| 2 | FOODS_1_001 | 2016-05-25 | 0.287392 | -0.362250 | 1.598791 |
| 3 | FOODS_1_001 | 2016-05-26 | 0.295326 | -0.145489 | 0.963542 |
| 4 | FOODS_1_001 | 2016-05-27 | 0.315868 | -0.166516 | 1.077437 |
### Step 5: Evaluate the Forecasts
Before measuring the performance metric, let's plot the predictions against the actual values.
```python
nixtla_client.plot(
test_df,
fcst_df,
models=['TimeGPT'],
level=[80],
time_col='ds',
target_col='y'
)
```
<Frame caption="Figure 2: Visualization of the predictions against the actual values">
![Predictions vs Actual Values](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/4_intermittent_demand_files/figure-markdown_strict/cell-16-output-1.png)
</Frame>
Finally, we can measure the mean absolute error (MAE) of the model. Learn more about [evaluation metrics](/forecasting/evaluation/evaluation_metrics) in our documentation.
```python
# Compute MAE
test_df = pd.merge(test_df, fcst_df, how='left', on=['unique_id', 'ds'])
evaluation = evaluate(
test_df,
metrics=[mae],
models=['TimeGPT'],
target_col='y',
id_col='unique_id'
)
average_metrics = evaluation.groupby('metric')['TimeGPT'].mean()
average_metrics
```
```bash
metric
mae 0.492559
```
### Step 6: Compare with Statistical Models
The library `statsforecast` by Nixtla provides a suite of statistical models specifically built for intermittent forecasting, such as Croston, IMAPA and TSB. Let's use these models and see how they perform against TimeGPT.
```python
from statsforecast import StatsForecast
from statsforecast.models import CrostonClassic, CrostonOptimized, IMAPA, TSB
sf = StatsForecast(
models=[CrostonClassic(), CrostonOptimized(), IMAPA(), TSB(0.1, 0.1)],
freq='D',
n_jobs=-1
)
```
Then, we can fit the models on our data.
```python
sf.fit(df=input_df)
sf_preds = sf.predict(h=28)
```
Again, we need to inverse the transformation. Remember that the training data was previously transformed using the log function.
```python
cols = [col for col in sf_preds.columns if col not in ['ds', 'unique_id']]
sf_preds[cols] = np.exp(sf_preds[cols]) - 1
sf_preds.head()
```
| | unique_id | ds | CrostonClassic | CrostonOptimized | IMAPA | TSB |
|---|-------------|------------|---------------|-----------------|-------|-----|
| 0 | FOODS_1_001 | 2016-05-23 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 1 | FOODS_1_001 | 2016-05-24 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 2 | FOODS_1_001 | 2016-05-25 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 3 | FOODS_1_001 | 2016-05-26 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 4 | FOODS_1_001 | 2016-05-27 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
Now, let's combine the predictions from all methods and see which performs best.
```python
test_df = pd.merge(test_df, sf_preds, 'left', ['unique_id', 'ds'])
test_df.head()
```
| | unique_id | ds | y | sell_price | event_type_Cultural | event_type_National | event_type_Religious | event_type_Sporting | TimeGPT | TimeGPT-lo-80 | TimeGPT-hi-80 | CrostonClassic | CrostonOptimized | IMAPA | TSB |
|---|-------------|------------|---|------------|---------------------|---------------------|----------------------|---------------------|---------|---------------|---------------|---------------|-----------------|-------|-----|
| 0 | FOODS_1_001 | 2016-05-23 | 1.386294 | 2.24 | 0 | 0 | 0 | 0 | 0.286841 | -0.267101 | 1.259465 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 1 | FOODS_1_001 | 2016-05-24 | 0.000000 | 2.24 | 0 | 0 | 0 | 0 | 0.320482 | -0.241236 | 1.298046 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 2 | FOODS_1_001 | 2016-05-25 | 0.000000 | 2.24 | 0 | 0 | 0 | 0 | 0.287392 | -0.362250 | 1.598791 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 3 | FOODS_1_001 | 2016-05-26 | 0.000000 | 2.24 | 0 | 0 | 0 | 0 | 0.295326 | -0.145489 | 0.963542 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
| 4 | FOODS_1_001 | 2016-05-27 | 1.945910 | 2.24 | 0 | 0 | 0 | 0 | 0.315868 | -0.166516 | 1.077437 | 0.599093 | 0.599093 | 0.445779 | 0.396258 |
```python
statistical_models = ["CrostonClassic", "CrostonOptimized", "IMAPA", "TSB"]
evaluation = evaluate(
test_df,
metrics=[mae],
models=["TimeGPT"] + statistical_models,
target_col="y",
id_col='unique_id'
)
average_metrics = evaluation.groupby('metric')[[
"TimeGPT"] + statistical_models].mean()
average_metrics
```
| metric | TimeGPT | CrostonClassic | CrostonOptimized | IMAPA | TSB |
|--------|----------|----------------|------------------|----------|----------|
| mae | 0.492559 | 0.564563 | 0.580922 | 0.571943 | 0.567178 |
In the table above, we can see that TimeGPT achieves the lowest MAE, achieving a 12.8% improvement over the best performing statistical model.
These results demonstrate TimeGPT's strong performance without additional features. We can further improve accuracy by incorporating exogenous variables, a capability TimeGPT supports but traditional statistical models do not.
### Step 7: Use Exogenous Variables
To forecast with [exogenous variables](/forecasting/exogenous-variables/numeric_features), we need to specify their future values over the forecast horizon. Therefore, let's simply take the types of events, as those dates are known in advance. You can also explore using [date features](/forecasting/exogenous-variables/date_features) and [holidays](/forecasting/exogenous-variables/holiday_and_special_dates) as exogenous variables.
```python
# Include holiday/event data as exogenous features
exog_cols = ['event_type_Cultural', 'event_type_National', 'event_type_Religious', 'event_type_Sporting']
futr_exog_df = test_df[['unique_id', 'ds'] + exog_cols]
futr_exog_df.head()
```
| | unique_id | ds | event_type_Cultural | event_type_National | event_type_Religious | event_type_Sporting |
|---|-------------|------------|---------------------|---------------------|----------------------|---------------------|
| 0 | FOODS_1_001 | 2016-05-23 | 0 | 0 | 0 | 0 |
| 1 | FOODS_1_001 | 2016-05-24 | 0 | 0 | 0 | 0 |
| 2 | FOODS_1_001 | 2016-05-25 | 0 | 0 | 0 | 0 |
| 3 | FOODS_1_001 | 2016-05-26 | 0 | 0 | 0 | 0 |
| 4 | FOODS_1_001 | 2016-05-27 | 0 | 0 | 0 | 0 |
Then, we simply call the `forecast` method and pass the `futr_exog_df` in the `X_df` parameter.
```python
fcst_df = nixtla_client.forecast(
df=input_df,
X_df=futr_exog_df,
h=28,
level=[80], # Generate a 80% confidence interval
finetune_steps=10, # Specify the number of steps for fine-tuning
finetune_loss='mae', # Use the MAE as the loss function for fine-tuning
model='timegpt-1-long-horizon', # Use the model for long-horizon forecasting
time_col='ds',
target_col='y',
id_col='unique_id'
)
```
```bash
INFO:nixtla.nixtla_client:Validating inputs...
INFO:nixtla.nixtla_client:Preprocessing dataframes...
INFO:nixtla.nixtla_client:Inferred freq: D
INFO:nixtla.nixtla_client:Using the following exogenous variables: event_type_Cultural, event_type_National, event_type_Religious, event_type_Sporting
INFO:nixtla.nixtla_client:Calling Forecast Endpoint...
```
Great! Remember that the predictions are transformed, so we have to inverse the transformation again.
```python
fcst_df.rename(columns={'TimeGPT': 'TimeGPT_ex'}, inplace=True)
cols = [col for col in fcst_df.columns if col not in ['ds', 'unique_id']]
fcst_df[cols] = np.exp(fcst_df[cols]) - 1
fcst_df.head()
```
| | unique_id | ds | TimeGPT_ex | TimeGPT-lo-80 | TimeGPT-hi-80 |
|---|-------------|------------|------------|---------------|---------------|
| 0 | FOODS_1_001 | 2016-05-23 | 0.281922 | -0.269902 | 1.250828 |
| 1 | FOODS_1_001 | 2016-05-24 | 0.313774 | -0.245091 | 1.286372 |
| 2 | FOODS_1_001 | 2016-05-25 | 0.285639 | -0.363119 | 1.595252 |
| 3 | FOODS_1_001 | 2016-05-26 | 0.295037 | -0.145679 | 0.963104 |
| 4 | FOODS_1_001 | 2016-05-27 | 0.315484 | -0.166760 | 1.076830 |
Finally, let's evaluate the performance of TimeGPT with exogenous features.
```python
test_df['TimeGPT_ex'] = fcst_df['TimeGPT_ex'].values
test_df.head()
```
| | unique_id | ds | y | sell_price | event_type_Cultural | event_type_National | event_type_Religious | event_type_Sporting | TimeGPT | TimeGPT-lo-80 | TimeGPT-hi-80 | CrostonClassic | CrostonOptimized | IMAPA | TSB | TimeGPT_ex |
|---|-------------|------------|---|------------|---------------------|---------------------|----------------------|---------------------|---------|---------------|---------------|---------------|-----------------|-------|-----|------------|
| 0 | FOODS_1_001 | 2016-05-23 | 1.386294 | 2.24 | 0 | 0 | 0 | 0 | 0.286841 | -0.267101 | 1.259465 | 0.599093 | 0.599093 | 0.445779 | 0.396258 | 0.281922 |
| 1 | FOODS_1_001 | 2016-05-24 | 0.000000 | 2.24 | 0 | 0 | 0 | 0 | 0.320482 | -0.241236 | 1.298046 | 0.599093 | 0.599093 | 0.445779 | 0.396258 | 0.313774 |
| 2 | FOODS_1_001 | 2016-05-25 | 0.000000 | 2.24 | 0 | 0 | 0 | 0 | 0.287392 | -0.362250 | 1.598791 | 0.599093 | 0.599093 | 0.445779 | 0.396258 | 0.285639 |
| 3 | FOODS_1_001 | 2016-05-26 | 0.000000 | 2.24 | 0 | 0 | 0 | 0 | 0.295326 | -0.145489 | 0.963542 | 0.599093 | 0.599093 | 0.445779 | 0.396258 | 0.295037 |
| 4 | FOODS_1_001 | 2016-05-27 | 1.945910 | 2.24 | 0 | 0 | 0 | 0 | 0.315868 | -0.166516 | 1.077437 | 0.599093 | 0.599093 | 0.445779 | 0.396258 | 0.315484 |
```python
evaluation = evaluate(
test_df,
metrics=[mae],
models=["TimeGPT"] + statistical_models + ["TimeGPT_ex"],
target_col="y",
id_col='unique_id'
)
average_metrics = (
evaluation.groupby('metric')[["TimeGPT"] + statistical_models + ["TimeGPT_ex"]]
).mean()
average_metrics
```
| metric | TimeGPT | CrostonClassic | CrostonOptimized | IMAPA | TSB | TimeGPT_ex |
|--------|----------|----------------|------------------|----------|----------|------------|
|mae | 0.492559 | 0.564563 | 0.580922 | 0.571943 | 0.567178 | 0.485352 |
From the table above, we can see that using exogenous features improved the performance of TimeGPT. Now, it represents a 14% improvement over the best statistical model.
## Conclusion
TimeGPT provides a robust solution for forecasting intermittent demand:
- ~14% MAE improvement over specialized models
- Supports exogenous features for enhanced accuracy
By leveraging TimeGPT and combining both internal series patterns and external factors, organizations can achieve more reliable forecasts even for challenging intermittent demands.
### Next Steps
- Explore [other use cases](/use_cases/forecasting_energy_demand) with TimeGPT
- Learn about [probabilistic forecasting](/forecasting/probabilistic/introduction) with prediction intervals
- Scale your forecasts with [distributed computing](/forecasting/forecasting-at-scale/computing_at_scale)
- Fine-tune models with [custom loss functions](/forecasting/fine-tuning/custom_loss)
\ No newline at end of file
---
title: "Forecasting Web Traffic"
description: "Learn how to predict website traffic patterns using TimeGPT."
icon: "globe"
---
<Info>
**Goal:** Forecast the next 7 days of daily visits to the website [cienciadedatos.net](https://cienciadedatos.net) using TimeGPT.
</Info>
This tutorial is adapted from *"Forecasting web traffic with machine learning and Python"* by Joaquín Amat Rodrigo and Javier Escobar Ortiz. You will learn how to:
<CardGroup cols={3}>
<Card title="Improve Accuracy">
Obtain forecasts nearly 10% more accurate than the original method.
</Card>
<Card title="Reduce Complexity">
Use significantly fewer lines of code and simpler workflows.
</Card>
<Card title="Save Time">
Generate forecasts in substantially less computation time.
</Card>
</CardGroup>
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nixtla/nixtla/blob/main/nbs/docs/use-cases/1_forecasting_web_traffic.ipynb)
<Steps>
<Step title="1. Import Packages and Initialize Client">
To start, import the required packages and initialize the Nixtla client with your API key.
```python Nixtla Client Initialization
import pandas as pd
from nixtla import NixtlaClient
nixtla_client = NixtlaClient(
api_key='my_api_key_provided_by_nixtla' # Defaults to os.environ.get("NIXTLA_API_KEY")
)
```
<Check>
**Use an Azure AI endpoint**
<br />
If you are using an Azure AI endpoint, also set the `base_url` argument:
```python Azure AI Endpoint Setup
nixtla_client = NixtlaClient(
base_url="your_azure_ai_endpoint",
api_key="your_api_key"
)
```
</Check>
</Step>
<Step title="2. Load Data">
We will load the website visit data directly from a CSV file. Then, we format the dataset by adding an identifier column named `daily_visits`.
```python Load and Format Data
url = (
'https://raw.githubusercontent.com/JoaquinAmatRodrigo/Estadistica-machine-learning-python/'
'master/data/visitas_por_dia_web_cienciadedatos.csv'
)
df = pd.read_csv(url, sep=',', parse_dates=[0], date_format='%d/%m/%y')
df['unique_id'] = 'daily_visits'
df.head(10)
```
<AccordionGroup>
<Accordion title="Data Preview (first 10 rows)">
| | date | users | unique_id |
| ----- | ------------ | ------- | -------------- |
| 0 | 2020-07-01 | 2324 | daily_visits |
| 1 | 2020-07-02 | 2201 | daily_visits |
| 2 | 2020-07-03 | 2146 | daily_visits |
| 3 | 2020-07-04 | 1666 | daily_visits |
| 4 | 2020-07-05 | 1433 | daily_visits |
| 5 | 2020-07-06 | 2195 | daily_visits |
| 6 | 2020-07-07 | 2240 | daily_visits |
| 7 | 2020-07-08 | 2295 | daily_visits |
| 8 | 2020-07-09 | 2279 | daily_visits |
| 9 | 2020-07-10 | 2155 | daily_visits |
</Accordion>
</AccordionGroup>
<Info>
**Note:** No further preprocessing is required before we start forecasting.
</Info>
</Step>
<Step title="3. Cross-Validation with TimeGPT">
We will set up a rolling window cross-validation using TimeGPT. This will help us evaluate the forecast accuracy across multiple historic windows.
```python Cross-validation Setup
timegpt_cv_df = nixtla_client.cross_validation(
df,
h=7,
n_windows=8,
time_col='date',
target_col='users',
freq='D',
level=[80, 90, 99.5]
)
timegpt_cv_df.head()
```
<Frame caption="Cross-validation forecast plot">
![CV Plot](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/1_forecasting_web_traffic_files/figure-markdown_strict/cell-12-output-1.png)
</Frame>
The results align closely with those from the original tutorial on [forecasting web traffic with machine learning](https://cienciadedatos.net/documentos/py37-forecasting-web-traffic-machine-learning.html).
Next, we compute the Mean Absolute Error (MAE) to quantify forecast accuracy:
```python Calculate MAE
from utilsforecast.losses import mae
mae_timegpt = mae(
df=timegpt_cv_df.drop(columns=['cutoff']),
models=['TimeGPT'],
target_col='users'
)
mae_timegpt
```
<Info>
**MAE Result:** The MAE obtained is `167.69`, outperforming the original pipeline.
</Info>
</Step>
<Step title="4. Adding Exogenous Variables (Weekday Indicators)">
Exogenous variables can provide additional context that may improve forecast accuracy. In this example, we add binary indicators for each day of the week.
```python Add Weekday Indicators
for i in range(7):
df[f'week_day_{i + 1}'] = 1 * (df['date'].dt.weekday == i)
df.head(10)
```
We repeat the cross-validation with these new features:
```python Cross-validation with Exogenous Variables
timegpt_cv_df_with_ex = nixtla_client.cross_validation(
df,
h=7,
n_windows=8,
time_col='date',
target_col='users',
freq='D',
level=[80, 90, 99.5]
)
```
<Frame caption="Forecast with Exogenous Variables">
![Exogenous CV Plot](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/1_forecasting_web_traffic_files/figure-markdown_strict/cell-17-output-1.png)
</Frame>
<Info>
Adding weekday indicators can capture weekly seasonality in user visits.
</Info>
</Step>
<Step title="5. Comparing Results">
<Card title="Results">
| **Model** | **Exogenous features** | **MAE Backtest**|
| --------- | -------------------- | -------------- |
| TimeGPT | No | 167.6917 |
| TimeGPT | Yes | 167.2286 |
</Card>
We see a slight improvement in MAE by including the weekday indicators. This illustrates how TimeGPT can incorporate additional signals without complex data processing or extensive model tuning.
</Step>
<Step title="6. Final Thoughts">
<Check>
**Key Takeaways**
- TimeGPT simplifies forecasting workflows by reducing code and tuning overhead.
- Feature engineering (like adding weekday variables) further boosts accuracy.
- Cross-validation provides a robust way to evaluate model performance.
</Check>
We have demonstrated significant improvements in forecasting accuracy with minimal effort using TimeGPT. This avoids the majority of the complex steps required when building custom models—such as extensive feature engineering, validation, model comparisons, and hyperparameter tuning.
**Good luck and happy forecasting!**
</Step>
</Steps>
\ No newline at end of file
---
title: "What-If Forecasting: Price Effects in Retail"
description: "Master what-if forecasting with TimeGPT for retail pricing optimization. Learn scenario analysis to predict demand changes from price adjustments using the M5 dataset. Step-by-step Python tutorial."
icon: "store"
---
## Introduction
Pricing decisions significantly impact retail demand. [TimeGPT](/introduction/about_timegpt) makes it possible to forecast product demand while incorporating price as a key factor, enabling retailers to evaluate how different pricing scenarios might affect sales. This approach offers valuable insights for strategic pricing decisions.
This tutorial demonstrates how to use TimeGPT for scenario analysis by forecasting demand under various pricing conditions. You'll learn to incorporate price data into forecasts and compare different pricing strategies to understand their impact on consumer demand.
### What You'll Learn
- How to forecast retail demand using price as an [exogenous variable](/forecasting/exogenous-variables/numeric_features)
- How to run what-if scenarios with different pricing strategies
- How to compare baseline, increased, and decreased price forecasts
- How to interpret price sensitivity in demand forecasts
## How to Forecast Sales with Pricing Scenarios
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nixtla/nixtla/blob/main/nbs/docs/use-cases/5_what_if_pricing_scenarios_in_retail.ipynb)
### Step 1: Import required packages
Import the packages needed for this tutorial and initialize your Nixtla client:
```python
import pandas as pd
import os
from nixtla import NixtlaClient
```
Initialize the Nixtla client:
```python
nixtla_client = NixtlaClient(
api_key='my_api_key_provided_by_nixtla'
)
```
### Step 2: Load the M5 dataset
Let's see an example on predicting sales of products of the [M5 dataset](https://nixtlaverse.nixtla.io/datasetsforecast/m5.html). The M5 dataset contains daily product demand (sales) for 10 retail stores in the US.
First, we load the data using `datasetsforecast`. This returns:
- `Y_df`, containing the sales (`y` column), for each unique product (`unique_id` column) at every timestamp (`ds` column).
- `X_df`, containing additional relevant information for each unique product (`unique_id` column) at every timestamp (`ds` column).
```python
from datasetsforecast.m5 import M5
Y_df, X_df, S_df = M5.load(directory=os.getcwd())
Y_df.head(10)
```
| unique_id | ds | y |
|-----------|------------|-----|
| FOODS_1_001_CA_1 | 2011-01-29 | 3.0 |
| FOODS_1_001_CA_1 | 2011-01-30 | 0.0 |
| FOODS_1_001_CA_1 | 2011-01-31 | 0.0 |
| FOODS_1_001_CA_1 | 2011-02-01 | 1.0 |
| FOODS_1_001_CA_1 | 2011-02-02 | 4.0 |
| FOODS_1_001_CA_1 | 2011-02-03 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-04 | 0.0 |
| FOODS_1_001_CA_1 | 2011-02-05 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-06 | 0.0 |
| FOODS_1_001_CA_1 | 2011-02-07 | 0.0 |
For this example, we will only keep the additional relevant information from the column `sell_price`. This column shows the selling price of the product, and we expect demand to fluctuate given a different selling price.
```python
X_df = X_df[['unique_id', 'ds', 'sell_price']]
X_df.head(10)
```
| unique_id | ds | sell_price |
|-----------|------------|------------|
| FOODS_1_001_CA_1 | 2011-01-29 | 2.0 |
| FOODS_1_001_CA_1 | 2011-01-30 | 2.0 |
| FOODS_1_001_CA_1 | 2011-01-31 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-01 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-02 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-03 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-04 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-05 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-06 | 2.0 |
| FOODS_1_001_CA_1 | 2011-02-07 | 2.0 |
### Step 3: Forecast demand using price as an exogenous variable
In this example, we forecast for a single product (`FOODS_1_129_`) across all 10 stores. This product exhibits frequent price changes, making it ideal for modeling price effects on demand. Learn more about using [exogenous variables in TimeGPT](/forecasting/exogenous-variables/numeric_features).
```python
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')
```
Merge the sales (`y`) and price (`sell_price`) data into one DataFrame:
```python
df = Y_df_product.merge(X_df_product)
df.head(10)
```
| unique_id | ds | y | sell_price |
|-----------|------------|-----|------------|
| FOODS_1_129_CA_1 | 2011-02-01 | 1.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-02 | 0.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-03 | 0.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-04 | 0.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-05 | 1.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-06 | 0.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-07 | 0.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-08 | 0.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-09 | 0.0 | 6.22 |
| FOODS_1_129_CA_1 | 2011-02-10 | 3.0 | 6.22 |
Let's investigate how the demand, our target `y`, of these products has evolved in the last year of data.
```python
nixtla_client.plot(df, unique_ids=products, max_insample_length=365)
```
<Frame caption="Historical retail demand showing intermittent sales patterns across 10 stores">
![Historical retail demand showing intermittent sales patterns across 10 stores for FOODS_1_129 product](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/5_what_if_pricing_scenarios_in_retail_files/figure-markdown_strict/cell-15-output-1.png)
</Frame>
We see that in the California stores (with a CA_ suffix), the product has sold intermittently, whereas in the other regions (TX and WY) sales where less intermittent. Note that the plot only shows 8 (out of 10) stores.
Next, we look at the `sell_price` of these products across the entire data available.
```python
nixtla_client.plot(df, unique_ids=products, target_col='sell_price')
```
<Frame caption="Historical pricing trends showing price changes over 5 years for retail products">
![Historical pricing trends showing approximately 20 price changes from 2011 to 2016 for retail products](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/5_what_if_pricing_scenarios_in_retail_files/figure-markdown_strict/cell-16-output-1.png)
</Frame>
We find that there have been relatively few price changes (about 20 in total) over the period 2011 to 2016.
Let's turn to our forecasting task. We will forecast the last 28 days in the dataset.
To use the `sell_price` exogenous variable in TimeGPT, we have to add it as future values. Therefore, we create a future values dataframe, that contains the `unique_id`, the timestamp `ds`, and `sell_price`.
```python
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_id | ds | sell_price |
|-----------|------------|------------|
| FOODS_1_129_CA_1 | 2016-05-23 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-24 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-25 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-26 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-27 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-28 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-29 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-30 | 5.74 |
| FOODS_1_129_CA_1 | 2016-05-31 | 5.74 |
| FOODS_1_129_CA_1 | 2016-06-01 | 5.74 |
Next, we limit our input dataframe to all but the 28 forecast days:
```python
df_train = df.query("ds < '2016-05-23'")
df_train.tail(10)
```
| unique_id | ds | y | sell_price |
|-----------|------------|-----|------------|
| FOODS_1_129_WI_3 | 2016-05-13 | 3.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-14 | 1.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-15 | 2.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-16 | 3.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-17 | 1.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-18 | 2.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-19 | 3.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-20 | 1.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-21 | 0.0 | 7.23 |
| FOODS_1_129_WI_3 | 2016-05-22 | 0.0 | 7.23 |
Now, we can generate forecasts using TimeGPT (28 days ahead):
```python
timegpt_fcst_df = nixtla_client.forecast(
df=df_train,
X_df=future_ex_vars_df,
h=28
)
timegpt_fcst_df.head()
```
| unique_id | ds | TimeGPT |
|-----------|------------|------------|
| FOODS_1_129_CA_1 | 2016-05-23 | 0.875594 |
| FOODS_1_129_CA_1 | 2016-05-24 | 0.777731 |
| FOODS_1_129_CA_1 | 2016-05-25 | 0.786871 |
| FOODS_1_129_CA_1 | 2016-05-26 | 0.828223 |
| FOODS_1_129_CA_1 | 2016-05-27 | 0.791228 |
We plot the forecast, the actuals and the last 28 days before the forecast period:
```python
nixtla_client.plot(
df[['unique_id', 'ds', 'y']],
timegpt_fcst_df,
max_insample_length=56
)
```
<Frame caption="TimeGPT baseline forecast with 28-day ahead predictions for retail demand">
![TimeGPT baseline forecast showing actual demand and 28-day ahead predictions for retail products](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/5_what_if_pricing_scenarios_in_retail_files/figure-markdown_strict/cell-20-output-1.png)
</Frame>
### Step 4: What-If Scenario Forecasting with Price Changes
What happens when we change the price of the products in our forecast period? Let's see how our forecast changes when we increase and decrease the `sell_price` by 5%.
```python
price_change = 0.05
future_ex_vars_df_plus = future_ex_vars_df.copy()
future_ex_vars_df_plus["sell_price"] *= (1 + price_change)
future_ex_vars_df_minus = future_ex_vars_df.copy()
future_ex_vars_df_minus["sell_price"] *= (1 - price_change)
```
Let's create a new set of forecasts with TimeGPT.
```python
timegpt_fcst_df_plus = nixtla_client.forecast(df_train, future_ex_vars_df_plus, h=28)
timegpt_fcst_df_minus = nixtla_client.forecast(df_train, future_ex_vars_df_minus, h=28)
```
Rename and combine the scenario forecasts:
```python
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_id | ds | TimeGPT | TimeGPT-sell_price_plus_5% | TimeGPT-sell_price_minus_5% |
|-----------|------------|------------|------------|------------|
| FOODS_1_129_CA_1 | 2016-05-23 | 0.875594 | 0.847006 | 1.370029 |
| FOODS_1_129_CA_1 | 2016-05-24 | 0.777731 | 0.749142 | 1.272166 |
| FOODS_1_129_CA_1 | 2016-05-25 | 0.786871 | 0.758283 | 1.281306 |
| FOODS_1_129_CA_1 | 2016-05-26 | 0.828223 | 0.799635 | 1.322658 |
| FOODS_1_129_CA_1 | 2016-05-27 | 0.791228 | 0.762640 | 1.285663 |
| FOODS_1_129_CA_1 | 2016-05-28 | 0.819133 | 0.790545 | 1.313568 |
| FOODS_1_129_CA_1 | 2016-05-29 | 0.839992 | 0.811404 | 1.334427 |
| FOODS_1_129_CA_1 | 2016-05-30 | 0.843070 | 0.814481 | 1.337505 |
| FOODS_1_129_CA_1 | 2016-05-31 | 0.833089 | 0.804500 | 1.327524 |
| FOODS_1_129_CA_1 | 2016-06-01 | 0.855032 | 0.826443 | 1.349467 |
As expected, demand increases when we reduce the price and decreases when we increase it. A cheaper product leads to higher sales and vice versa.
Finally, let's plot the forecasts for our different pricing scenarios, showing how TimeGPT forecasts a different demand when the price of a set of products is changed.
```python
nixtla_client.plot(
df[['unique_id', 'ds', 'y']],
timegpt_fcst_df,
max_insample_length=56
)
```
<Frame caption="What-if scenario comparison showing demand forecasts under different pricing strategies">
![What-if scenario comparison: baseline, +5% price increase, and -5% price decrease demand forecasts](https://raw.githubusercontent.com/Nixtla/nixtla/readme_docs/nbs/_docs/docs/use-cases/5_what_if_pricing_scenarios_in_retail_files/figure-markdown_strict/cell-24-output-1.png)
</Frame>
In the graphs we can see that for specific products for certain periods the discount increases expected demand, while during other periods and for other products, price change has a smaller effect on total demand.
## Conclusion
What-if forecasting with TimeGPT enables data-driven pricing decisions by:
- Modeling demand sensitivity to price changes
- Comparing multiple pricing scenarios simultaneously
- Incorporating exogenous variables for realistic predictions
This scenario analysis approach helps retailers optimize pricing strategies and maximize revenue while understanding demand elasticity.
### Next Steps
- Explore [intermittent demand forecasting](/use_cases/forecasting_intermittent_demand) with TimeGPT
- Learn about [fine-tuning models](/forecasting/fine-tuning/steps) for better accuracy
- Understand [cross-validation](/forecasting/evaluation/cross_validation) for model evaluation
- Scale forecasts with [distributed computing](/forecasting/forecasting-at-scale/computing_at_scale)
### Important Considerations
- This method assumes that historical demand and price behaviour is predictive of future demand, and omits other factors affecting demand. To include these other factors, use additional exogenous variables that provide the model with more context about the factors influencing demand.
- This method is sensitive to unmodelled events that affect the demand, such as sudden market shifts. To include those, use additional exogenous variables indicating such sudden shifts if they have been observed in the past too.
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment