Commit e3f7f7b3 authored by chenzk's avatar chenzk
Browse files

v1.0

parents
Pipeline #956 failed with stages
in 0 seconds
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "4a93f115",
"metadata": {},
"outputs": [],
"source": [
"#| default_exp common._scalers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5c704dc1",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "markdown",
"id": "83d112c7-18f8-4f20-acad-34e6de54cebf",
"metadata": {},
"source": [
"# TemporalNorm\n",
"\n",
"> Temporal normalization has proven to be essential in neural forecasting tasks, as it enables network's non-linearities to express themselves. Forecasting scaling methods take particular interest in the temporal dimension where most of the variance dwells, contrary to other deep learning techniques like `BatchNorm` that normalizes across batch and temporal dimensions, and `LayerNorm` that normalizes across the feature dimension. Currently we support the following techniques: `std`, `median`, `norm`, `norm1`, `invariant`, `revin`."
]
},
{
"cell_type": "markdown",
"id": "fee5e60b-f53b-44ff-9ace-1f5def7b601d",
"metadata": {},
"source": [
"## References"
]
},
{
"cell_type": "markdown",
"id": "f9211dd2-99a4-4d67-90cb-bb1f7851685e",
"metadata": {},
"source": [
"* [Kin G. Olivares, David Luo, Cristian Challu, Stefania La Vattiata, Max Mergenthaler, Artur Dubrawski (2023). \"HINT: Hierarchical Mixture Networks For Coherent Probabilistic Forecasting\". Neural Information Processing Systems, submitted. Working Paper version available at arxiv.](https://arxiv.org/abs/2305.07089)\n",
"* [Taesung Kim and Jinhee Kim and Yunwon Tae and Cheonbok Park and Jang-Ho Choi and Jaegul Choo. \"Reversible Instance Normalization for Accurate Time-Series Forecasting against Distribution Shift\". ICLR 2022.](https://openreview.net/pdf?id=cGDAkQo1C0p)\n",
"* [David Salinas, Valentin Flunkert, Jan Gasthaus, Tim Januschowski (2020). \"DeepAR: Probabilistic forecasting with autoregressive recurrent networks\". International Journal of Forecasting.](https://www.sciencedirect.com/science/article/pii/S0169207019301888)"
]
},
{
"cell_type": "markdown",
"id": "9319296d",
"metadata": {},
"source": [
"![Figure 1. Illustration of temporal normalization (left), layer normalization (center) and batch normalization (right). The entries in green show the components used to compute the normalizing statistics.](imgs_models/temporal_norm.png)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "df2cc55a",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"import torch\n",
"import torch.nn as nn"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0f08562b-88d8-4e92-aeeb-bc9bc4c61ab7",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"from nbdev.showdoc import show_doc\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5201e067-f7c0-4ca3-89a7-d879001b1908",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"plt.rcParams[\"axes.grid\"]=True\n",
"plt.rcParams['font.family'] = 'serif'\n",
"plt.rcParams[\"figure.figsize\"] = (4,2)"
]
},
{
"cell_type": "markdown",
"id": "ef461e9c",
"metadata": {},
"source": [
"# 1. Auxiliary Functions"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "12a249a3",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def masked_median(x, mask, dim=-1, keepdim=True):\n",
" \"\"\" Masked Median\n",
"\n",
" Compute the median of tensor `x` along dim, ignoring values where \n",
" `mask` is False. `x` and `mask` need to be broadcastable.\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor to compute median of along `dim` dimension.<br>\n",
" `mask`: torch Tensor bool with same shape as `x`, where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `dim` (int, optional): Dimension to take median of. Defaults to -1.<br>\n",
" `keepdim` (bool, optional): Keep dimension of `x` or not. Defaults to True.<br>\n",
"\n",
" **Returns:**<br>\n",
" `x_median`: torch.Tensor with normalized values.\n",
" \"\"\"\n",
" x_nan = x.float().masked_fill(mask<1, float(\"nan\"))\n",
" x_median, _ = x_nan.nanmedian(dim=dim, keepdim=keepdim)\n",
" x_median = torch.nan_to_num(x_median, nan=0.0)\n",
" return x_median\n",
"\n",
"def masked_mean(x, mask, dim=-1, keepdim=True):\n",
" \"\"\" Masked Mean\n",
"\n",
" Compute the mean of tensor `x` along dimension, ignoring values where \n",
" `mask` is False. `x` and `mask` need to be broadcastable.\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor to compute mean of along `dim` dimension.<br>\n",
" `mask`: torch Tensor bool with same shape as `x`, where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `dim` (int, optional): Dimension to take mean of. Defaults to -1.<br>\n",
" `keepdim` (bool, optional): Keep dimension of `x` or not. Defaults to True.<br>\n",
"\n",
" **Returns:**<br>\n",
" `x_mean`: torch.Tensor with normalized values.\n",
" \"\"\"\n",
" x_nan = x.float().masked_fill(mask<1, float(\"nan\"))\n",
" x_mean = x_nan.nanmean(dim=dim, keepdim=keepdim)\n",
" x_mean = torch.nan_to_num(x_mean, nan=0.0)\n",
" return x_mean"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "49d2e338",
"metadata": {},
"outputs": [],
"source": [
"show_doc(masked_median, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "300e1b4c",
"metadata": {},
"outputs": [],
"source": [
"show_doc(masked_mean, title_level=3)"
]
},
{
"cell_type": "markdown",
"id": "a7a486a2",
"metadata": {},
"source": [
"# 2. Scalers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "42c76dab",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def minmax_statistics(x, mask, eps=1e-6, dim=-1):\n",
" \"\"\" MinMax Scaler\n",
"\n",
" Standardizes temporal features by ensuring its range dweels between\n",
" [0,1] range. This transformation is often used as an alternative \n",
" to the standard scaler. The scaled features are obtained as:\n",
"\n",
" $$\n",
" \\mathbf{z} = (\\mathbf{x}_{[B,T,C]}-\\mathrm{min}({\\mathbf{x}})_{[B,1,C]})/\n",
" (\\mathrm{max}({\\mathbf{x}})_{[B,1,C]}- \\mathrm{min}({\\mathbf{x}})_{[B,1,C]})\n",
" $$\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor input tensor.<br>\n",
" `mask`: torch Tensor bool, same dimension as `x`, indicates where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `eps` (float, optional): Small value to avoid division by zero. Defaults to 1e-6.<br>\n",
" `dim` (int, optional): Dimension over to compute min and max. Defaults to -1.<br>\n",
"\n",
" **Returns:**<br>\n",
" `z`: torch.Tensor same shape as `x`, except scaled.\n",
" \"\"\"\n",
" mask = mask.clone()\n",
" mask[mask==0] = torch.inf\n",
" mask[mask==1] = 0\n",
" x_max = torch.max(torch.nan_to_num(x-mask,nan=-torch.inf), dim=dim, keepdim=True)[0]\n",
" x_min = torch.min(torch.nan_to_num(x+mask,nan=torch.inf), dim=dim, keepdim=True)[0]\n",
" x_max = x_max.type(x.dtype)\n",
" x_min = x_min.type(x.dtype)\n",
"\n",
" # x_range and prevent division by zero\n",
" x_range = x_max - x_min\n",
" x_range[x_range==0] = 1.0\n",
" x_range = x_range + eps\n",
" return x_min, x_range"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39fa429b",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"def minmax_scaler(x, x_min, x_range):\n",
" return (x - x_min) / x_range\n",
"\n",
"def inv_minmax_scaler(z, x_min, x_range):\n",
" return z * x_range + x_min"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "99ea1aa9",
"metadata": {},
"outputs": [],
"source": [
"show_doc(minmax_statistics, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "334b3d18",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def minmax1_statistics(x, mask, eps=1e-6, dim=-1):\n",
" \"\"\" MinMax1 Scaler\n",
"\n",
" Standardizes temporal features by ensuring its range dweels between\n",
" [-1,1] range. This transformation is often used as an alternative \n",
" to the standard scaler or classic Min Max Scaler. \n",
" The scaled features are obtained as:\n",
"\n",
" $$\\mathbf{z} = 2 (\\mathbf{x}_{[B,T,C]}-\\mathrm{min}({\\mathbf{x}})_{[B,1,C]})/ (\\mathrm{max}({\\mathbf{x}})_{[B,1,C]}- \\mathrm{min}({\\mathbf{x}})_{[B,1,C]})-1$$\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor input tensor.<br>\n",
" `mask`: torch Tensor bool, same dimension as `x`, indicates where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `eps` (float, optional): Small value to avoid division by zero. Defaults to 1e-6.<br>\n",
" `dim` (int, optional): Dimension over to compute min and max. Defaults to -1.<br>\n",
"\n",
" **Returns:**<br>\n",
" `z`: torch.Tensor same shape as `x`, except scaled.\n",
" \"\"\"\n",
" # Mask values (set masked to -inf or +inf)\n",
" mask = mask.clone()\n",
" mask[mask==0] = torch.inf\n",
" mask[mask==1] = 0\n",
" x_max = torch.max(torch.nan_to_num(x-mask,nan=-torch.inf), dim=dim, keepdim=True)[0]\n",
" x_min = torch.min(torch.nan_to_num(x+mask,nan=torch.inf), dim=dim, keepdim=True)[0]\n",
" x_max = x_max.type(x.dtype)\n",
" x_min = x_min.type(x.dtype)\n",
" \n",
" # x_range and prevent division by zero\n",
" x_range = x_max - x_min\n",
" x_range[x_range==0] = 1.0\n",
" x_range = x_range + eps\n",
" return x_min, x_range"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a19ed5a8",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"def minmax1_scaler(x, x_min, x_range):\n",
" x = (x - x_min) / x_range\n",
" z = x * (2) - 1\n",
" return z\n",
"\n",
"def inv_minmax1_scaler(z, x_min, x_range):\n",
" z = (z + 1) / 2\n",
" return z * x_range + x_min"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "88ccb77b",
"metadata": {},
"outputs": [],
"source": [
"show_doc(minmax1_statistics, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0c187a8f",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def std_statistics(x, mask, dim=-1, eps=1e-6):\n",
" \"\"\" Standard Scaler\n",
"\n",
" Standardizes features by removing the mean and scaling\n",
" to unit variance along the `dim` dimension. \n",
"\n",
" For example, for `base_windows` models, the scaled features are obtained as (with dim=1):\n",
"\n",
" $$\\mathbf{z} = (\\mathbf{x}_{[B,T,C]}-\\\\bar{\\mathbf{x}}_{[B,1,C]})/\\hat{\\sigma}_{[B,1,C]}$$\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor.<br>\n",
" `mask`: torch Tensor bool, same dimension as `x`, indicates where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `eps` (float, optional): Small value to avoid division by zero. Defaults to 1e-6.<br>\n",
" `dim` (int, optional): Dimension over to compute mean and std. Defaults to -1.<br>\n",
"\n",
" **Returns:**<br>\n",
" `z`: torch.Tensor same shape as `x`, except scaled.\n",
" \"\"\"\n",
" x_means = masked_mean(x=x, mask=mask, dim=dim)\n",
" x_stds = torch.sqrt(masked_mean(x=(x-x_means)**2, mask=mask, dim=dim))\n",
"\n",
" # Protect against division by zero\n",
" x_stds[x_stds==0] = 1.0\n",
" x_stds = x_stds + eps\n",
" return x_means, x_stds"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "17f90821",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"def std_scaler(x, x_means, x_stds):\n",
" return (x - x_means) / x_stds\n",
"\n",
"def inv_std_scaler(z, x_mean, x_std):\n",
" return (z * x_std) + x_mean"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e077730c",
"metadata": {},
"outputs": [],
"source": [
"show_doc(std_statistics, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2c22a041",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def robust_statistics(x, mask, dim=-1, eps=1e-6):\n",
" \"\"\" Robust Median Scaler\n",
"\n",
" Standardizes features by removing the median and scaling\n",
" with the mean absolute deviation (mad) a robust estimator of variance.\n",
" This scaler is particularly useful with noisy data where outliers can \n",
" heavily influence the sample mean / variance in a negative way.\n",
" In these scenarios the median and amd give better results.\n",
" \n",
" For example, for `base_windows` models, the scaled features are obtained as (with dim=1):\n",
"\n",
" $$\\mathbf{z} = (\\mathbf{x}_{[B,T,C]}-\\\\textrm{median}(\\mathbf{x})_{[B,1,C]})/\\\\textrm{mad}(\\mathbf{x})_{[B,1,C]}$$\n",
" \n",
" $$\\\\textrm{mad}(\\mathbf{x}) = \\\\frac{1}{N} \\sum_{}|\\mathbf{x} - \\mathrm{median}(x)|$$\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor input tensor.<br>\n",
" `mask`: torch Tensor bool, same dimension as `x`, indicates where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `eps` (float, optional): Small value to avoid division by zero. Defaults to 1e-6.<br>\n",
" `dim` (int, optional): Dimension over to compute median and mad. Defaults to -1.<br>\n",
"\n",
" **Returns:**<br>\n",
" `z`: torch.Tensor same shape as `x`, except scaled.\n",
" \"\"\"\n",
" x_median = masked_median(x=x, mask=mask, dim=dim)\n",
" x_mad = masked_median(x=torch.abs(x-x_median), mask=mask, dim=dim)\n",
"\n",
" # Protect x_mad=0 values\n",
" # Assuming normality and relationship between mad and std\n",
" x_means = masked_mean(x=x, mask=mask, dim=dim)\n",
" x_stds = torch.sqrt(masked_mean(x=(x-x_means)**2, mask=mask, dim=dim)) \n",
" x_mad_aux = x_stds * 0.6744897501960817\n",
" x_mad = x_mad * (x_mad>0) + x_mad_aux * (x_mad==0)\n",
" \n",
" # Protect against division by zero\n",
" x_mad[x_mad==0] = 1.0\n",
" x_mad = x_mad + eps\n",
" return x_median, x_mad"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "33f3cf28",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"def robust_scaler(x, x_median, x_mad):\n",
" return (x - x_median) / x_mad\n",
"\n",
"def inv_robust_scaler(z, x_median, x_mad):\n",
" return z * x_mad + x_median"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7355a5f9",
"metadata": {},
"outputs": [],
"source": [
"show_doc(robust_statistics, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8879b00b",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def invariant_statistics(x, mask, dim=-1, eps=1e-6):\n",
" \"\"\" Invariant Median Scaler\n",
"\n",
" Standardizes features by removing the median and scaling\n",
" with the mean absolute deviation (mad) a robust estimator of variance.\n",
" Aditionally it complements the transformation with the arcsinh transformation.\n",
"\n",
" For example, for `base_windows` models, the scaled features are obtained as (with dim=1):\n",
"\n",
" $$\\mathbf{z} = (\\mathbf{x}_{[B,T,C]}-\\\\textrm{median}(\\mathbf{x})_{[B,1,C]})/\\\\textrm{mad}(\\mathbf{x})_{[B,1,C]}$$\n",
"\n",
" $$\\mathbf{z} = \\\\textrm{arcsinh}(\\mathbf{z})$$\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor input tensor.<br>\n",
" `mask`: torch Tensor bool, same dimension as `x`, indicates where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `eps` (float, optional): Small value to avoid division by zero. Defaults to 1e-6.<br>\n",
" `dim` (int, optional): Dimension over to compute median and mad. Defaults to -1.<br>\n",
"\n",
" **Returns:**<br>\n",
" `z`: torch.Tensor same shape as `x`, except scaled.\n",
" \"\"\"\n",
" x_median = masked_median(x=x, mask=mask, dim=dim)\n",
" x_mad = masked_median(x=torch.abs(x-x_median), mask=mask, dim=dim)\n",
"\n",
" # Protect x_mad=0 values\n",
" # Assuming normality and relationship between mad and std\n",
" x_means = masked_mean(x=x, mask=mask, dim=dim)\n",
" x_stds = torch.sqrt(masked_mean(x=(x-x_means)**2, mask=mask, dim=dim)) \n",
" x_mad_aux = x_stds * 0.6744897501960817\n",
" x_mad = x_mad * (x_mad>0) + x_mad_aux * (x_mad==0)\n",
"\n",
" # Protect against division by zero\n",
" x_mad[x_mad==0] = 1.0\n",
" x_mad = x_mad + eps\n",
" return x_median, x_mad"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "24cca2bf",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"def invariant_scaler(x, x_median, x_mad):\n",
" return torch.arcsinh((x - x_median) / x_mad)\n",
"\n",
"def inv_invariant_scaler(z, x_median, x_mad):\n",
" return torch.sinh(z) * x_mad + x_median"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f4b1b313",
"metadata": {},
"outputs": [],
"source": [
"show_doc(invariant_statistics, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "50ba1916",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def identity_statistics(x, mask, dim=-1, eps=1e-6):\n",
" \"\"\" Identity Scaler\n",
"\n",
" A placeholder identity scaler, that is argument insensitive.\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor input tensor.<br>\n",
" `mask`: torch Tensor bool, same dimension as `x`, indicates where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
" `eps` (float, optional): Small value to avoid division by zero. Defaults to 1e-6.<br>\n",
" `dim` (int, optional): Dimension over to compute median and mad. Defaults to -1.<br>\n",
"\n",
" **Returns:**<br>\n",
" `x`: original torch.Tensor `x`.\n",
" \"\"\"\n",
" # Collapse dim dimension\n",
" shape = list(x.shape)\n",
" shape[dim] = 1\n",
"\n",
" x_shift = torch.zeros(shape)\n",
" x_scale = torch.ones(shape)\n",
"\n",
" return x_shift, x_scale"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1d7b313e",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"def identity_scaler(x, x_shift, x_scale):\n",
" return x\n",
"\n",
"def inv_identity_scaler(z, x_shift, x_scale):\n",
" return z"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e56ae8f7",
"metadata": {},
"outputs": [],
"source": [
"show_doc(identity_statistics, title_level=3)"
]
},
{
"cell_type": "markdown",
"id": "e87e828c",
"metadata": {},
"source": [
"# 3. TemporalNorm Module"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb48423b",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"class TemporalNorm(nn.Module):\n",
" \"\"\" Temporal Normalization\n",
"\n",
" Standardization of the features is a common requirement for many \n",
" machine learning estimators, and it is commonly achieved by removing \n",
" the level and scaling its variance. The `TemporalNorm` module applies \n",
" temporal normalization over the batch of inputs as defined by the type of scaler.\n",
"\n",
" $$\\mathbf{z}_{[B,T,C]} = \\\\textrm{Scaler}(\\mathbf{x}_{[B,T,C]})$$\n",
"\n",
" If `scaler_type` is `revin` learnable normalization parameters are added on top of\n",
" the usual normalization technique, the parameters are learned through scale decouple\n",
" global skip connections. The technique is available for point and probabilistic outputs.\n",
"\n",
" $$\\mathbf{\\hat{z}}_{[B,T,C]} = \\\\boldsymbol{\\hat{\\\\gamma}}_{[1,1,C]} \\mathbf{z}_{[B,T,C]} +\\\\boldsymbol{\\hat{\\\\beta}}_{[1,1,C]}$$\n",
"\n",
" **Parameters:**<br>\n",
" `scaler_type`: str, defines the type of scaler used by TemporalNorm. Available [`identity`, `standard`, `robust`, `minmax`, `minmax1`, `invariant`, `revin`].<br>\n",
" `dim` (int, optional): Dimension over to compute scale and shift. Defaults to -1.<br>\n",
" `eps` (float, optional): Small value to avoid division by zero. Defaults to 1e-6.<br>\n",
" `num_features`: int=None, for RevIN-like learnable affine parameters initialization.<br>\n",
"\n",
" **References**<br>\n",
" - [Kin G. Olivares, David Luo, Cristian Challu, Stefania La Vattiata, Max Mergenthaler, Artur Dubrawski (2023). \"HINT: Hierarchical Mixture Networks For Coherent Probabilistic Forecasting\". Neural Information Processing Systems, submitted. Working Paper version available at arxiv.](https://arxiv.org/abs/2305.07089)<br>\n",
" \"\"\"\n",
" def __init__(self, scaler_type='robust', dim=-1, eps=1e-6, num_features=None):\n",
" super().__init__()\n",
" compute_statistics = {None: identity_statistics,\n",
" 'identity': identity_statistics,\n",
" 'standard': std_statistics,\n",
" 'revin': std_statistics,\n",
" 'robust': robust_statistics,\n",
" 'minmax': minmax_statistics,\n",
" 'minmax1': minmax1_statistics,\n",
" 'invariant': invariant_statistics,}\n",
" scalers = {None: identity_scaler,\n",
" 'identity': identity_scaler,\n",
" 'standard': std_scaler,\n",
" 'revin': std_scaler,\n",
" 'robust': robust_scaler,\n",
" 'minmax': minmax_scaler,\n",
" 'minmax1': minmax1_scaler,\n",
" 'invariant':invariant_scaler,}\n",
" inverse_scalers = {None: inv_identity_scaler,\n",
" 'identity': inv_identity_scaler,\n",
" 'standard': inv_std_scaler,\n",
" 'revin': inv_std_scaler,\n",
" 'robust': inv_robust_scaler,\n",
" 'minmax': inv_minmax_scaler,\n",
" 'minmax1': inv_minmax1_scaler,\n",
" 'invariant': inv_invariant_scaler,}\n",
" assert (scaler_type in scalers.keys()), f'{scaler_type} not defined'\n",
" if (scaler_type=='revin') and (num_features is None):\n",
" raise Exception('You must pass num_features for ReVIN scaler.')\n",
"\n",
" self.compute_statistics = compute_statistics[scaler_type]\n",
" self.scaler = scalers[scaler_type]\n",
" self.inverse_scaler = inverse_scalers[scaler_type]\n",
" self.scaler_type = scaler_type\n",
" self.dim = dim\n",
" self.eps = eps\n",
"\n",
" if (scaler_type=='revin'):\n",
" self._init_params(num_features=num_features)\n",
"\n",
" def _init_params(self, num_features):\n",
" # Initialize RevIN scaler params to broadcast:\n",
" if self.dim==1: # [B,T,C] [1,1,C]\n",
" self.revin_bias = nn.Parameter(torch.zeros(1,1,num_features))\n",
" self.revin_weight = nn.Parameter(torch.ones(1,1,num_features))\n",
" elif self.dim==-1: # [B,C,T] [1,C,1]\n",
" self.revin_bias = nn.Parameter(torch.zeros(1,num_features,1))\n",
" self.revin_weight = nn.Parameter(torch.ones(1,num_features,1))\n",
"\n",
" #@torch.no_grad()\n",
" def transform(self, x, mask):\n",
" \"\"\" Center and scale the data.\n",
"\n",
" **Parameters:**<br>\n",
" `x`: torch.Tensor shape [batch, time, channels].<br>\n",
" `mask`: torch Tensor bool, shape [batch, time] where `x` is valid and False\n",
" where `x` should be masked. Mask should not be all False in any column of\n",
" dimension dim to avoid NaNs from zero division.<br>\n",
"\n",
" **Returns:**<br>\n",
" `z`: torch.Tensor same shape as `x`, except scaled.\n",
" \"\"\"\n",
" x_shift, x_scale = self.compute_statistics(x=x, mask=mask, dim=self.dim, eps=self.eps)\n",
" self.x_shift = x_shift\n",
" self.x_scale = x_scale\n",
"\n",
" # Original Revin performs this operation\n",
" # z = self.revin_weight * z\n",
" # z = z + self.revin_bias\n",
" # However this is only valid for point forecast not for\n",
" # distribution's scale decouple technique.\n",
" if self.scaler_type=='revin':\n",
" self.x_shift = self.x_shift + self.revin_bias\n",
" self.x_scale = self.x_scale * (torch.relu(self.revin_weight) + self.eps)\n",
"\n",
" z = self.scaler(x, x_shift, x_scale)\n",
" return z\n",
"\n",
" #@torch.no_grad()\n",
" def inverse_transform(self, z, x_shift=None, x_scale=None):\n",
" \"\"\" Scale back the data to the original representation.\n",
"\n",
" **Parameters:**<br>\n",
" `z`: torch.Tensor shape [batch, time, channels], scaled.<br>\n",
"\n",
" **Returns:**<br>\n",
" `x`: torch.Tensor original data.\n",
" \"\"\"\n",
"\n",
" if x_shift is None:\n",
" x_shift = self.x_shift\n",
" if x_scale is None:\n",
" x_scale = self.x_scale\n",
"\n",
" # Original Revin performs this operation\n",
" # z = z - self.revin_bias\n",
" # z = (z / (self.revin_weight + self.eps))\n",
" # However this is only valid for point forecast not for\n",
" # distribution's scale decouple technique.\n",
"\n",
" x = self.inverse_scaler(z, x_shift, x_scale)\n",
" return x\n",
"\n",
" def forward(self, x):\n",
" # The gradients are optained from BaseWindows/BaseRecurrent forwards.\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "91d7a892",
"metadata": {},
"outputs": [],
"source": [
"show_doc(TemporalNorm, name='TemporalNorm', title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3490b4a6",
"metadata": {},
"outputs": [],
"source": [
"show_doc(TemporalNorm.transform, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "df49d4f5",
"metadata": {},
"outputs": [],
"source": [
"show_doc(TemporalNorm.inverse_transform, title_level=3)"
]
},
{
"cell_type": "markdown",
"id": "3e2968e0",
"metadata": {},
"source": [
"# Example"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "99722125",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c7fef46f",
"metadata": {},
"outputs": [],
"source": [
"# Declare synthetic batch to normalize\n",
"x1 = 10**0 * np.arange(36)[:, None]\n",
"x2 = 10**1 * np.arange(36)[:, None]\n",
"\n",
"np_x = np.concatenate([x1, x2], axis=1)\n",
"np_x = np.repeat(np_x[None, :,:], repeats=2, axis=0)\n",
"np_x[0,:,:] = np_x[0,:,:] + 100\n",
"\n",
"np_mask = np.ones(np_x.shape)\n",
"np_mask[:, -12:, :] = 0\n",
"\n",
"print(f'x.shape [batch, time, features]={np_x.shape}')\n",
"print(f'mask.shape [batch, time, features]={np_mask.shape}')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da1f93ae",
"metadata": {},
"outputs": [],
"source": [
"# Validate scalers\n",
"x = 1.0*torch.tensor(np_x)\n",
"mask = torch.tensor(np_mask)\n",
"scaler = TemporalNorm(scaler_type='standard', dim=1)\n",
"x_scaled = scaler.transform(x=x, mask=mask)\n",
"x_recovered = scaler.inverse_transform(x_scaled)\n",
"\n",
"plt.plot(x[0,:,0], label='x1', color='#78ACA8')\n",
"plt.plot(x[0,:,1], label='x2', color='#E3A39A')\n",
"plt.title('Before TemporalNorm')\n",
"plt.xlabel('Time')\n",
"plt.legend()\n",
"plt.show()\n",
"\n",
"plt.plot(x_scaled[0,:,0], label='x1', color='#78ACA8')\n",
"plt.plot(x_scaled[0,:,1]+0.1, label='x2+0.1', color='#E3A39A')\n",
"plt.title(f'TemporalNorm \\'{scaler.scaler_type}\\' ')\n",
"plt.xlabel('Time')\n",
"plt.legend()\n",
"plt.show()\n",
"\n",
"plt.plot(x_recovered[0,:,0], label='x1', color='#78ACA8')\n",
"plt.plot(x_recovered[0,:,1], label='x2', color='#E3A39A')\n",
"plt.title('Recovered')\n",
"plt.xlabel('Time')\n",
"plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9aa6920e",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Validate scalers\n",
"for scaler_type in [None, 'identity', 'standard', 'robust', 'minmax', 'minmax1', 'invariant', 'revin']:\n",
" x = 1.0*torch.tensor(np_x)\n",
" mask = torch.tensor(np_mask)\n",
" scaler = TemporalNorm(scaler_type=scaler_type, dim=1, num_features=np_x.shape[-1])\n",
" x_scaled = scaler.transform(x=x, mask=mask)\n",
" x_recovered = scaler.inverse_transform(x_scaled)\n",
" assert torch.allclose(x, x_recovered, atol=1e-3), f'Recovered data is not the same as original with {scaler_type}'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "17e3dbfc-2677-4d1f-85bc-de6343196045",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"import pandas as pd\n",
"\n",
"from neuralforecast import NeuralForecast\n",
"from neuralforecast.models import NHITS\n",
"from neuralforecast.utils import AirPassengersDF as Y_df"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "28e5f23d-9a64-4d77-8a27-55fcc765d0b7",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Unit test for masked predict filtering\n",
"model = NHITS(h=12,\n",
" input_size=12*2,\n",
" max_steps=1,\n",
" windows_batch_size=None, \n",
" n_freq_downsample=[1,1,1],\n",
" scaler_type='minmax')\n",
"\n",
"nf = NeuralForecast(models=[model], freq='M')\n",
"nf.fit(df=Y_df)\n",
"Y_hat = nf.predict(df=Y_df)\n",
"assert pd.isnull(Y_hat).sum().sum() == 0, 'Predictions should not have NaNs'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "383f05b4-e921-4fa6-b2a1-65105b5eebd0",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"from neuralforecast import NeuralForecast\n",
"from neuralforecast.models import NHITS, RNN\n",
"from neuralforecast.losses.pytorch import DistributionLoss, HuberLoss, GMM, MAE\n",
"from neuralforecast.tsdataset import TimeSeriesDataset\n",
"from neuralforecast.utils import AirPassengers, AirPassengersPanel, AirPassengersStatic"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb2095d2-74d4-4b94-bee3-c049aac8494d",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Unit test for ReVIN, and its compatibility with distribution's scale decouple\n",
"Y_df = AirPassengersPanel\n",
"# del Y_df['trend']\n",
"\n",
"# Instantiate BaseWindow model and test revin dynamic dimensionality with hist_exog_list\n",
"model = NHITS(h=12,\n",
" input_size=24,\n",
" loss=GMM(n_components=10, level=[90]),\n",
" hist_exog_list=['y_[lag12]'],\n",
" max_steps=1,\n",
" early_stop_patience_steps=10,\n",
" val_check_steps=50,\n",
" scaler_type='revin',\n",
" learning_rate=1e-3)\n",
"nf = NeuralForecast(models=[model], freq='MS')\n",
"Y_hat_df = nf.cross_validation(df=Y_df, val_size=12, n_windows=1)\n",
"\n",
"# Instantiate BaseWindow model and test revin dynamic dimensionality with hist_exog_list\n",
"model = NHITS(h=12,\n",
" input_size=24,\n",
" loss=HuberLoss(),\n",
" hist_exog_list=['trend', 'y_[lag12]'],\n",
" max_steps=1,\n",
" early_stop_patience_steps=10,\n",
" val_check_steps=50,\n",
" scaler_type='revin',\n",
" learning_rate=1e-3)\n",
"nf = NeuralForecast(models=[model], freq='MS')\n",
"Y_hat_df = nf.cross_validation(df=Y_df, val_size=12, n_windows=1)\n",
"\n",
"# Instantiate BaseRecurrent model and test revin dynamic dimensionality with hist_exog_list\n",
"model = RNN(h=12,\n",
" input_size=24,\n",
" loss=GMM(n_components=10, level=[90]),\n",
" hist_exog_list=['trend', 'y_[lag12]'],\n",
" max_steps=1,\n",
" early_stop_patience_steps=10,\n",
" val_check_steps=50,\n",
" scaler_type='revin',\n",
" learning_rate=1e-3)\n",
"nf = NeuralForecast(models=[model], freq='MS')\n",
"Y_hat_df = nf.cross_validation(df=Y_df, val_size=12, n_windows=1)\n",
"\n",
"# Instantiate BaseRecurrent model and test revin dynamic dimensionality with hist_exog_list\n",
"model = RNN(h=12,\n",
" input_size=24,\n",
" loss=HuberLoss(),\n",
" hist_exog_list=['trend'],\n",
" max_steps=1,\n",
" early_stop_patience_steps=10,\n",
" val_check_steps=50,\n",
" scaler_type='revin',\n",
" learning_rate=1e-3)\n",
"nf = NeuralForecast(models=[model], freq='MS')\n",
"Y_hat_df = nf.cross_validation(df=Y_df, val_size=12, n_windows=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b2f50bd8",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#| default_exp compat"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"try:\n",
" from pyspark.sql import DataFrame as SparkDataFrame\n",
"except ImportError:\n",
" class SparkDataFrame: ..."
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "524620c1",
"metadata": {},
"outputs": [],
"source": [
"#| default_exp core"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "15392f6f",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "12fa25a4",
"metadata": {},
"source": [
"# Core\n",
"> NeuralForecast contains two main components, PyTorch implementations deep learning predictive models, as well as parallelization and distributed computation utilities. The first component comprises low-level PyTorch model estimator classes like `models.NBEATS` and `models.RNN`. The second component is a high-level `core.NeuralForecast` wrapper class that operates with sets of time series data stored in pandas DataFrames."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2508f7a9-1433-4ad8-8f2f-0078c6ed6c3c",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"import shutil\n",
"import sys\n",
"\n",
"import git\n",
"import s3fs\n",
"from fastcore.test import test_eq, test_fail\n",
"from nbdev.showdoc import show_doc\n",
"from neuralforecast.utils import generate_series"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "44065066-e72a-431f-938f-1528adef9fe8",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"import os\n",
"import pickle\n",
"import warnings\n",
"from copy import deepcopy\n",
"from itertools import chain\n",
"from typing import Any, Dict, List, Optional, Union\n",
"\n",
"import fsspec\n",
"import numpy as np\n",
"import pandas as pd\n",
"import pytorch_lightning as pl\n",
"import torch\n",
"import utilsforecast.processing as ufp\n",
"from coreforecast.grouped_array import GroupedArray\n",
"from coreforecast.scalers import (\n",
" LocalBoxCoxScaler,\n",
" LocalMinMaxScaler,\n",
" LocalRobustScaler,\n",
" LocalStandardScaler,\n",
")\n",
"from utilsforecast.compat import DataFrame, Series, pl_DataFrame, pl_Series\n",
"from utilsforecast.validation import validate_freq\n",
"\n",
"from neuralforecast.common._base_model import DistributedConfig\n",
"from neuralforecast.compat import SparkDataFrame\n",
"from neuralforecast.tsdataset import _FilesDataset, TimeSeriesDataset\n",
"from neuralforecast.models import (\n",
" GRU, LSTM, RNN, TCN, DeepAR, DilatedRNN,\n",
" MLP, NHITS, NBEATS, NBEATSx, DLinear, NLinear,\n",
" TFT, VanillaTransformer,\n",
" Informer, Autoformer, FEDformer,\n",
" StemGNN, PatchTST, TimesNet, TimeLLM, TSMixer, TSMixerx,\n",
" MLPMultivariate, iTransformer,\n",
" BiTCN,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb8b4b3c-04bf-4a92-9a1a-b60735997c36",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"# this disables warnings about the number of workers in the dataloaders\n",
"# which the user can't control\n",
"pl.disable_possible_user_warnings()\n",
"\n",
"def _insample_times(\n",
" times: np.ndarray,\n",
" uids: Series,\n",
" indptr: np.ndarray,\n",
" h: int,\n",
" freq: Union[int, str, pd.offsets.BaseOffset],\n",
" step_size: int = 1,\n",
" id_col: str = 'unique_id',\n",
" time_col: str = 'ds',\n",
") -> DataFrame:\n",
" sizes = np.diff(indptr)\n",
" if (sizes < h).any():\n",
" raise ValueError('`sizes` should be greater or equal to `h`.')\n",
" # TODO: we can just truncate here instead of raising an error\n",
" ns, resids = np.divmod(sizes - h, step_size)\n",
" if (resids != 0).any():\n",
" raise ValueError('`sizes - h` should be multiples of `step_size`')\n",
" windows_per_serie = ns + 1\n",
" # determine the offsets for the cutoffs, e.g. 2 means the 3rd training date is a cutoff\n",
" cutoffs_offsets = step_size * np.hstack([np.arange(w) for w in windows_per_serie])\n",
" # start index of each serie, e.g. [0, 17] means the the second serie starts on the 18th entry\n",
" # we repeat each of these as many times as we have windows, e.g. windows_per_serie = [2, 3]\n",
" # would yield [0, 0, 17, 17, 17]\n",
" start_idxs = np.repeat(indptr[:-1], windows_per_serie)\n",
" # determine the actual indices of the cutoffs, we repeat the cutoff for the complete horizon\n",
" # e.g. if we have two series and h=2 this could be [0, 0, 1, 1, 17, 17, 18, 18]\n",
" # which would have the first two training dates from each serie as the cutoffs\n",
" cutoff_idxs = np.repeat(start_idxs + cutoffs_offsets, h)\n",
" cutoffs = times[cutoff_idxs]\n",
" total_windows = windows_per_serie.sum()\n",
" # determine the offsets for the actual dates. this is going to be [0, ..., h] repeated\n",
" ds_offsets = np.tile(np.arange(h), total_windows)\n",
" # determine the actual indices of the times\n",
" # e.g. if we have two series and h=2 this could be [0, 1, 1, 2, 17, 18, 18, 19]\n",
" ds_idxs = cutoff_idxs + ds_offsets\n",
" ds = times[ds_idxs]\n",
" if isinstance(uids, pl_Series):\n",
" df_constructor = pl_DataFrame\n",
" else:\n",
" df_constructor = pd.DataFrame\n",
" out = df_constructor(\n",
" {\n",
" id_col: ufp.repeat(uids, h * windows_per_serie),\n",
" time_col: ds,\n",
" 'cutoff': cutoffs,\n",
" }\n",
" )\n",
" # the first cutoff is before the first train date\n",
" actual_cutoffs = ufp.offset_times(out['cutoff'], freq, -1)\n",
" out = ufp.assign_columns(out, 'cutoff', actual_cutoffs)\n",
" return out"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6aead6db-170a-4a74-baf3-7cbaf8b7468c",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"uids = pd.Series(['id_0', 'id_1'])\n",
"indptr = np.array([0, 4, 10], dtype=np.int32)\n",
"h = 2\n",
"for step_size, freq, days in zip([1, 2], ['D', 'W-THU'], [1, 14]):\n",
" times = np.hstack([\n",
" pd.date_range('2000-01-01', freq=freq, periods=4),\n",
" pd.date_range('2000-10-10', freq=freq, periods=10),\n",
" ]) \n",
" times_df = _insample_times(times, uids, indptr, h, freq, step_size=step_size)\n",
" pd.testing.assert_frame_equal(\n",
" times_df.groupby('unique_id')['ds'].min().reset_index(),\n",
" pd.DataFrame({\n",
" 'unique_id': uids,\n",
" 'ds': times[indptr[:-1]],\n",
" })\n",
" )\n",
" pd.testing.assert_frame_equal(\n",
" times_df.groupby('unique_id')['ds'].max().reset_index(),\n",
" pd.DataFrame({\n",
" 'unique_id': uids,\n",
" 'ds': times[indptr[1:] - 1],\n",
" })\n",
" )\n",
" cutoff_deltas = (\n",
" times_df\n",
" .drop_duplicates(['unique_id', 'cutoff'])\n",
" .groupby('unique_id')\n",
" ['cutoff']\n",
" .diff()\n",
" .dropna()\n",
" )\n",
" assert cutoff_deltas.nunique() == 1\n",
" assert cutoff_deltas.unique()[0] == pd.Timedelta(f'{days}D')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1c58a8a5",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"MODEL_FILENAME_DICT = {\n",
" 'autoformer': Autoformer, 'autoautoformer': Autoformer,\n",
" 'deepar': DeepAR, 'autodeepar': DeepAR,\n",
" 'dlinear': DLinear, 'autodlinear': DLinear,\n",
" 'nlinear': NLinear, 'autonlinear': NLinear, \n",
" 'dilatedrnn': DilatedRNN , 'autodilatedrnn': DilatedRNN,\n",
" 'fedformer': FEDformer, 'autofedformer': FEDformer,\n",
" 'gru': GRU, 'autogru': GRU,\n",
" 'informer': Informer, 'autoinformer': Informer,\n",
" 'lstm': LSTM, 'autolstm': LSTM,\n",
" 'mlp': MLP, 'automlp': MLP,\n",
" 'nbeats': NBEATS, 'autonbeats': NBEATS,\n",
" 'nbeatsx': NBEATSx, 'autonbeatsx': NBEATSx,\n",
" 'nhits': NHITS, 'autonhits': NHITS,\n",
" 'patchtst': PatchTST, 'autopatchtst': PatchTST,\n",
" 'rnn': RNN, 'autornn': RNN,\n",
" 'stemgnn': StemGNN, 'autostemgnn': StemGNN,\n",
" 'tcn': TCN, 'autotcn': TCN, \n",
" 'tft': TFT, 'autotft': TFT,\n",
" 'timesnet': TimesNet, 'autotimesnet': TimesNet,\n",
" 'vanillatransformer': VanillaTransformer, 'autovanillatransformer': VanillaTransformer,\n",
" 'timellm': TimeLLM,\n",
" 'tsmixer': TSMixer, 'autotsmixer': TSMixer,\n",
" 'tsmixerx': TSMixerx, 'autotsmixerx': TSMixerx,\n",
" 'mlpmultivariate': MLPMultivariate, 'automlpmultivariate': MLPMultivariate,\n",
" 'itransformer': iTransformer, 'autoitransformer': iTransformer,\n",
" 'bitcn': BiTCN, 'autobitcn': BiTCN,\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4c621a39-5658-4850-95c4-050eee97403d",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"_type2scaler = {\n",
" 'standard': LocalStandardScaler,\n",
" 'robust': lambda: LocalRobustScaler(scale='mad'),\n",
" 'robust-iqr': lambda: LocalRobustScaler(scale='iqr'),\n",
" 'minmax': LocalMinMaxScaler,\n",
" 'boxcox': lambda: LocalBoxCoxScaler(method='loglik', lower=0.0)\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d4bf5a30-8378-40ac-920b-af757c228a9b",
"metadata": {},
"outputs": [],
"source": [
"#| exporti\n",
"def _id_as_idx() -> bool:\n",
" return not bool(os.getenv(\"NIXTLA_ID_AS_COL\", \"\"))\n",
"\n",
"def _warn_id_as_idx():\n",
" warnings.warn(\n",
" \"In a future version the predictions will have the id as a column. \"\n",
" \"You can set the `NIXTLA_ID_AS_COL` environment variable \"\n",
" \"to adopt the new behavior and to suppress this warning.\",\n",
" category=FutureWarning,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c4dae43c-4d11-4bbc-a431-ac33b004859a",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"class NeuralForecast:\n",
" \n",
" def __init__(self, \n",
" models: List[Any],\n",
" freq: Union[str, int],\n",
" local_scaler_type: Optional[str] = None):\n",
" \"\"\"\n",
" The `core.StatsForecast` class allows you to efficiently fit multiple `NeuralForecast` models \n",
" for large sets of time series. It operates with pandas DataFrame `df` that identifies series \n",
" and datestamps with the `unique_id` and `ds` columns. The `y` column denotes the target \n",
" time series variable.\n",
"\n",
" Parameters\n",
" ----------\n",
" models : List[typing.Any]\n",
" Instantiated `neuralforecast.models` \n",
" see [collection here](https://nixtla.github.io/neuralforecast/models.html).\n",
" freq : str or int\n",
" Frequency of the data. Must be a valid pandas or polars offset alias, or an integer.\n",
" local_scaler_type : str, optional (default=None)\n",
" Scaler to apply per-serie to all features before fitting, which is inverted after predicting.\n",
" Can be 'standard', 'robust', 'robust-iqr', 'minmax' or 'boxcox'\n",
" \n",
" Returns\n",
" -------\n",
" self : NeuralForecast\n",
" Returns instantiated `NeuralForecast` class.\n",
" \"\"\"\n",
" assert all(model.h == models[0].h for model in models), 'All models should have the same horizon'\n",
"\n",
" self.h = models[0].h\n",
" self.models_init = models\n",
" self.freq = freq\n",
" if local_scaler_type is not None and local_scaler_type not in _type2scaler:\n",
" raise ValueError(f'scaler_type must be one of {_type2scaler.keys()}')\n",
" self.local_scaler_type = local_scaler_type\n",
" self.scalers_: Dict\n",
"\n",
" # Flags and attributes\n",
" self._fitted = False\n",
" self._reset_models()\n",
"\n",
" def _scalers_fit_transform(self, dataset: TimeSeriesDataset) -> None:\n",
" self.scalers_ = {} \n",
" if self.local_scaler_type is None:\n",
" return None\n",
" for i, col in enumerate(dataset.temporal_cols):\n",
" if col == 'available_mask':\n",
" continue\n",
" ga = GroupedArray(dataset.temporal[:, i].numpy(), dataset.indptr) \n",
" self.scalers_[col] = _type2scaler[self.local_scaler_type]().fit(ga)\n",
" dataset.temporal[:, i] = torch.from_numpy(self.scalers_[col].transform(ga))\n",
"\n",
" def _scalers_transform(self, dataset: TimeSeriesDataset) -> None:\n",
" if not self.scalers_:\n",
" return None\n",
" for i, col in enumerate(dataset.temporal_cols):\n",
" scaler = self.scalers_.get(col, None)\n",
" if scaler is None:\n",
" continue\n",
" ga = GroupedArray(dataset.temporal[:, i].numpy(), dataset.indptr)\n",
" dataset.temporal[:, i] = torch.from_numpy(scaler.transform(ga))\n",
"\n",
" def _scalers_target_inverse_transform(self, data: np.ndarray, indptr: np.ndarray) -> np.ndarray:\n",
" if not self.scalers_:\n",
" return data\n",
" for i in range(data.shape[1]):\n",
" ga = GroupedArray(data[:, i], indptr)\n",
" data[:, i] = self.scalers_[self.target_col].inverse_transform(ga)\n",
" return data\n",
"\n",
" def _prepare_fit(self, df, static_df, sort_df, predict_only, id_col, time_col, target_col):\n",
" #TODO: uids, last_dates and ds should be properties of the dataset class. See github issue.\n",
" self.id_col = id_col\n",
" self.time_col = time_col\n",
" self.target_col = target_col\n",
" self._check_nan(df, static_df, id_col, time_col, target_col)\n",
" \n",
" dataset, uids, last_dates, ds = TimeSeriesDataset.from_df(\n",
" df=df,\n",
" static_df=static_df,\n",
" sort_df=sort_df,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" target_col=target_col,\n",
" )\n",
" if predict_only:\n",
" self._scalers_transform(dataset)\n",
" else:\n",
" self._scalers_fit_transform(dataset)\n",
" return dataset, uids, last_dates, ds\n",
"\n",
"\n",
" def _check_nan(self, df, static_df, id_col, time_col, target_col):\n",
" cols_with_nans = []\n",
"\n",
" temporal_cols = [target_col] + [c for c in df.columns if c not in (id_col, time_col, target_col)]\n",
" if \"available_mask\" in temporal_cols:\n",
" available_mask = df[\"available_mask\"].to_numpy().astype(bool)\n",
" else:\n",
" available_mask = np.full(df.shape[0], True)\n",
"\n",
" df_to_check = ufp.filter_with_mask(df, available_mask)\n",
" for col in temporal_cols:\n",
" if ufp.is_nan_or_none(df_to_check[col]).any():\n",
" cols_with_nans.append(col)\n",
"\n",
" if static_df is not None:\n",
" for col in [x for x in static_df.columns if x != id_col]:\n",
" if ufp.is_nan_or_none(static_df[col]).any():\n",
" cols_with_nans.append(col)\n",
"\n",
" if cols_with_nans:\n",
" raise ValueError(f\"Found missing values in {cols_with_nans}.\") \n",
"\n",
" def fit(self,\n",
" df: Optional[Union[DataFrame, SparkDataFrame]] = None,\n",
" static_df: Optional[Union[DataFrame, SparkDataFrame]] = None,\n",
" val_size: Optional[int] = 0,\n",
" sort_df: bool = True,\n",
" use_init_models: bool = False,\n",
" verbose: bool = False,\n",
" id_col: str = 'unique_id',\n",
" time_col: str = 'ds',\n",
" target_col: str = 'y',\n",
" distributed_config: Optional[DistributedConfig] = None,\n",
" ) -> None:\n",
" \"\"\"Fit the core.NeuralForecast.\n",
"\n",
" Fit `models` to a large set of time series from DataFrame `df`.\n",
" and store fitted models for later inspection.\n",
"\n",
" Parameters\n",
" ----------\n",
" df : pandas, polars or spark DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`, `ds`, `y`] and exogenous variables.\n",
" If None, a previously stored dataset is required.\n",
" static_df : pandas, polars or spark DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`] and static exogenous.\n",
" val_size : int, optional (default=0)\n",
" Size of validation set.\n",
" sort_df : bool, optional (default=False)\n",
" Sort `df` before fitting.\n",
" use_init_models : bool, optional (default=False)\n",
" Use initial model passed when NeuralForecast object was instantiated.\n",
" verbose : bool (default=False)\n",
" Print processing steps.\n",
" id_col : str (default='unique_id')\n",
" Column that identifies each serie.\n",
" time_col : str (default='ds')\n",
" Column that identifies each timestep, its values can be timestamps or integers.\n",
" target_col : str (default='y')\n",
" Column that contains the target.\n",
" distributed_config : neuralforecast.DistributedConfig\n",
" Configuration to use for DDP training. Currently only spark is supported.\n",
"\n",
" Returns\n",
" -------\n",
" self : NeuralForecast\n",
" Returns `NeuralForecast` class with fitted `models`.\n",
" \"\"\"\n",
" if (df is None) and not (hasattr(self, 'dataset')):\n",
" raise Exception('You must pass a DataFrame or have one stored.')\n",
"\n",
" # Model and datasets interactions protections\n",
" if (any(model.early_stop_patience_steps>0 for model in self.models)) \\\n",
" and (val_size==0):\n",
" raise Exception('Set val_size>0 if early stopping is enabled.')\n",
"\n",
" # Process and save new dataset (in self)\n",
" if isinstance(df, (pd.DataFrame, pl_DataFrame)):\n",
" validate_freq(df[time_col], self.freq)\n",
" self.dataset, self.uids, self.last_dates, self.ds = self._prepare_fit(\n",
" df=df,\n",
" static_df=static_df,\n",
" sort_df=sort_df,\n",
" predict_only=False,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" target_col=target_col,\n",
" )\n",
" self.sort_df = sort_df\n",
" elif isinstance(df, SparkDataFrame):\n",
" if distributed_config is None:\n",
" raise ValueError(\n",
" \"Must set `distributed_config` when using a spark dataframe\"\n",
" )\n",
" if self.local_scaler_type is not None:\n",
" raise ValueError(\n",
" \"Historic scaling isn't supported in distributed. \"\n",
" \"Please open an issue if this would be valuable to you.\"\n",
" )\n",
" temporal_cols = [c for c in df.columns if c not in (id_col, time_col)]\n",
" if static_df is not None:\n",
" if not isinstance(static_df, SparkDataFrame):\n",
" raise ValueError(\n",
" \"`static_df` must be a spark dataframe when `df` is a spark dataframe.\"\n",
" )\n",
" static_cols = [c for c in static_df.columns if c != id_col]\n",
" df = df.join(static_df, on=[id_col], how=\"left\")\n",
" else:\n",
" static_cols = None\n",
" self.id_col = id_col\n",
" self.time_col = time_col\n",
" self.target_col = target_col\n",
" self.scalers_ = {}\n",
" self.sort_df = sort_df\n",
" num_partitions = distributed_config.num_nodes * distributed_config.devices\n",
" df = df.repartitionByRange(num_partitions, id_col)\n",
" df.write.parquet(path=distributed_config.partitions_path, mode=\"overwrite\")\n",
" fs, _, _ = fsspec.get_fs_token_paths(distributed_config.partitions_path)\n",
" protocol = fs.protocol \n",
" if isinstance(protocol, tuple):\n",
" protocol = protocol[0]\n",
" files = [\n",
" f'{protocol}://{file}'\n",
" for file in fs.ls(distributed_config.partitions_path)\n",
" if file.endswith(\"parquet\")\n",
" ]\n",
" self.dataset = _FilesDataset(\n",
" files=files,\n",
" temporal_cols=temporal_cols,\n",
" static_cols=static_cols,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" target_col=target_col,\n",
" min_size=df.groupBy(id_col).count().agg({\"count\": \"min\"}).first()[0],\n",
" )\n",
" elif df is None:\n",
" if verbose:\n",
" print(\"Using stored dataset.\")\n",
" else:\n",
" raise ValueError(\n",
" f\"`df` must be a pandas, polars or spark DataFrame or `None`, got: {type(df)}\"\n",
" )\n",
"\n",
" if val_size is not None:\n",
" if self.dataset.min_size < val_size:\n",
" warnings.warn('Validation set size is larger than the shorter time-series.')\n",
"\n",
" # Recover initial model if use_init_models\n",
" if use_init_models:\n",
" self._reset_models()\n",
"\n",
" for i, model in enumerate(self.models):\n",
" self.models[i] = model.fit(\n",
" self.dataset, val_size=val_size, distributed_config=distributed_config\n",
" )\n",
"\n",
" self._fitted = True\n",
"\n",
" def make_future_dataframe(self, df: Optional[DataFrame] = None) -> DataFrame:\n",
" \"\"\"Create a dataframe with all ids and future times in the forecasting horizon.\n",
"\n",
" Parameters\n",
" ----------\n",
" df : pandas or polars DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`, `ds`, `y`] and exogenous variables.\n",
" Only required if this is different than the one used in the fit step.\n",
" \"\"\"\n",
" if not self._fitted:\n",
" raise Exception('You must fit the model first.')\n",
" if df is not None:\n",
" df = ufp.sort(df, by=[self.id_col, self.time_col])\n",
" last_times_by_id = ufp.group_by_agg(\n",
" df,\n",
" by=self.id_col,\n",
" aggs={self.time_col: 'max'},\n",
" maintain_order=True,\n",
" )\n",
" uids = last_times_by_id[self.id_col]\n",
" last_times = last_times_by_id[self.time_col]\n",
" else:\n",
" uids = self.uids\n",
" last_times = self.last_dates\n",
" return ufp.make_future_dataframe(\n",
" uids=uids,\n",
" last_times=last_times,\n",
" freq=self.freq,\n",
" h=self.h,\n",
" id_col=self.id_col,\n",
" time_col=self.time_col,\n",
" )\n",
"\n",
" def get_missing_future(\n",
" self, futr_df: DataFrame, df: Optional[DataFrame] = None\n",
" ) -> DataFrame:\n",
" \"\"\"Get the missing ids and times combinations in `futr_df`.\n",
" \n",
" Parameters\n",
" ----------\n",
" futr_df : pandas or polars DataFrame\n",
" DataFrame with [`unique_id`, `ds`] columns and `df`'s future exogenous.\n",
" df : pandas or polars DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`, `ds`, `y`] and exogenous variables.\n",
" Only required if this is different than the one used in the fit step.\n",
" \"\"\"\n",
" expected = self.make_future_dataframe(df)\n",
" ids = [self.id_col, self.time_col]\n",
" return ufp.anti_join(expected, futr_df[ids], on=ids)\n",
"\n",
" def _get_needed_futr_exog(self):\n",
" return set(chain.from_iterable(getattr(m, 'futr_exog_list', []) for m in self.models))\n",
"\n",
" def _get_model_names(self) -> List[str]:\n",
" names: List[str] = []\n",
" count_names = {'model': 0}\n",
" for model in self.models:\n",
" model_name = repr(model)\n",
" count_names[model_name] = count_names.get(model_name, -1) + 1\n",
" if count_names[model_name] > 0:\n",
" model_name += str(count_names[model_name])\n",
" names.extend(model_name + n for n in model.loss.output_names)\n",
" return names\n",
"\n",
" def predict(self,\n",
" df: Optional[Union[DataFrame, SparkDataFrame]] = None,\n",
" static_df: Optional[Union[DataFrame, SparkDataFrame]] = None,\n",
" futr_df: Optional[Union[DataFrame, SparkDataFrame]] = None,\n",
" sort_df: bool = True,\n",
" verbose: bool = False,\n",
" engine = None,\n",
" **data_kwargs):\n",
" \"\"\"Predict with core.NeuralForecast.\n",
"\n",
" Use stored fitted `models` to predict large set of time series from DataFrame `df`. \n",
"\n",
" Parameters\n",
" ----------\n",
" df : pandas, polars or spark DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`, `ds`, `y`] and exogenous variables.\n",
" If a DataFrame is passed, it is used to generate forecasts.\n",
" static_df : pandas, polars or spark DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`] and static exogenous.\n",
" futr_df : pandas, polars or spark DataFrame, optional (default=None)\n",
" DataFrame with [`unique_id`, `ds`] columns and `df`'s future exogenous.\n",
" sort_df : bool (default=True)\n",
" Sort `df` before fitting.\n",
" verbose : bool (default=False)\n",
" Print processing steps.\n",
" engine : spark session\n",
" Distributed engine for inference. Only used if df is a spark dataframe or if fit was called on a spark dataframe.\n",
" data_kwargs : kwargs\n",
" Extra arguments to be passed to the dataset within each model.\n",
"\n",
" Returns\n",
" -------\n",
" fcsts_df : pandas or polars DataFrame\n",
" DataFrame with insample `models` columns for point predictions and probabilistic\n",
" predictions for all fitted `models`. \n",
" \"\"\"\n",
" if (df is None) and not (hasattr(self, 'dataset')):\n",
" raise Exception('You must pass a DataFrame or have one stored.')\n",
"\n",
" if not self._fitted:\n",
" raise Exception(\"You must fit the model before predicting.\")\n",
"\n",
" needed_futr_exog = self._get_needed_futr_exog()\n",
" if needed_futr_exog:\n",
" if futr_df is None:\n",
" raise ValueError(\n",
" f'Models require the following future exogenous features: {needed_futr_exog}. '\n",
" 'Please provide them through the `futr_df` argument.'\n",
" )\n",
" else:\n",
" missing = needed_futr_exog - set(futr_df.columns)\n",
" if missing:\n",
" raise ValueError(f'The following features are missing from `futr_df`: {missing}')\n",
"\n",
" # distributed df or NeuralForecast instance was trained with a distributed input and no df is provided\n",
" # we assume the user wants to perform distributed inference as well\n",
" if (\n",
" isinstance(df, SparkDataFrame)\n",
" or (\n",
" df is None and isinstance(getattr(self, 'dataset', None), _FilesDataset)\n",
" )\n",
" ):\n",
" import fugue.api as fa\n",
"\n",
" def _predict(\n",
" df: pd.DataFrame,\n",
" static_cols,\n",
" futr_exog_cols,\n",
" models,\n",
" freq,\n",
" id_col,\n",
" time_col,\n",
" target_col,\n",
" ) -> pd.DataFrame:\n",
" from neuralforecast import NeuralForecast\n",
"\n",
" nf = NeuralForecast(models=models, freq=freq)\n",
" nf.id_col = id_col\n",
" nf.time_col = time_col\n",
" nf.target_col = target_col\n",
" nf.scalers_ = {}\n",
" nf._fitted = True\n",
" if futr_exog_cols:\n",
" # if we have futr_exog we'll have extra rows with the future values\n",
" futr_rows = df[target_col].isnull()\n",
" futr_df = df.loc[futr_rows, [self.id_col, self.time_col] + futr_exog_cols].copy()\n",
" df = df[~futr_rows].copy()\n",
" else:\n",
" futr_df = None\n",
" if static_cols:\n",
" static_df = df[[self.id_col] + static_cols].groupby(self.id_col, observed=True).head(1)\n",
" df = df.drop(columns=static_cols)\n",
" else:\n",
" static_df = None\n",
" preds = nf.predict(df=df, static_df=static_df, futr_df=futr_df)\n",
" if preds.index.name == id_col:\n",
" preds = preds.reset_index()\n",
" return preds\n",
" \n",
" # df\n",
" if isinstance(df, SparkDataFrame):\n",
" repartition = True\n",
" else:\n",
" if engine is None:\n",
" raise ValueError(\"engine is required for distributed inference\")\n",
" df = engine.read.parquet(*self.dataset.files)\n",
" # we save the datataset with partitioning\n",
" repartition = False\n",
"\n",
" # static\n",
" static_cols = set(chain.from_iterable(getattr(m, 'stat_exog_list', []) for m in self.models))\n",
" if static_df is not None:\n",
" if not isinstance(static_df, SparkDataFrame):\n",
" raise ValueError(\n",
" \"`static_df` must be a spark dataframe when `df` is a spark dataframe \"\n",
" \"or the models were trained in a distributed setting.\\n\"\n",
" \"You can also provide local dataframes (pandas or polars) as `df` and `static_df`.\"\n",
" )\n",
" missing_static = static_cols - set(static_df.columns)\n",
" if missing_static:\n",
" raise ValueError(\n",
" f\"The following static columns are missing from the static_df: {missing_static}\"\n",
" )\n",
" # join is supposed to preserve the partitioning\n",
" df = df.join(static_df, on=[self.id_col], how=\"left\")\n",
"\n",
" # exog\n",
" if futr_df is not None:\n",
" if not isinstance(futr_df, SparkDataFrame):\n",
" raise ValueError(\n",
" \"`futr_df` must be a spark dataframe when `df` is a spark dataframe \"\n",
" \"or the models were trained in a distributed setting.\\n\"\n",
" \"You can also provide local dataframes (pandas or polars) as `df` and `futr_df`.\"\n",
" )\n",
" if self.target_col in futr_df.columns:\n",
" raise ValueError(\"`futr_df` must not contain the target column.\")\n",
" # df has the statics, historic exog and target at this point, futr_df doesnt\n",
" df = df.unionByName(futr_df, allowMissingColumns=True)\n",
" # union doesn't guarantee preserving the partitioning\n",
" repartition = True\n",
"\n",
" if repartition:\n",
" df = df.repartitionByRange(df.rdd.getNumPartitions(), self.id_col) \n",
"\n",
" # predict\n",
" base_schema = fa.get_schema(df).extract([self.id_col, self.time_col])\n",
" models_schema = {model: 'float' for model in self._get_model_names()}\n",
" return fa.transform(\n",
" df=df,\n",
" using=_predict,\n",
" schema=base_schema.append(models_schema),\n",
" params=dict(\n",
" static_cols=list(static_cols),\n",
" futr_exog_cols=list(needed_futr_exog),\n",
" models=self.models,\n",
" freq=self.freq,\n",
" id_col=self.id_col,\n",
" time_col=self.time_col,\n",
" target_col=self.target_col,\n",
" ),\n",
" )\n",
"\n",
" # Process new dataset but does not store it.\n",
" if df is not None:\n",
" validate_freq(df[self.time_col], self.freq)\n",
" dataset, uids, last_dates, _ = self._prepare_fit(\n",
" df=df,\n",
" static_df=static_df,\n",
" sort_df=sort_df,\n",
" predict_only=True,\n",
" id_col=self.id_col,\n",
" time_col=self.time_col,\n",
" target_col=self.target_col,\n",
" )\n",
" else:\n",
" dataset = self.dataset\n",
" uids = self.uids\n",
" last_dates = self.last_dates\n",
" if verbose: print('Using stored dataset.')\n",
" \n",
" cols = self._get_model_names()\n",
"\n",
" # Placeholder dataframe for predictions with unique_id and ds\n",
" fcsts_df = ufp.make_future_dataframe(\n",
" uids=uids,\n",
" last_times=last_dates,\n",
" freq=self.freq,\n",
" h=self.h,\n",
" id_col=self.id_col,\n",
" time_col=self.time_col,\n",
" )\n",
"\n",
" # Update and define new forecasting dataset\n",
" if futr_df is None:\n",
" futr_df = fcsts_df\n",
" else:\n",
" futr_orig_rows = futr_df.shape[0]\n",
" futr_df = ufp.join(futr_df, fcsts_df, on=[self.id_col, self.time_col])\n",
" if futr_df.shape[0] < fcsts_df.shape[0]:\n",
" if df is None:\n",
" expected_cmd = 'make_future_dataframe()'\n",
" missing_cmd = 'get_missing_future(futr_df)'\n",
" else:\n",
" expected_cmd = 'make_future_dataframe(df)'\n",
" missing_cmd = 'get_missing_future(futr_df, df)'\n",
" raise ValueError(\n",
" 'There are missing combinations of ids and times in `futr_df`.\\n'\n",
" f'You can run the `{expected_cmd}` method to get the expected combinations or '\n",
" f'the `{missing_cmd}` method to get the missing combinations.'\n",
" )\n",
" if futr_orig_rows > futr_df.shape[0]:\n",
" dropped_rows = futr_orig_rows - futr_df.shape[0]\n",
" warnings.warn(\n",
" f'Dropped {dropped_rows:,} unused rows from `futr_df`.'\n",
" )\n",
" if any(ufp.is_none(futr_df[col]).any() for col in needed_futr_exog):\n",
" raise ValueError('Found null values in `futr_df`')\n",
" futr_dataset = dataset.align(\n",
" futr_df,\n",
" id_col=self.id_col,\n",
" time_col=self.time_col,\n",
" target_col=self.target_col,\n",
" )\n",
" self._scalers_transform(futr_dataset)\n",
" dataset = dataset.append(futr_dataset)\n",
"\n",
" col_idx = 0\n",
" fcsts = np.full((self.h * len(uids), len(cols)), fill_value=np.nan, dtype=np.float32)\n",
" for model in self.models:\n",
" old_test_size = model.get_test_size()\n",
" model.set_test_size(self.h) # To predict h steps ahead\n",
" model_fcsts = model.predict(dataset=dataset, **data_kwargs)\n",
" # Append predictions in memory placeholder\n",
" output_length = len(model.loss.output_names)\n",
" fcsts[:, col_idx : col_idx + output_length] = model_fcsts\n",
" col_idx += output_length\n",
" model.set_test_size(old_test_size) # Set back to original value\n",
" if self.scalers_:\n",
" indptr = np.append(0, np.full(len(uids), self.h).cumsum())\n",
" fcsts = self._scalers_target_inverse_transform(fcsts, indptr)\n",
"\n",
" # Declare predictions pd.DataFrame\n",
" if isinstance(fcsts_df, pl_DataFrame):\n",
" fcsts = pl_DataFrame(dict(zip(cols, fcsts.T)))\n",
" else:\n",
" fcsts = pd.DataFrame(fcsts, columns=cols)\n",
" fcsts_df = ufp.horizontal_concat([fcsts_df, fcsts])\n",
" if isinstance(fcsts_df, pd.DataFrame) and _id_as_idx():\n",
" _warn_id_as_idx()\n",
" fcsts_df = fcsts_df.set_index(self.id_col)\n",
" return fcsts_df\n",
"\n",
" def _reset_models(self):\n",
" self.models = [deepcopy(model) for model in self.models_init]\n",
" if self._fitted:\n",
" print('WARNING: Deleting previously fitted models.') \n",
" \n",
" def _no_refit_cross_validation(\n",
" self,\n",
" df: Optional[DataFrame],\n",
" static_df: Optional[DataFrame],\n",
" n_windows: int,\n",
" step_size: int,\n",
" val_size: Optional[int], \n",
" test_size: int,\n",
" sort_df: bool,\n",
" verbose: bool,\n",
" id_col: str,\n",
" time_col: str,\n",
" target_col: str,\n",
" **data_kwargs\n",
" ) -> DataFrame:\n",
" if (df is None) and not (hasattr(self, 'dataset')):\n",
" raise Exception('You must pass a DataFrame or have one stored.')\n",
"\n",
" # Process and save new dataset (in self)\n",
" if df is not None:\n",
" validate_freq(df[time_col], self.freq)\n",
" self.dataset, self.uids, self.last_dates, self.ds = self._prepare_fit(\n",
" df=df,\n",
" static_df=static_df,\n",
" sort_df=sort_df,\n",
" predict_only=False,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" target_col=target_col,\n",
" )\n",
" self.sort_df = sort_df\n",
" else:\n",
" if verbose: print('Using stored dataset.')\n",
"\n",
" if val_size is not None:\n",
" if self.dataset.min_size < (val_size+test_size):\n",
" warnings.warn('Validation and test sets are larger than the shorter time-series.')\n",
"\n",
" cols = []\n",
" count_names = {'model': 0}\n",
" for model in self.models:\n",
" model_name = repr(model)\n",
" count_names[model_name] = count_names.get(model_name, -1) + 1\n",
" if count_names[model_name] > 0:\n",
" model_name += str(count_names[model_name])\n",
" cols += [model_name + n for n in model.loss.output_names]\n",
"\n",
" fcsts_df = ufp.cv_times(\n",
" times=self.ds,\n",
" uids=self.uids,\n",
" indptr=self.dataset.indptr,\n",
" h=self.h,\n",
" test_size=test_size,\n",
" step_size=step_size,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" )\n",
" # the cv_times is sorted by window and then id\n",
" fcsts_df = ufp.sort(fcsts_df, [id_col, 'cutoff', time_col])\n",
"\n",
" col_idx = 0\n",
" fcsts = np.full((self.dataset.n_groups * self.h * n_windows, len(cols)),\n",
" np.nan, dtype=np.float32)\n",
" \n",
" for model in self.models:\n",
" model.fit(dataset=self.dataset,\n",
" val_size=val_size, \n",
" test_size=test_size)\n",
" model_fcsts = model.predict(self.dataset, step_size=step_size, **data_kwargs)\n",
"\n",
" # Append predictions in memory placeholder\n",
" output_length = len(model.loss.output_names)\n",
" fcsts[:,col_idx:(col_idx + output_length)] = model_fcsts\n",
" col_idx += output_length\n",
" if self.scalers_: \n",
" indptr = np.append(0, np.full(self.dataset.n_groups, self.h * n_windows).cumsum())\n",
" fcsts = self._scalers_target_inverse_transform(fcsts, indptr)\n",
"\n",
" self._fitted = True\n",
"\n",
" # Add predictions to forecasts DataFrame\n",
" if isinstance(self.uids, pl_Series):\n",
" fcsts = pl_DataFrame(dict(zip(cols, fcsts.T)))\n",
" else:\n",
" fcsts = pd.DataFrame(fcsts, columns=cols)\n",
" fcsts_df = ufp.horizontal_concat([fcsts_df, fcsts])\n",
"\n",
" # Add original input df's y to forecasts DataFrame \n",
" fcsts_df = ufp.join(\n",
" fcsts_df,\n",
" df[[id_col, time_col, target_col]],\n",
" how='left',\n",
" on=[id_col, time_col],\n",
" )\n",
" if isinstance(fcsts_df, pd.DataFrame) and _id_as_idx():\n",
" _warn_id_as_idx()\n",
" fcsts_df = fcsts_df.set_index(id_col)\n",
" return fcsts_df\n",
"\n",
" def cross_validation(\n",
" self,\n",
" df: Optional[DataFrame] = None,\n",
" static_df: Optional[DataFrame] = None,\n",
" n_windows: int = 1,\n",
" step_size: int = 1,\n",
" val_size: Optional[int] = 0, \n",
" test_size: Optional[int] = None,\n",
" sort_df: bool = True,\n",
" use_init_models: bool = False,\n",
" verbose: bool = False,\n",
" refit: Union[bool, int] = False,\n",
" id_col: str = 'unique_id',\n",
" time_col: str = 'ds',\n",
" target_col: str = 'y',\n",
" **data_kwargs\n",
" ) -> DataFrame:\n",
" \"\"\"Temporal Cross-Validation with core.NeuralForecast.\n",
"\n",
" `core.NeuralForecast`'s cross-validation efficiently fits a list of NeuralForecast \n",
" models through multiple windows, in either chained or rolled manner.\n",
"\n",
" Parameters\n",
" ----------\n",
" df : pandas or polars DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`, `ds`, `y`] and exogenous variables.\n",
" If None, a previously stored dataset is required.\n",
" static_df : pandas or polars DataFrame, optional (default=None)\n",
" DataFrame with columns [`unique_id`] and static exogenous.\n",
" n_windows : int (default=1)\n",
" Number of windows used for cross validation.\n",
" step_size : int (default=1)\n",
" Step size between each window.\n",
" val_size : int, optional (default=None)\n",
" Length of validation size. If passed, set `n_windows=None`.\n",
" test_size : int, optional (default=None)\n",
" Length of test size. If passed, set `n_windows=None`.\n",
" sort_df : bool (default=True)\n",
" Sort `df` before fitting.\n",
" use_init_models : bool, option (default=False)\n",
" Use initial model passed when object was instantiated.\n",
" verbose : bool (default=False)\n",
" Print processing steps.\n",
" refit : bool or int (default=False)\n",
" Retrain model for each cross validation window.\n",
" If False, the models are trained at the beginning and then used to predict each window.\n",
" If positive int, the models are retrained every `refit` windows.\n",
" id_col : str (default='unique_id')\n",
" Column that identifies each serie.\n",
" time_col : str (default='ds')\n",
" Column that identifies each timestep, its values can be timestamps or integers.\n",
" target_col : str (default='y')\n",
" Column that contains the target. \n",
" data_kwargs : kwargs\n",
" Extra arguments to be passed to the dataset within each model.\n",
"\n",
" Returns\n",
" -------\n",
" fcsts_df : pandas or polars DataFrame\n",
" DataFrame with insample `models` columns for point predictions and probabilistic\n",
" predictions for all fitted `models`. \n",
" \"\"\"\n",
" h = self.h\n",
" if n_windows is None and test_size is None:\n",
" raise Exception('you must define `n_windows` or `test_size`.') \n",
" if test_size is None:\n",
" test_size = h + step_size * (n_windows - 1)\n",
" elif n_windows is None:\n",
" if (test_size - h) % step_size:\n",
" raise Exception('`test_size - h` should be module `step_size`')\n",
" n_windows = int((test_size - h) / step_size) + 1\n",
" else:\n",
" raise Exception('you must define `n_windows` or `test_size` but not both') \n",
" # Recover initial model if use_init_models.\n",
" if use_init_models:\n",
" self._reset_models()\n",
" if isinstance(df, pd.DataFrame) and df.index.name == id_col:\n",
" warnings.warn(\n",
" \"Passing the id as index is deprecated, please provide it as a column instead.\",\n",
" FutureWarning,\n",
" )\n",
" df = df.reset_index(id_col) \n",
" if not refit:\n",
" return self._no_refit_cross_validation(\n",
" df=df,\n",
" static_df=static_df,\n",
" n_windows=n_windows,\n",
" step_size=step_size,\n",
" val_size=val_size,\n",
" test_size=test_size,\n",
" sort_df=sort_df,\n",
" verbose=verbose,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" target_col=target_col,\n",
" **data_kwargs\n",
" )\n",
" if df is None:\n",
" raise ValueError('Must specify `df` with `refit!=False`.')\n",
" validate_freq(df[time_col], self.freq)\n",
" splits = ufp.backtest_splits(\n",
" df,\n",
" n_windows=n_windows,\n",
" h=self.h,\n",
" id_col=id_col,\n",
" time_col=time_col,\n",
" freq=self.freq,\n",
" step_size=step_size,\n",
" input_size=None,\n",
" )\n",
" results = []\n",
" for i_window, (cutoffs, train, test) in enumerate(splits):\n",
" should_fit = i_window == 0 or (refit > 0 and i_window % refit == 0)\n",
" if should_fit:\n",
" self.fit(\n",
" df=train,\n",
" static_df=static_df,\n",
" val_size=val_size,\n",
" sort_df=sort_df,\n",
" use_init_models=False,\n",
" verbose=verbose, \n",
" )\n",
" predict_df: Optional[DataFrame] = None\n",
" else:\n",
" predict_df = train\n",
" needed_futr_exog = self._get_needed_futr_exog()\n",
" if needed_futr_exog:\n",
" futr_df: Optional[DataFrame] = test\n",
" else:\n",
" futr_df = None\n",
" preds = self.predict(\n",
" df=predict_df,\n",
" static_df=static_df,\n",
" futr_df=futr_df,\n",
" sort_df=sort_df,\n",
" verbose=verbose,\n",
" **data_kwargs\n",
" )\n",
" preds = ufp.join(preds, cutoffs, on=id_col, how='left')\n",
" fold_result = ufp.join(\n",
" preds, test[[id_col, time_col, target_col]], on=[id_col, time_col]\n",
" )\n",
" results.append(fold_result)\n",
" out = ufp.vertical_concat(results, match_categories=False)\n",
" out = ufp.drop_index_if_pandas(out)\n",
" # match order of cv with no refit\n",
" first_out_cols = [id_col, time_col, \"cutoff\"]\n",
" remaining_cols = [\n",
" c for c in out.columns if c not in first_out_cols + [target_col]\n",
" ]\n",
" cols_order = first_out_cols + remaining_cols + [target_col]\n",
" out = ufp.sort(out[cols_order], by=[id_col, 'cutoff', time_col])\n",
" if isinstance(out, pd.DataFrame) and _id_as_idx():\n",
" _warn_id_as_idx()\n",
" out = out.set_index(id_col)\n",
" return out\n",
"\n",
" def predict_insample(self, step_size: int = 1):\n",
" \"\"\"Predict insample with core.NeuralForecast.\n",
"\n",
" `core.NeuralForecast`'s `predict_insample` uses stored fitted `models`\n",
" to predict historic values of a time series from the stored dataframe.\n",
"\n",
" Parameters\n",
" ----------\n",
" step_size : int (default=1)\n",
" Step size between each window.\n",
"\n",
" Returns\n",
" -------\n",
" fcsts_df : pandas.DataFrame\n",
" DataFrame with insample predictions for all fitted `models`. \n",
" \"\"\"\n",
" if not self._fitted:\n",
" raise Exception('The models must be fitted first with `fit` or `cross_validation`.')\n",
"\n",
" for model in self.models:\n",
" if model.SAMPLING_TYPE == 'recurrent':\n",
" warnings.warn(f'Predict insample might not provide accurate predictions for \\\n",
" recurrent model {repr(model)} class yet due to scaling.')\n",
" print(f'WARNING: Predict insample might not provide accurate predictions for \\\n",
" recurrent model {repr(model)} class yet due to scaling.')\n",
" \n",
" cols = []\n",
" count_names = {'model': 0}\n",
" for model in self.models:\n",
" model_name = repr(model)\n",
" count_names[model_name] = count_names.get(model_name, -1) + 1\n",
" if count_names[model_name] > 0:\n",
" model_name += str(count_names[model_name])\n",
" cols += [model_name + n for n in model.loss.output_names]\n",
"\n",
" # Remove test set from dataset and last dates\n",
" test_size = self.models[0].get_test_size()\n",
"\n",
" # trim the forefront period to ensure `test_size - h` should be module `step_size\n",
" # Note: current constraint imposes that all series lengths are equal, so we can take the first series length as sample\n",
" series_length = self.dataset.indptr[1] - self.dataset.indptr[0]\n",
" _, forefront_offset = np.divmod((series_length - test_size - self.h), step_size)\n",
"\n",
" if test_size>0 or forefront_offset>0:\n",
" trimmed_dataset = TimeSeriesDataset.trim_dataset(dataset=self.dataset,\n",
" right_trim=test_size,\n",
" left_trim=forefront_offset)\n",
" new_idxs = np.hstack(\n",
" [\n",
" np.arange(self.dataset.indptr[i] + forefront_offset, self.dataset.indptr[i + 1] - test_size)\n",
" for i in range(self.dataset.n_groups)\n",
" ]\n",
" )\n",
" times = self.ds[new_idxs]\n",
" else:\n",
" trimmed_dataset = self.dataset\n",
" times = self.ds\n",
"\n",
" # Generate dates\n",
" fcsts_df = _insample_times(\n",
" times=times,\n",
" uids=self.uids,\n",
" indptr=trimmed_dataset.indptr,\n",
" h=self.h,\n",
" freq=self.freq,\n",
" step_size=step_size,\n",
" id_col=self.id_col,\n",
" time_col=self.time_col,\n",
" )\n",
"\n",
" col_idx = 0\n",
" fcsts = np.full((len(fcsts_df), len(cols)), np.nan, dtype=np.float32)\n",
"\n",
" for model in self.models:\n",
" # Test size is the number of periods to forecast (full size of trimmed dataset)\n",
" model.set_test_size(test_size=trimmed_dataset.max_size)\n",
"\n",
" # Predict\n",
" model_fcsts = model.predict(trimmed_dataset, step_size=step_size)\n",
" # Append predictions in memory placeholder\n",
" output_length = len(model.loss.output_names)\n",
" fcsts[:,col_idx:(col_idx + output_length)] = model_fcsts\n",
" col_idx += output_length \n",
" model.set_test_size(test_size=test_size) # Set original test_size\n",
"\n",
" # original y\n",
" original_y = {\n",
" self.id_col: ufp.repeat(self.uids, np.diff(self.dataset.indptr)),\n",
" self.time_col: self.ds,\n",
" self.target_col: self.dataset.temporal[:, 0].numpy(),\n",
" }\n",
"\n",
" # Add predictions to forecasts DataFrame\n",
" if isinstance(self.uids, pl_Series):\n",
" fcsts = pl_DataFrame(dict(zip(cols, fcsts.T)))\n",
" Y_df = pl_DataFrame(original_y)\n",
" else:\n",
" fcsts = pd.DataFrame(fcsts, columns=cols)\n",
" Y_df = pd.DataFrame(original_y).reset_index(drop=True)\n",
" fcsts_df = ufp.horizontal_concat([fcsts_df, fcsts])\n",
"\n",
" # Add original input df's y to forecasts DataFrame\n",
" fcsts_df = ufp.join(fcsts_df, Y_df, how='left', on=[self.id_col, self.time_col])\n",
" if self.scalers_:\n",
" sizes = ufp.counts_by_id(fcsts_df, self.id_col)['counts'].to_numpy()\n",
" indptr = np.append(0, sizes.cumsum())\n",
" invert_cols = cols + [self.target_col]\n",
" fcsts_df[invert_cols] = self._scalers_target_inverse_transform(\n",
" fcsts_df[invert_cols].to_numpy(),\n",
" indptr\n",
" )\n",
" if isinstance(fcsts_df, pd.DataFrame) and _id_as_idx():\n",
" _warn_id_as_idx()\n",
" fcsts_df = fcsts_df.set_index(self.id_col) \n",
" return fcsts_df\n",
" \n",
" # Save list of models with pytorch lightning save_checkpoint function\n",
" def save(self, path: str, model_index: Optional[List]=None, save_dataset: bool=True, overwrite: bool=False):\n",
" \"\"\"Save NeuralForecast core class.\n",
"\n",
" `core.NeuralForecast`'s method to save current status of models, dataset, and configuration.\n",
" Note that by default the `models` are not saving training checkpoints to save disk memory,\n",
" to get them change the individual model `**trainer_kwargs` to include `enable_checkpointing=True`.\n",
"\n",
" Parameters\n",
" ----------\n",
" path : str\n",
" Directory to save current status.\n",
" model_index : list, optional (default=None)\n",
" List to specify which models from list of self.models to save.\n",
" save_dataset : bool (default=True)\n",
" Whether to save dataset or not.\n",
" overwrite : bool (default=False)\n",
" Whether to overwrite files or not.\n",
" \"\"\"\n",
" # Standarize path without '/'\n",
" if path[-1] == '/':\n",
" path = path[:-1]\n",
"\n",
" # Model index list\n",
" if model_index is None:\n",
" model_index = list(range(len(self.models)))\n",
"\n",
" fs, _, _ = fsspec.get_fs_token_paths(path)\n",
" if not fs.exists(path):\n",
" fs.makedirs(path)\n",
" else:\n",
" # Check if directory is empty to protect overwriting files\n",
" files = fs.ls(path)\n",
"\n",
" # Checking if the list is empty or not\n",
" if files:\n",
" if not overwrite:\n",
" raise Exception('Directory is not empty. Set `overwrite=True` to overwrite files.')\n",
" else:\n",
" fs.rm(path, recursive=True)\n",
" fs.mkdir(path)\n",
"\n",
" # Save models\n",
" count_names = {'model': 0}\n",
" alias_to_model = {}\n",
" for i, model in enumerate(self.models):\n",
" # Skip model if not in list\n",
" if i not in model_index:\n",
" continue\n",
"\n",
" model_name = repr(model)\n",
" model_class_name = model.__class__.__name__.lower()\n",
" alias_to_model[model_name] = model_class_name\n",
" count_names[model_name] = count_names.get(model_name, -1) + 1\n",
" model.save(f\"{path}/{model_name}_{count_names[model_name]}.ckpt\")\n",
" with fsspec.open(f\"{path}/alias_to_model.pkl\", \"wb\") as f:\n",
" pickle.dump(alias_to_model, f)\n",
"\n",
" # Save dataset\n",
" if save_dataset and hasattr(self, 'dataset'):\n",
" if isinstance(self.dataset, _FilesDataset):\n",
" raise ValueError(\n",
" \"Cannot save distributed dataset.\\n\"\n",
" \"You can set `save_dataset=False` and use the `df` argument in the predict method after loading \"\n",
" \"this model to use it for inference.\"\n",
" )\n",
" with fsspec.open(f\"{path}/dataset.pkl\", \"wb\") as f:\n",
" pickle.dump(self.dataset, f)\n",
" elif save_dataset:\n",
" raise Exception('You need to have a stored dataset to save it, \\\n",
" set `save_dataset=False` to skip saving dataset.')\n",
"\n",
" # Save configuration and parameters\n",
" config_dict = {\n",
" \"h\": self.h,\n",
" \"freq\": self.freq,\n",
" \"sort_df\": self.sort_df,\n",
" \"_fitted\": self._fitted,\n",
" \"local_scaler_type\": self.local_scaler_type,\n",
" \"scalers_\": self.scalers_,\n",
" \"id_col\": self.id_col,\n",
" \"time_col\": self.time_col,\n",
" \"target_col\": self.target_col,\n",
" }\n",
" if save_dataset:\n",
" config_dict.update(\n",
" {\n",
" \"uids\": self.uids,\n",
" \"last_dates\": self.last_dates,\n",
" \"ds\": self.ds,\n",
" }\n",
" )\n",
"\n",
" with fsspec.open(f\"{path}/configuration.pkl\", \"wb\") as f:\n",
" pickle.dump(config_dict, f)\n",
"\n",
" @staticmethod\n",
" def load(path, verbose=False, **kwargs):\n",
" \"\"\"Load NeuralForecast\n",
"\n",
" `core.NeuralForecast`'s method to load checkpoint from path.\n",
"\n",
" Parameters\n",
" -----------\n",
" path : str\n",
" Directory with stored artifacts.\n",
" kwargs\n",
" Additional keyword arguments to be passed to the function\n",
" `load_from_checkpoint`.\n",
"\n",
" Returns\n",
" -------\n",
" result : NeuralForecast\n",
" Instantiated `NeuralForecast` class.\n",
" \"\"\"\n",
" # Standarize path without '/'\n",
" if path[-1] == '/':\n",
" path = path[:-1]\n",
" \n",
" fs, _, _ = fsspec.get_fs_token_paths(path)\n",
" files = [f.split('/')[-1] for f in fs.ls(path) if fs.isfile(f)]\n",
"\n",
" # Load models\n",
" models_ckpt = [f for f in files if f.endswith('.ckpt')]\n",
" if len(models_ckpt) == 0:\n",
" raise Exception('No model found in directory.') \n",
" \n",
" if verbose: print(10 * '-' + ' Loading models ' + 10 * '-')\n",
" models = []\n",
" try:\n",
" with fsspec.open(f'{path}/alias_to_model.pkl', 'rb') as f:\n",
" alias_to_model = pickle.load(f)\n",
" except FileNotFoundError:\n",
" alias_to_model = {}\n",
" for model in models_ckpt:\n",
" model_name = '_'.join(model.split('_')[:-1])\n",
" model_class_name = alias_to_model.get(model_name, model_name)\n",
" loaded_model = MODEL_FILENAME_DICT[model_class_name].load(f'{path}/{model}', **kwargs)\n",
" loaded_model.alias = model_name\n",
" models.append(loaded_model)\n",
" if verbose: print(f\"Model {model_name} loaded.\")\n",
"\n",
" if verbose: print(10*'-' + ' Loading dataset ' + 10*'-')\n",
" # Load dataset\n",
" try:\n",
" with fsspec.open(f\"{path}/dataset.pkl\", \"rb\") as f:\n",
" dataset = pickle.load(f)\n",
" if verbose: print('Dataset loaded.')\n",
" except FileNotFoundError:\n",
" dataset = None\n",
" if verbose: print('No dataset found in directory.')\n",
"\n",
" if verbose: print(10*'-' + ' Loading configuration ' + 10*'-')\n",
" # Load configuration\n",
" try:\n",
" with fsspec.open(f\"{path}/configuration.pkl\", \"rb\") as f:\n",
" config_dict = pickle.load(f)\n",
" if verbose: print('Configuration loaded.')\n",
" except FileNotFoundError:\n",
" raise Exception('No configuration found in directory.')\n",
"\n",
" # Create NeuralForecast object\n",
" neuralforecast = NeuralForecast(\n",
" models=models,\n",
" freq=config_dict['freq'],\n",
" local_scaler_type=config_dict['local_scaler_type'],\n",
" )\n",
"\n",
" for attr in ['id_col', 'time_col', 'target_col']:\n",
" setattr(neuralforecast, attr, config_dict[attr])\n",
"\n",
" # Dataset\n",
" if dataset is not None:\n",
" neuralforecast.dataset = dataset\n",
" restore_attrs = [\n",
" 'uids',\n",
" 'last_dates',\n",
" 'ds',\n",
" 'sort_df',\n",
" ]\n",
" for attr in restore_attrs:\n",
" setattr(neuralforecast, attr, config_dict[attr])\n",
"\n",
" # Fitted flag\n",
" neuralforecast._fitted = config_dict['_fitted']\n",
"\n",
" neuralforecast.scalers_ = config_dict['scalers_']\n",
"\n",
" return neuralforecast"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5d6ef366-daec-4ec6-a2ae-199c6ea39a51",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"import logging\n",
"import warnings"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0ac1aa65-40a4-4909-bdfb-1439c30439b8",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"logging.getLogger(\"pytorch_lightning\").setLevel(logging.ERROR)\n",
"warnings.filterwarnings(\"ignore\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4bede563-78c0-40ee-ba76-f06f329cd772",
"metadata": {},
"outputs": [],
"source": [
"show_doc(NeuralForecast.fit, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f90209f6-16da-40a6-8302-1c5c2f66c619",
"metadata": {},
"outputs": [],
"source": [
"show_doc(NeuralForecast.predict, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "19a8923a-f4f3-4e60-b9b9-a7088fc9bff5",
"metadata": {},
"outputs": [],
"source": [
"show_doc(NeuralForecast.cross_validation, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "355df52b",
"metadata": {},
"outputs": [],
"source": [
"show_doc(NeuralForecast.predict_insample, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "93155738-b40f-43d3-ba76-d345bf2583d5",
"metadata": {},
"outputs": [],
"source": [
"show_doc(NeuralForecast.save, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e915796-173c-4400-812f-c6351d5df3be",
"metadata": {},
"outputs": [],
"source": [
"show_doc(NeuralForecast.load, title_level=3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b534d29d-eecc-43ba-8468-c23305fa24a2",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"import matplotlib.pyplot as plt\n",
"import pytorch_lightning as pl\n",
"\n",
"import neuralforecast\n",
"from ray import tune\n",
"\n",
"from neuralforecast.auto import (\n",
" AutoMLP, AutoNBEATS, \n",
" AutoRNN, AutoTCN, AutoDilatedRNN,\n",
")\n",
"\n",
"from neuralforecast.models.rnn import RNN\n",
"from neuralforecast.models.tcn import TCN\n",
"from neuralforecast.models.deepar import DeepAR\n",
"from neuralforecast.models.dilated_rnn import DilatedRNN\n",
"\n",
"from neuralforecast.models.mlp import MLP\n",
"from neuralforecast.models.nhits import NHITS\n",
"from neuralforecast.models.nbeats import NBEATS\n",
"from neuralforecast.models.nbeatsx import NBEATSx\n",
"\n",
"from neuralforecast.models.tft import TFT\n",
"from neuralforecast.models.vanillatransformer import VanillaTransformer\n",
"from neuralforecast.models.informer import Informer\n",
"from neuralforecast.models.autoformer import Autoformer\n",
"\n",
"from neuralforecast.models.stemgnn import StemGNN\n",
"from neuralforecast.models.tsmixer import TSMixer\n",
"from neuralforecast.models.tsmixerx import TSMixerx\n",
"\n",
"from neuralforecast.losses.pytorch import MQLoss, MAE, MSE\n",
"from neuralforecast.utils import AirPassengersDF, AirPassengersPanel, AirPassengersStatic\n",
"\n",
"from datetime import date"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6fd1507c",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"AirPassengersPanel_train = AirPassengersPanel[AirPassengersPanel['ds'] < AirPassengersPanel['ds'].values[-12]].reset_index(drop=True)\n",
"AirPassengersPanel_test = AirPassengersPanel[AirPassengersPanel['ds'] >= AirPassengersPanel['ds'].values[-12]].reset_index(drop=True)\n",
"AirPassengersPanel_test['y'] = np.nan\n",
"AirPassengersPanel_test['y_[lag12]'] = np.nan"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c596acd4-c95a-41f3-a710-cb9b2c27459d",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# id as index warnings\n",
"df_with_idx = AirPassengersPanel_train.set_index('unique_id')\n",
"models = [\n",
" NHITS(h=12, input_size=12, max_steps=1)\n",
"]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"with warnings.catch_warnings(record=True) as issued_warnings:\n",
" warnings.simplefilter('always', category=FutureWarning)\n",
" nf.fit(df=df_with_idx) \n",
" nf.predict()\n",
" nf.predict_insample()\n",
" nf.cross_validation(df=df_with_idx)\n",
"input_id_warnings = [\n",
" w for w in issued_warnings if 'Passing the id as index is deprecated' in str(w.message)\n",
"]\n",
"assert len(input_id_warnings) == 2\n",
"output_id_warnings = [\n",
" w for w in issued_warnings if 'the predictions will have the id as a column' in str(w.message)\n",
"]\n",
"assert len(output_id_warnings) == 3"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "51ecf21b-1919-44b2-843d-9059fb30f1df",
"metadata": {},
"outputs": [],
"source": [
"os.environ['NIXTLA_ID_AS_COL'] = '1'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e2e35f8f",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Unitest for early stopping without val_size protection\n",
"models = [\n",
" NHITS(h=12, input_size=12, max_steps=1, early_stop_patience_steps=5)\n",
"]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"test_fail(nf.fit,\n",
" contains='Set val_size>0 if early stopping is enabled.',\n",
" args=(AirPassengersPanel_train,))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "14ae4692",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test fit+cross_validation behaviour\n",
"models = [NHITS(h=12, input_size=24, max_steps=10)]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train)\n",
"init_fcst = nf.predict()\n",
"init_cv = nf.cross_validation(AirPassengersPanel_train, use_init_models=True)\n",
"after_cv = nf.cross_validation(AirPassengersPanel_train, use_init_models=True)\n",
"nf.fit(AirPassengersPanel_train, use_init_models=True)\n",
"after_fcst = nf.predict()\n",
"test_eq(init_cv, after_cv)\n",
"test_eq(init_fcst, after_fcst)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fddd5459-cc9b-4fd3-b50c-493b969b83f6",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test cross_validation with refit\n",
"models = [\n",
" NHITS(\n",
" h=12,\n",
" input_size=24,\n",
" max_steps=2,\n",
" futr_exog_list=['trend'],\n",
" stat_exog_list=['airline1', 'airline2']\n",
" )\n",
"]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"cv_kwargs = dict(\n",
" df=AirPassengersPanel_train,\n",
" static_df=AirPassengersStatic,\n",
" n_windows=4,\n",
" use_init_models=True,\n",
")\n",
"cv_res_norefit = nf.cross_validation(refit=False, **cv_kwargs)\n",
"cutoffs = cv_res_norefit['cutoff'].unique()\n",
"for refit in [True, 2]:\n",
" cv_res = nf.cross_validation(refit=refit, **cv_kwargs)\n",
" refit = int(refit)\n",
" fltr = lambda df: df['cutoff'].isin(cutoffs[:refit])\n",
" expected = cv_res_norefit[fltr]\n",
" actual = cv_res[fltr]\n",
" # predictions for the no-refit windows should be the same\n",
" pd.testing.assert_frame_equal(\n",
" actual.reset_index(drop=True),\n",
" expected.reset_index(drop=True)\n",
" )\n",
" # predictions after refit should be different\n",
" test_fail(\n",
" lambda: pd.testing.assert_frame_equal(\n",
" cv_res_norefit.drop(expected.index).reset_index(drop=True),\n",
" cv_res.drop(actual.index).reset_index(drop=True),\n",
" ),\n",
" contains='(column name=\"NHITS\") are different',\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1161197c-c0c2-4d71-9b39-701777db26e3",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test scaling\n",
"models = [NHITS(h=12, input_size=24, max_steps=10)]\n",
"models_exog = [NHITS(h=12, input_size=12, max_steps=10, hist_exog_list=['trend'], futr_exog_list=['trend'])]\n",
"\n",
"# fit+predict\n",
"nf = NeuralForecast(models=models, freq='M', local_scaler_type='standard')\n",
"nf.fit(AirPassengersPanel_train)\n",
"scaled_fcst = nf.predict()\n",
"# check that the forecasts are similar to the one without scaling\n",
"np.testing.assert_allclose(\n",
" init_fcst['NHITS'].values,\n",
" scaled_fcst['NHITS'].values,\n",
" rtol=0.3,\n",
")\n",
"# with exog\n",
"nf = NeuralForecast(models=models_exog, freq='M', local_scaler_type='standard')\n",
"nf.fit(AirPassengersPanel_train)\n",
"scaled_exog_fcst = nf.predict(futr_df=AirPassengersPanel_test)\n",
"# check that the forecasts are similar to the one without exog\n",
"np.testing.assert_allclose(\n",
" scaled_fcst['NHITS'].values,\n",
" scaled_exog_fcst['NHITS'].values,\n",
" rtol=0.3,\n",
")\n",
"\n",
"# CV\n",
"nf = NeuralForecast(models=models, freq='M', local_scaler_type='robust')\n",
"cv_res = nf.cross_validation(AirPassengersPanel)\n",
"# check that the forecasts are similar to the original values (originals are restored directly from the df)\n",
"np.testing.assert_allclose(\n",
" cv_res['NHITS'].values,\n",
" cv_res['y'].values,\n",
" rtol=0.3,\n",
")\n",
"# with exog\n",
"nf = NeuralForecast(models=models_exog, freq='M', local_scaler_type='robust-iqr')\n",
"cv_res_exog = nf.cross_validation(AirPassengersPanel)\n",
"# check that the forecasts are similar to the original values (originals are restored directly from the df)\n",
"np.testing.assert_allclose(\n",
" cv_res_exog['NHITS'].values,\n",
" cv_res_exog['y'].values,\n",
" rtol=0.2,\n",
")\n",
"\n",
"# fit+predict_insample\n",
"nf = NeuralForecast(models=models, freq='M', local_scaler_type='minmax')\n",
"nf.fit(AirPassengersPanel_train)\n",
"insample_res = (\n",
" nf.predict_insample()\n",
" .groupby('unique_id').tail(-12) # first values aren't reliable\n",
" .merge(\n",
" AirPassengersPanel_train[['unique_id', 'ds', 'y']],\n",
" on=['unique_id', 'ds'],\n",
" how='left',\n",
" suffixes=('_actual', '_expected'),\n",
" )\n",
")\n",
"# y is inverted correctly\n",
"np.testing.assert_allclose(\n",
" insample_res['y_actual'].values,\n",
" insample_res['y_expected'].values,\n",
" rtol=1e-5,\n",
")\n",
"# predictions are in the same scale\n",
"np.testing.assert_allclose(\n",
" insample_res['NHITS'].values,\n",
" insample_res['y_expected'].values,\n",
" rtol=0.7,\n",
")\n",
"# with exog\n",
"nf = NeuralForecast(models=models_exog, freq='M', local_scaler_type='minmax')\n",
"nf.fit(AirPassengersPanel_train)\n",
"insample_res_exog = (\n",
" nf.predict_insample()\n",
" .groupby('unique_id').tail(-12) # first values aren't reliable\n",
" .merge(\n",
" AirPassengersPanel_train[['unique_id', 'ds', 'y']],\n",
" on=['unique_id', 'ds'],\n",
" how='left',\n",
" suffixes=('_actual', '_expected'),\n",
" )\n",
")\n",
"# y is inverted correctly\n",
"np.testing.assert_allclose(\n",
" insample_res_exog['y_actual'].values,\n",
" insample_res_exog['y_expected'].values,\n",
" rtol=1e-5,\n",
")\n",
"# predictions are similar than without exog\n",
"np.testing.assert_allclose(\n",
" insample_res['NHITS'].values,\n",
" insample_res_exog['NHITS'].values,\n",
" rtol=0.2,\n",
")\n",
"\n",
"# test boxcox\n",
"nf = NeuralForecast(models=models, freq='M', local_scaler_type='boxcox')\n",
"nf.fit(AirPassengersPanel_train)\n",
"insample_res = (\n",
" nf.predict_insample()\n",
" .groupby('unique_id').tail(-12) # first values aren't reliable\n",
" .merge(\n",
" AirPassengersPanel_train[['unique_id', 'ds', 'y']],\n",
" on=['unique_id', 'ds'],\n",
" how='left',\n",
" suffixes=('_actual', '_expected'),\n",
" )\n",
")\n",
"# y is inverted correctly\n",
"np.testing.assert_allclose(\n",
" insample_res['y_actual'].values,\n",
" insample_res['y_expected'].values,\n",
" rtol=1e-5,\n",
")\n",
"# predictions are in the same scale\n",
"np.testing.assert_allclose(\n",
" insample_res['NHITS'].values,\n",
" insample_res['y_expected'].values,\n",
" rtol=0.7,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f1b34d37-29b0-49d4-9c7b-cb8add7ce9cf",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test futr_df contents\n",
"models = [NHITS(h=6, input_size=24, max_steps=10, hist_exog_list=['trend'], futr_exog_list=['trend'])]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train)\n",
"# not enough rows in futr_df raises an error\n",
"test_fail(lambda: nf.predict(futr_df=AirPassengersPanel_test.head()), contains='There are missing combinations')\n",
"# extra rows issues a warning\n",
"with warnings.catch_warnings(record=True) as issued_warnings:\n",
" warnings.simplefilter('always', UserWarning)\n",
" nf.predict(futr_df=AirPassengersPanel_test)\n",
"assert any('Dropped 12 unused rows' in str(w.message) for w in issued_warnings)\n",
"# models require futr_df and not provided raises an error\n",
"test_fail(lambda: nf.predict(), contains=\"Models require the following future exogenous features: {'trend'}\") \n",
"# missing feature in futr_df raises an error\n",
"test_fail(lambda: nf.predict(futr_df=AirPassengersPanel_test.drop(columns='trend')), contains=\"missing from `futr_df`: {'trend'}\")\n",
"# null values in futr_df raises an error\n",
"test_fail(lambda: nf.predict(futr_df=AirPassengersPanel_test.assign(trend=np.nan)), contains='Found null values in `futr_df`')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1e78b113",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Test inplace model fitting\n",
"models = [MLP(h=12, input_size=12, max_steps=1, scaler_type='robust')]\n",
"initial_weights = models[0].mlp[0].weight.detach().clone()\n",
"fcst = NeuralForecast(models=models, freq='M')\n",
"fcst.fit(df=AirPassengersPanel_train, static_df=AirPassengersStatic, use_init_models=True)\n",
"after_weights = fcst.models_init[0].mlp[0].weight.detach().clone()\n",
"assert np.allclose(initial_weights, after_weights), 'init models should not be modified'\n",
"assert len(fcst.models[0].train_trajectories)>0, 'models stored trajectories should not be empty'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "340dd8a9",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Test predict_insample\n",
"test_size = 12\n",
"n_series = 2\n",
"h = 12\n",
"\n",
"config = {'input_size': tune.choice([12, 24]), \n",
" 'hidden_size': 128,\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1,\n",
" 'step_size': 12}\n",
"\n",
"models = [\n",
" NHITS(h=h, input_size=24, loss=MQLoss(level=[80]), max_steps=1, alias='NHITS', scaler_type=None),\n",
" AutoMLP(h=12, config=config, cpus=1, num_samples=1),\n",
" RNN(h=h, input_size=-1, loss=MAE(), max_steps=1, alias='RNN', scaler_type=None),\n",
" ]\n",
"\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"cv = nf.cross_validation(df=AirPassengersPanel_train, static_df=AirPassengersStatic, val_size=0, test_size=test_size, n_windows=None)\n",
"\n",
"forecasts = nf.predict_insample(step_size=1)\n",
"\n",
"expected_size = n_series*((len(AirPassengersPanel_train)//n_series-test_size)-h+1)*h\n",
"assert len(forecasts) == expected_size, f'Shape mismatch in predict_insample: {len(forecasts)=}, {expected_size=}'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "23fb98f8-0e27-44b2-a8a9-3b551986d53f",
"metadata": {},
"outputs": [],
"source": [
"#| hide,\n",
"# Test predict_insample step_size\n",
"\n",
"h = 12\n",
"train_end = AirPassengersPanel_train['ds'].max()\n",
"sizes = AirPassengersPanel_train['unique_id'].value_counts().to_numpy()\n",
"for step_size, test_size in [(7, 0), (9, 0), (7, 5), (9, 5)]:\n",
" models = [NHITS(h=h, input_size=12, max_steps=1)]\n",
" nf = NeuralForecast(models=models, freq='M')\n",
" nf.fit(AirPassengersPanel_train)\n",
" # Note: only apply set_test_size() upon nf.fit(), otherwise it would have set the test_size = 0\n",
" nf.models[0].set_test_size(test_size)\n",
" \n",
" forecasts = nf.predict_insample(step_size=step_size)\n",
" last_cutoff = train_end - test_size * pd.offsets.MonthEnd() - h * pd.offsets.MonthEnd()\n",
" n_expected_cutoffs = (sizes[0] - test_size - nf.h + step_size) // step_size\n",
"\n",
" # compare cutoff values\n",
" expected_cutoffs = np.flip(np.array([last_cutoff - step_size * i * pd.offsets.MonthEnd() for i in range(n_expected_cutoffs)]))\n",
" actual_cutoffs = np.array([pd.Timestamp(x) for x in forecasts[forecasts['unique_id']==nf.uids[1]]['cutoff'].unique()])\n",
" np.testing.assert_array_equal(expected_cutoffs, actual_cutoffs, err_msg=f\"{step_size=},{expected_cutoffs=},{actual_cutoffs=}\")\n",
" \n",
" # check forecast-points count per series\n",
" cutoffs_by_series = forecasts.groupby(['unique_id', 'cutoff']).size().unstack('unique_id')\n",
" pd.testing.assert_series_equal(cutoffs_by_series['Airline1'], cutoffs_by_series['Airline2'], check_names=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1d6bbc2c-d38f-4cec-a3ef-15164852479f",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# tests aliases\n",
"config_drnn = {'input_size': tune.choice([-1]), \n",
" 'encoder_hidden_size': tune.choice([5, 10]),\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1,\n",
" 'step_size': 1}\n",
"models = [\n",
" # test Auto\n",
" AutoDilatedRNN(h=12, config=config_drnn, cpus=1, num_samples=2, alias='AutoDIL'),\n",
" # test BaseWindows\n",
" NHITS(h=12, input_size=24, loss=MQLoss(level=[80]), max_steps=1, alias='NHITSMQ'),\n",
" # test BaseRecurrent\n",
" RNN(h=12, input_size=-1, encoder_hidden_size=10, max_steps=1,\n",
" stat_exog_list=['airline1'],\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]'], alias='MyRNN'),\n",
" # test BaseMultivariate\n",
" StemGNN(h=12, input_size=24, n_series=2, max_steps=1, scaler_type='robust', alias='StemMulti'),\n",
" # test model without alias\n",
" NHITS(h=12, input_size=24, max_steps=1),\n",
"]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(df=AirPassengersPanel_train, static_df=AirPassengersStatic)\n",
"forecasts = nf.predict(futr_df=AirPassengersPanel_test)\n",
"test_eq(\n",
" forecasts.columns.to_list(),\n",
" ['unique_id', 'ds', 'AutoDIL', 'NHITSMQ-median', 'NHITSMQ-lo-80', 'NHITSMQ-hi-80', 'MyRNN', 'StemMulti', 'NHITS']\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0d3779a6-2d03-4ac3-9f01-8bd5cb306845",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Unit test for core/model interactions\n",
"config = {'input_size': tune.choice([12, 24]), \n",
" 'hidden_size': 256,\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1,\n",
" 'step_size': 12}\n",
"\n",
"config_drnn = {'input_size': tune.choice([-1]), \n",
" 'encoder_hidden_size': tune.choice([5, 10]),\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1,\n",
" 'step_size': 1}\n",
"\n",
"fcst = NeuralForecast(\n",
" models=[\n",
" AutoDilatedRNN(h=12, config=config_drnn, cpus=1, num_samples=2),\n",
" DeepAR(h=12, input_size=24, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend']),\n",
" DilatedRNN(h=12, input_size=-1, encoder_hidden_size=10, max_steps=1,\n",
" stat_exog_list=['airline1'],\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" RNN(h=12, input_size=-1, encoder_hidden_size=10, max_steps=1,\n",
" inference_input_size=24,\n",
" stat_exog_list=['airline1'],\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" TCN(h=12, input_size=-1, encoder_hidden_size=10, max_steps=1,\n",
" stat_exog_list=['airline1'],\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" AutoMLP(h=12, config=config, cpus=1, num_samples=2),\n",
" NBEATSx(h=12, input_size=12, max_steps=1,\n",
" stat_exog_list=['airline1'],\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" NHITS(h=12, input_size=24, loss=MQLoss(level=[80]), max_steps=1),\n",
" NHITS(h=12, input_size=12, max_steps=1,\n",
" stat_exog_list=['airline1'],\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" DLinear(h=12, input_size=24, max_steps=1),\n",
" MLP(h=12, input_size=12, max_steps=1,\n",
" stat_exog_list=['airline1'],\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" TFT(h=12, input_size=24, max_steps=1),\n",
" VanillaTransformer(h=12, input_size=24, max_steps=1),\n",
" Informer(h=12, input_size=24, max_steps=1),\n",
" Autoformer(h=12, input_size=24, max_steps=1),\n",
" FEDformer(h=12, input_size=24, max_steps=1),\n",
" PatchTST(h=12, input_size=24, max_steps=1),\n",
" TimesNet(h=12, input_size=24, max_steps=1),\n",
" StemGNN(h=12, input_size=24, n_series=2, max_steps=1, scaler_type='robust'),\n",
" TSMixer(h=12, input_size=24, n_series=2, max_steps=1, scaler_type='robust'),\n",
" TSMixerx(h=12, input_size=24, n_series=2, max_steps=1, scaler_type='robust'),\n",
" ],\n",
" freq='M'\n",
")\n",
"fcst.fit(df=AirPassengersPanel_train, static_df=AirPassengersStatic)\n",
"forecasts = fcst.predict(futr_df=AirPassengersPanel_test)\n",
"forecasts"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "40038532-fd68-4375-b7da-ba5bc2491c5e",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"fig, ax = plt.subplots(1, 1, figsize = (20, 7))\n",
"plot_df = pd.concat([AirPassengersPanel_train, forecasts.reset_index()]).set_index('ds')\n",
"\n",
"plot_df[plot_df['unique_id']=='Airline1'].drop(['unique_id','trend','y_[lag12]'], axis=1).plot(ax=ax, linewidth=2)\n",
"\n",
"ax.set_title('AirPassengers Forecast', fontsize=22)\n",
"ax.set_ylabel('Monthly Passengers', fontsize=20)\n",
"ax.set_xlabel('Timestamp [t]', fontsize=20)\n",
"ax.legend(prop={'size': 15})\n",
"ax.grid()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7d61909b",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"fig, ax = plt.subplots(1, 1, figsize = (20, 7))\n",
"plot_df = pd.concat([AirPassengersPanel_train, forecasts.reset_index()]).set_index('ds')\n",
"\n",
"plot_df[plot_df['unique_id']=='Airline2'].drop(['unique_id','trend','y_[lag12]'], axis=1).plot(ax=ax, linewidth=2)\n",
"\n",
"ax.set_title('AirPassengers Forecast', fontsize=22)\n",
"ax.set_ylabel('Monthly Passengers', fontsize=20)\n",
"ax.set_xlabel('Timestamp [t]', fontsize=20)\n",
"ax.legend(prop={'size': 15})\n",
"ax.grid()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c4a8162a-3d9d-48df-a314-3a2ce0377e36",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"config = {'input_size': tune.choice([12, 24]), \n",
" 'hidden_size': 256,\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1,\n",
" 'step_size': 12}\n",
"\n",
"config_drnn = {'input_size': tune.choice([-1]), \n",
" 'encoder_hidden_size': tune.choice([5, 10]),\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1,\n",
" 'step_size': 1}\n",
"\n",
"fcst = NeuralForecast(\n",
" models=[\n",
" DilatedRNN(h=12, input_size=-1, encoder_hidden_size=10, max_steps=1),\n",
" AutoMLP(h=12, config=config, cpus=1, num_samples=1),\n",
" NHITS(h=12, input_size=12, max_steps=1)\n",
" ],\n",
" freq='M'\n",
")\n",
"cv_df = fcst.cross_validation(df=AirPassengersPanel, static_df=AirPassengersStatic, n_windows=3, step_size=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "17c5ea12-ed87-4e46-ad04-3088e7167dfd",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"#test cross validation no leakage\n",
"def test_cross_validation(df, static_df, h, test_size):\n",
" if (test_size - h) % 1:\n",
" raise Exception(\"`test_size - h` should be module `step_size`\")\n",
" \n",
" n_windows = int((test_size - h) / 1) + 1\n",
" Y_test_df = df.groupby('unique_id').tail(test_size)\n",
" Y_train_df = df.drop(Y_test_df.index)\n",
" config = {'input_size': tune.choice([12, 24]),\n",
" 'step_size': 12, 'hidden_size': 256, 'max_steps': 1, 'val_check_steps': 1}\n",
" config_drnn = {'input_size': tune.choice([-1]), 'encoder_hidden_size': tune.choice([5, 10]),\n",
" 'max_steps': 1, 'val_check_steps': 1}\n",
" fcst = NeuralForecast(\n",
" models=[\n",
" AutoDilatedRNN(h=12, config=config_drnn, cpus=1, num_samples=1),\n",
" DilatedRNN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1),\n",
" RNN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" TCN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" AutoMLP(h=12, config=config, cpus=1, num_samples=1),\n",
" MLP(h=12, input_size=12, max_steps=1, scaler_type='robust'),\n",
" NBEATSx(h=12, input_size=12, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" NHITS(h=12, input_size=12, max_steps=1, scaler_type='robust'),\n",
" NHITS(h=12, input_size=12, loss=MQLoss(level=[80]), max_steps=1),\n",
" TFT(h=12, input_size=24, max_steps=1, scaler_type='robust'),\n",
" DLinear(h=12, input_size=24, max_steps=1),\n",
" VanillaTransformer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" Informer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" Autoformer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" FEDformer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" PatchTST(h=12, input_size=24, max_steps=1, scaler_type=None),\n",
" TimesNet(h=12, input_size=24, max_steps=1, scaler_type='standard'),\n",
" StemGNN(h=12, input_size=12, n_series=2, max_steps=1, scaler_type='robust'),\n",
" TSMixer(h=12, input_size=12, n_series=2, max_steps=1, scaler_type='robust'),\n",
" TSMixerx(h=12, input_size=12, n_series=2, max_steps=1, scaler_type='robust'),\n",
" DeepAR(h=12, input_size=24, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend']),\n",
" ],\n",
" freq='M'\n",
" )\n",
" fcst.fit(df=Y_train_df, static_df=static_df)\n",
" Y_hat_df = fcst.predict(futr_df=Y_test_df)\n",
" Y_hat_df = Y_hat_df.merge(Y_test_df, how='left', on=['unique_id', 'ds'])\n",
" last_dates = Y_train_df.groupby('unique_id').tail(1)\n",
" last_dates = last_dates[['unique_id', 'ds']].rename(columns={'ds': 'cutoff'})\n",
" Y_hat_df = Y_hat_df.merge(last_dates, how='left', on='unique_id')\n",
" \n",
" #cross validation\n",
" fcst = NeuralForecast(\n",
" models=[\n",
" AutoDilatedRNN(h=12, config=config_drnn, cpus=1, num_samples=1),\n",
" DilatedRNN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1),\n",
" RNN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" TCN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" AutoMLP(h=12, config=config, cpus=1, num_samples=1),\n",
" MLP(h=12, input_size=12, max_steps=1, scaler_type='robust'),\n",
" NBEATSx(h=12, input_size=12, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend'], hist_exog_list=['y_[lag12]']),\n",
" NHITS(h=12, input_size=12, max_steps=1, scaler_type='robust'),\n",
" NHITS(h=12, input_size=12, loss=MQLoss(level=[80]), max_steps=1),\n",
" TFT(h=12, input_size=24, max_steps=1, scaler_type='robust'),\n",
" DLinear(h=12, input_size=24, max_steps=1),\n",
" VanillaTransformer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" Informer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" Autoformer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" FEDformer(h=12, input_size=12, max_steps=1, scaler_type=None),\n",
" PatchTST(h=12, input_size=24, max_steps=1, scaler_type=None),\n",
" TimesNet(h=12, input_size=24, max_steps=1, scaler_type='standard'),\n",
" StemGNN(h=12, input_size=12, n_series=2, max_steps=1, scaler_type='robust'),\n",
" TSMixer(h=12, input_size=12, n_series=2, max_steps=1, scaler_type='robust'),\n",
" TSMixerx(h=12, input_size=12, n_series=2, max_steps=1, scaler_type='robust'),\n",
" DeepAR(h=12, input_size=24, max_steps=1,\n",
" stat_exog_list=['airline1'], futr_exog_list=['trend']),\n",
" ],\n",
" freq='M'\n",
" )\n",
" Y_hat_df_cv = fcst.cross_validation(df, static_df=static_df, test_size=test_size, \n",
" n_windows=None)\n",
" for col in ['ds', 'cutoff']:\n",
" Y_hat_df_cv[col] = pd.to_datetime(Y_hat_df_cv[col].astype(str))\n",
" Y_hat_df[col] = pd.to_datetime(Y_hat_df[col].astype(str))\n",
" pd.testing.assert_frame_equal(\n",
" Y_hat_df[Y_hat_df_cv.columns],\n",
" Y_hat_df_cv,\n",
" check_dtype=False,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b0467904-748e-42ec-99cc-bac514626304",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"test_cross_validation(AirPassengersPanel, AirPassengersStatic, h=12, test_size=12)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6f61d030-a51e-49f8-a16e-b97bccb62401",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test save and load\n",
"config = {'input_size': tune.choice([12, 24]),\n",
" 'hidden_size': 256,\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1,\n",
" 'step_size': 12}\n",
"\n",
"config_drnn = {'input_size': tune.choice([-1]),\n",
" 'encoder_hidden_size': tune.choice([5, 10]),\n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1}\n",
"\n",
"fcst = NeuralForecast(\n",
" models=[\n",
" AutoRNN(h=12, config=config_drnn, cpus=1, num_samples=2, refit_with_val=True),\n",
" DilatedRNN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1),\n",
" AutoMLP(h=12, config=config, cpus=1, num_samples=2),\n",
" NHITS(h=12, input_size=12, max_steps=1,\n",
" futr_exog_list=['trend'], hist_exog_list=['y_[lag12]'], alias='Model1'),\n",
" StemGNN(h=12, input_size=12, n_series=2, max_steps=1, scaler_type='robust')\n",
" ],\n",
" freq='M'\n",
")\n",
"fcst.fit(AirPassengersPanel_train)\n",
"forecasts1 = fcst.predict(futr_df=AirPassengersPanel_test)\n",
"save_paths = ['./examples/debug_run/']\n",
"try:\n",
" s3fs.S3FileSystem().ls('s3://nixtla-tmp') \n",
" pyver = f'{sys.version_info.major}_{sys.version_info.minor}'\n",
" sha = git.Repo(search_parent_directories=True).head.object.hexsha\n",
" save_dir = f'{sys.platform}-{pyver}-{sha}'\n",
" save_paths.append(f's3://nixtla-tmp/neural/{save_dir}')\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"for path in save_paths:\n",
" fcst.save(path=path, model_index=None, overwrite=True, save_dataset=True)\n",
" fcst2 = NeuralForecast.load(path=path)\n",
" forecasts2 = fcst2.predict(futr_df=AirPassengersPanel_test)\n",
" pd.testing.assert_frame_equal(forecasts1, forecasts2[forecasts1.columns])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0d221d90-7a89-4338-96b8-09543f3d5554",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test save and load without dataset\n",
"shutil.rmtree('examples/debug_run')\n",
"fcst = NeuralForecast(\n",
" models=[DilatedRNN(h=12, input_size=-1, encoder_hidden_size=5, max_steps=1)],\n",
" freq='M',\n",
")\n",
"fcst.fit(AirPassengersPanel_train)\n",
"forecasts1 = fcst.predict(futr_df=AirPassengersPanel_test)\n",
"fcst.save(path='./examples/debug_run/', model_index=None, overwrite=True, save_dataset=False)\n",
"fcst2 = NeuralForecast.load(path='./examples/debug_run/')\n",
"forecasts2 = fcst2.predict(df=AirPassengersPanel_train, futr_df=AirPassengersPanel_test)\n",
"np.testing.assert_allclose(forecasts1['DilatedRNN'], forecasts2['DilatedRNN'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c22ad495",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test `enable_checkpointing=True` should generate chkpt\n",
"shutil.rmtree('lightning_logs')\n",
"fcst = NeuralForecast(\n",
" models=[\n",
" MLP(h=12, input_size=12, max_steps=10, val_check_steps=5, enable_checkpointing=True),\n",
" RNN(h=12, input_size=-1, max_steps=10, val_check_steps=5, enable_checkpointing=True)\n",
" ],\n",
" freq='M'\n",
")\n",
"fcst.fit(AirPassengersPanel_train)\n",
"last_log = f\"lightning_logs/{os.listdir('lightning_logs')[-1]}\"\n",
"no_chkpt_found = ~np.any([file.endswith('checkpoints') for file in os.listdir(last_log)])\n",
"test_eq(no_chkpt_found, False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5ac7a0b1",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test `enable_checkpointing=False` should not generate chkpt\n",
"shutil.rmtree('lightning_logs')\n",
"fcst = NeuralForecast(\n",
" models=[\n",
" MLP(h=12, input_size=12, max_steps=10, val_check_steps=5),\n",
" RNN(h=12, input_size=-1, max_steps=10, val_check_steps=5)\n",
" ],\n",
" freq='M'\n",
")\n",
"fcst.fit(AirPassengersPanel_train)\n",
"last_log = f\"lightning_logs/{os.listdir('lightning_logs')[-1]}\"\n",
"no_chkpt_found = ~np.any([file.endswith('checkpoints') for file in os.listdir(last_log)])\n",
"test_eq(no_chkpt_found, True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8602941e",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test short time series\n",
"config = {'input_size': tune.choice([12, 24]), \n",
" 'max_steps': 1,\n",
" 'val_check_steps': 1}\n",
"\n",
"fcst = NeuralForecast(\n",
" models=[\n",
" AutoNBEATS(h=12, config=config, cpus=1, num_samples=2)],\n",
" freq='M'\n",
")\n",
"\n",
"AirPassengersShort = AirPassengersPanel.tail(36+144).reset_index(drop=True)\n",
"forecasts = fcst.cross_validation(AirPassengersShort, val_size=48, n_windows=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cadac88d",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test validation scale BaseWindows\n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=50, scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train,val_size=12)\n",
"valid_losses = nf.models[0].valid_trajectories\n",
"assert valid_losses[-1][1] < 40, 'Validation loss is too high'\n",
"assert valid_losses[-1][1] > 10, 'Validation loss is too low'\n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=50, scaler_type=None)]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train,val_size=12)\n",
"valid_losses = nf.models[0].valid_trajectories\n",
"assert valid_losses[-1][1] < 40, 'Validation loss is too high'\n",
"assert valid_losses[-1][1] > 10, 'Validation loss is too low'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee083d85",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test validation scale BaseRecurrent\n",
"\n",
"nf = NeuralForecast(\n",
" models=[LSTM(h=12,\n",
" input_size=-1,\n",
" loss=MAE(),\n",
" scaler_type='robust',\n",
" encoder_n_layers=2,\n",
" encoder_hidden_size=128,\n",
" context_size=10,\n",
" decoder_hidden_size=128,\n",
" decoder_layers=2,\n",
" max_steps=50,\n",
" val_check_steps=10,\n",
" )\n",
" ],\n",
" freq='M'\n",
")\n",
"nf.fit(AirPassengersPanel_train,val_size=12)\n",
"valid_losses = nf.models[0].valid_trajectories\n",
"assert valid_losses[-1][1] < 100, 'Validation loss is too high'\n",
"assert valid_losses[-1][1] > 30, 'Validation loss is too low'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "02ee53b9",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Test order of variables does not affect validation loss\n",
"\n",
"AirPassengersPanel_train['zeros'] = 0\n",
"AirPassengersPanel_train['large_number'] = 100000\n",
"AirPassengersPanel_train['available_mask'] = 1\n",
"AirPassengersPanel_train = AirPassengersPanel_train[['unique_id','ds','zeros','y','available_mask','large_number']]\n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=50, scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train,val_size=12)\n",
"valid_losses = nf.models[0].valid_trajectories\n",
"assert valid_losses[-1][1] < 40, 'Validation loss is too high'\n",
"assert valid_losses[-1][1] > 10, 'Validation loss is too low'\n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=50, scaler_type=None)]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train,val_size=12)\n",
"valid_losses = nf.models[0].valid_trajectories\n",
"assert valid_losses[-1][1] < 40, 'Validation loss is too high'\n",
"assert valid_losses[-1][1] > 10, 'Validation loss is too low'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7ba31378",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Test fit fails if variable not in dataframe\n",
"\n",
"# Base Windows\n",
"models = [NHITS(h=12, input_size=24, max_steps=1, hist_exog_list=['not_included'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"test_fail(nf.fit,\n",
" contains='historical exogenous variables not found in input dataset',\n",
" args=(AirPassengersPanel_train,))\n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=1, futr_exog_list=['not_included'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"test_fail(nf.fit,\n",
" contains='future exogenous variables not found in input dataset',\n",
" args=(AirPassengersPanel_train,))\n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=1, stat_exog_list=['not_included'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"test_fail(nf.fit,\n",
" contains='static exogenous variables not found in input dataset',\n",
" args=(AirPassengersPanel_train,))\n",
"\n",
"# Base Recurrent\n",
"models = [LSTM(h=12, input_size=24, max_steps=1, hist_exog_list=['not_included'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"test_fail(nf.fit,\n",
" contains='historical exogenous variables not found in input dataset',\n",
" args=(AirPassengersPanel_train,))\n",
"\n",
"models = [LSTM(h=12, input_size=24, max_steps=1, futr_exog_list=['not_included'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"test_fail(nf.fit,\n",
" contains='future exogenous variables not found in input dataset',\n",
" args=(AirPassengersPanel_train,))\n",
"\n",
"models = [LSTM(h=12, input_size=24, max_steps=1, stat_exog_list=['not_included'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"test_fail(nf.fit,\n",
" contains='static exogenous variables not found in input dataset',\n",
" args=(AirPassengersPanel_train,))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d221479c",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Test passing unused variables in dataframe does not affect forecasts \n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=5, hist_exog_list=['zeros'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train)\n",
"\n",
"Y_hat1 = nf.predict(df=AirPassengersPanel_train[['unique_id','ds','y','zeros','large_number']])\n",
"Y_hat2 = nf.predict(df=AirPassengersPanel_train[['unique_id','ds','y','zeros']])\n",
"\n",
"pd.testing.assert_frame_equal(\n",
" Y_hat1,\n",
" Y_hat2,\n",
" check_dtype=False,\n",
")\n",
"\n",
"models = [LSTM(h=12, input_size=24, max_steps=5, hist_exog_list=['zeros'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train)\n",
"\n",
"Y_hat1 = nf.predict(df=AirPassengersPanel_train[['unique_id','ds','y','zeros','large_number']])\n",
"Y_hat2 = nf.predict(df=AirPassengersPanel_train[['unique_id','ds','y','zeros']])\n",
"\n",
"pd.testing.assert_frame_equal(\n",
" Y_hat1,\n",
" Y_hat2,\n",
" check_dtype=False,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "30890c07-1763-4795-afba-f5ed916245be",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"#| polars\n",
"import polars\n",
"from polars.testing import assert_frame_equal"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7502d18c-62a5-4381-bfdb-bba5300c5290",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"#| polars\n",
"models = [LSTM(h=12, input_size=24, max_steps=5, hist_exog_list=['zeros'], scaler_type='robust')]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(AirPassengersPanel_train, static_df=AirPassengersStatic)\n",
"insample_preds = nf.predict_insample()\n",
"preds = nf.predict()\n",
"cv_res = nf.cross_validation(df=AirPassengersPanel_train, static_df=AirPassengersStatic)\n",
"\n",
"renamer = {'unique_id': 'uid', 'ds': 'time', 'y': 'target'}\n",
"inverse_renamer = {v: k for k, v in renamer.items()}\n",
"AirPassengers_pl = polars.from_pandas(AirPassengersPanel_train)\n",
"AirPassengers_pl = AirPassengers_pl.rename(renamer)\n",
"AirPassengersStatic_pl = polars.from_pandas(AirPassengersStatic)\n",
"AirPassengersStatic_pl = AirPassengersStatic_pl.rename({'unique_id': 'uid'})\n",
"nf = NeuralForecast(models=models, freq='1mo')\n",
"nf.fit(\n",
" AirPassengers_pl,\n",
" static_df=AirPassengersStatic_pl,\n",
" id_col='uid',\n",
" time_col='time',\n",
" target_col='target',\n",
")\n",
"insample_preds_pl = nf.predict_insample()\n",
"preds_pl = nf.predict()\n",
"cv_res_pl = nf.cross_validation(\n",
" df=AirPassengers_pl,\n",
" static_df=AirPassengersStatic_pl,\n",
" id_col='uid',\n",
" time_col='time',\n",
" target_col='target',\n",
")\n",
"\n",
"def assert_equal_dfs(pandas_df, polars_df):\n",
" mapping = {k: v for k, v in inverse_renamer.items() if k in polars_df}\n",
" pd.testing.assert_frame_equal(\n",
" pandas_df,\n",
" polars_df.rename(mapping).to_pandas(),\n",
" )\n",
"\n",
"assert_equal_dfs(preds, preds_pl)\n",
"assert_equal_dfs(insample_preds, insample_preds_pl)\n",
"assert_equal_dfs(cv_res, cv_res_pl)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "906fd509-82f5-431e-86df-d73e928ddeef",
"metadata": {},
"outputs": [],
"source": [
"#| hide,\n",
"#| polars\n",
"# Test predict_insample step_size\n",
"\n",
"h = 12\n",
"train_end = AirPassengers_pl['time'].max()\n",
"sizes = AirPassengers_pl['uid'].value_counts().to_numpy()\n",
"\n",
"for step_size, test_size in [(7, 0), (9, 0), (7, 5), (9, 5)]:\n",
" models = [NHITS(h=h, input_size=12, max_steps=1)]\n",
" nf = NeuralForecast(models=models, freq='1mo')\n",
" nf.fit(\n",
" AirPassengers_pl,\n",
" id_col='uid',\n",
" time_col='time',\n",
" target_col='target', \n",
" )\n",
" # Note: only apply set_test_size() upon nf.fit(), otherwise it would have set the test_size = 0\n",
" nf.models[0].set_test_size(test_size) \n",
" \n",
" forecasts = nf.predict_insample(step_size=step_size)\n",
" n_expected_cutoffs = (sizes[0][1] - test_size - nf.h + step_size) // step_size\n",
"\n",
" # compare cutoff values\n",
" last_cutoff = train_end - test_size * pd.offsets.MonthEnd() - h * pd.offsets.MonthEnd()\n",
" expected_cutoffs = np.flip(np.array([last_cutoff - step_size * i * pd.offsets.MonthEnd() for i in range(n_expected_cutoffs)]))\n",
" pl_cutoffs = forecasts.filter(polars.col('uid') ==nf.uids[1]).select('cutoff').unique(maintain_order=True)\n",
" actual_cutoffs = np.array([pd.Timestamp(x['cutoff']) for x in pl_cutoffs.rows(named=True)])\n",
" np.testing.assert_array_equal(expected_cutoffs, actual_cutoffs, err_msg=f\"{step_size=},{expected_cutoffs=},{actual_cutoffs=}\")\n",
"\n",
" # check forecast-points count per series\n",
" cutoffs_by_series = forecasts.groupby(['uid', 'cutoff']).count()\n",
" assert_frame_equal(cutoffs_by_series.filter(polars.col('uid') == \"Airline1\").select(['cutoff', 'count']), cutoffs_by_series.filter(polars.col('uid') == \"Airline2\").select(['cutoff', 'count'] ), check_row_order=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9fa887b3-4164-4758-931d-8d28a71b19b1",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# Test if any of the inputs contains NaNs with available_mask = 1, fit shall raise error\n",
"# input type is pandas.DataFrame\n",
"# available_mask is explicitly given\n",
"\n",
"n_static_features = 2\n",
"n_temporal_features = 4\n",
"temporal_df, static_df = generate_series(n_series=4,\n",
" min_length=50,\n",
" max_length=50,\n",
" n_static_features=n_static_features,\n",
" n_temporal_features=n_temporal_features, \n",
" equal_ends=False) \n",
"temporal_df[\"available_mask\"] = 1\n",
"temporal_df.loc[10:20, \"available_mask\"] = 0\n",
"models = [NHITS(h=12, input_size=24, max_steps=20)]\n",
"nf = NeuralForecast(models=models, freq='D')\n",
"\n",
"# test case 1: target has NaN values\n",
"test_df1 = temporal_df.copy()\n",
"test_df1.loc[5:7, \"y\"] = np.nan\n",
"test_fail(lambda: nf.fit(test_df1), contains=\"Found missing values in ['y']\")\n",
"\n",
"# test case 2: exogenous has NaN values that are correctly flagged with exception\n",
"test_df2 = temporal_df.copy()\n",
"# temporal_0 won't raise ValueError as available_mask = 0\n",
"test_df2.loc[15:18, \"temporal_0\"] = np.nan\n",
"test_df2.loc[5, \"temporal_1\"] = np.nan\n",
"test_df2.loc[25, \"temporal_2\"] = np.nan\n",
"test_fail(lambda: nf.fit(test_df2), contains=\"Found missing values in ['temporal_1', 'temporal_2']\")\n",
"\n",
"# test case 3: static column has NaN values\n",
"test_df3 = static_df.copy()\n",
"test_df3.loc[3, \"static_1\"] = np.nan\n",
"test_fail(lambda: nf.fit(temporal_df, static_df=test_df3), contains=\"Found missing values in ['static_1']\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a157b6b4-0943-48f9-9427-fa8cf0b15d49",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"#| polars\n",
"# Test if any of the inputs contains NaNs with available_mask = 1, fit shall raise error\n",
"# input type is polars.Dataframe\n",
"# Note that available_mask is not explicitly provided for this test\n",
"\n",
"pl_df = polars.DataFrame(\n",
" {\n",
" 'unique_id': [1]*50,\n",
" 'y': list(range(50)), \n",
" 'temporal_0': list(range(100,150)),\n",
" 'temporal_1': list(range(200,250)),\n",
" 'ds': polars.date_range(start=date(2022, 1, 1), end=date(2022, 2, 19), interval=\"1d\", eager=True), \n",
" }\n",
")\n",
"\n",
"pl_static_df = polars.DataFrame(\n",
" {\n",
" 'unique_id': [1],\n",
" 'static_0': [1.2], \n",
" 'static_1': [10.9],\n",
" }\n",
")\n",
"\n",
"models = [NHITS(h=12, input_size=24, max_steps=20)]\n",
"nf = NeuralForecast(models=models, freq='1d')\n",
"\n",
"# test case 1: target has NaN values\n",
"test_pl_df1 = pl_df.clone()\n",
"test_pl_df1[3, 'y'] = np.nan\n",
"test_pl_df1[4, 'y'] = None\n",
"test_fail(lambda: nf.fit(test_pl_df1), contains=\"Found missing values in ['y']\")\n",
"\n",
"# test case 2: exogenous has NaN values that are correctly flagged with exception\n",
"test_pl_df2 = pl_df.clone()\n",
"test_pl_df2[15, \"temporal_0\"] = np.nan\n",
"test_pl_df2[5, \"temporal_1\"] = np.nan\n",
"test_fail(lambda: nf.fit(test_pl_df2), contains=\"Found missing values in ['temporal_0', 'temporal_1']\")\n",
"\n",
"# test case 3: static column has NaN values\n",
"test_pl_df3 = pl_static_df.clone()\n",
"test_pl_df3[0, \"static_1\"] = np.nan\n",
"test_fail(lambda: nf.fit(pl_df, static_df=test_pl_df3), contains=\"Found missing values in ['static_1']\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "859a474c",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test customized optimizer behavior such that the user defiend optimizer result should differ from default\n",
"# tests consider models implemented using different base classes such as BaseWindows, BaseRecurrent, BaseMultivariate\n",
"\n",
"for nf_model in [NHITS, RNN, StemGNN]:\n",
" # default optimizer is based on Adam\n",
" params = {\"h\": 12, \"input_size\": 24, \"max_steps\": 1}\n",
" if nf_model.__name__ == \"StemGNN\":\n",
" params.update({\"n_series\": 2})\n",
" models = [nf_model(**params)]\n",
" nf = NeuralForecast(models=models, freq='M')\n",
" nf.fit(AirPassengersPanel_train)\n",
" default_optimizer_predict = nf.predict()\n",
" mean = default_optimizer_predict.loc[:, nf_model.__name__].mean()\n",
"\n",
" # using a customized optimizer\n",
" params.update({\n",
" \"optimizer\": torch.optim.Adadelta,\n",
" \"optimizer_kwargs\": {\"rho\": 0.45}, \n",
" })\n",
" models2 = [nf_model(**params)]\n",
" nf2 = NeuralForecast(models=models2, freq='M')\n",
" nf2.fit(AirPassengersPanel_train)\n",
" customized_optimizer_predict = nf2.predict()\n",
" mean2 = customized_optimizer_predict.loc[:, nf_model.__name__].mean()\n",
" assert mean2 != mean"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3db3fe1e",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test that if the user-defined optimizer is not a subclass of torch.optim.optimizer, failed with exception\n",
"# tests cover different types of base classes such as BaseWindows, BaseRecurrent, BaseMultivariate\n",
"test_fail(lambda: NHITS(h=12, input_size=24, max_steps=10, optimizer=torch.nn.Module), contains=\"optimizer is not a valid subclass of torch.optim.Optimizer\")\n",
"test_fail(lambda: RNN(h=12, input_size=24, max_steps=10, optimizer=torch.nn.Module), contains=\"optimizer is not a valid subclass of torch.optim.Optimizer\")\n",
"test_fail(lambda: StemGNN(h=12, input_size=24, max_steps=10, n_series=2, optimizer=torch.nn.Module), contains=\"optimizer is not a valid subclass of torch.optim.Optimizer\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d908240f",
"metadata": {},
"outputs": [],
"source": [
"#| hide\n",
"# test that if we pass in \"lr\" parameter, we expect warning and it ignores the passed in 'lr' parameter\n",
"# tests consider models implemented using different base classes such as BaseWindows, BaseRecurrent, BaseMultivariate\n",
"\n",
"for nf_model in [NHITS, RNN, StemGNN]:\n",
" params = {\n",
" \"h\": 12, \n",
" \"input_size\": 24, \n",
" \"max_steps\": 1, \n",
" \"optimizer\": torch.optim.Adadelta, \n",
" \"optimizer_kwargs\": {\"lr\": 0.8, \"rho\": 0.45}\n",
" }\n",
" if nf_model.__name__ == \"StemGNN\":\n",
" params.update({\"n_series\": 2})\n",
" models = [nf_model(**params)]\n",
" nf = NeuralForecast(models=models, freq='M')\n",
" with warnings.catch_warnings(record=True) as issued_warnings:\n",
" warnings.simplefilter('always', UserWarning)\n",
" nf.fit(AirPassengersPanel_train)\n",
" assert any(\"ignoring learning rate passed in optimizer_kwargs, using the model's learning rate\" in str(w.message) for w in issued_warnings)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
website:
logo: https://github.com/Nixtla/styles/blob/b9ea432cfa2dae20fc84d8634cae6db902f9ca3f/images/Nixtla_Blanco.png
reader-mode: false
navbar:
collapse-below: lg
left:
- text: "Get Started"
href: examples/Getting_Started.ipynb
- text: "Help"
menu:
- text: "Report an Issue"
icon: bug
href: https://github.com/nixtla/neuralforecast/issues
- text: "Slack Nixtla"
icon: chat-right-text
href: https://join.slack.com/t/nixtlaworkspace/shared_invite/zt-135dssye9-fWTzMpv2WBthq8NK0Yvu6A
right:
- icon: twitter
href: https://twitter.com/nixtlainc
aria-label: Nixtla Twitter
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Hyperparameter Optimization"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Deep-learning models are the state-of-the-art in time series forecasting. They have outperformed statistical and tree-based approaches in recent large-scale competitions, such as the M series, and are being increasingly adopted in industry. However, their performance is greatly affected by the choice of hyperparameters. Selecting the optimal configuration, a process called hyperparameter tuning, is essential to achieve the best performance.\n",
"\n",
"The main steps of hyperparameter tuning are:\n",
"\n",
" 1. Define training and validation sets.\n",
" 2. Define search space.\n",
" 3. Sample configurations with a search algorithm, train models, and evaluate them on the validation set.\n",
" 4. Select and store the best model.\n",
"\n",
"With `Neuralforecast`, we automatize and simplify the hyperparameter tuning process with the `Auto` models. Every model in the library has an `Auto` version (for example, `AutoNHITS`, `AutoTFT`) which can perform automatic hyperparameter selection on default or user-defined search space.\n",
"\n",
"The `Auto` models can be used with two backends: Ray's `Tune` library and `Optuna`, with a user-friendly and simplified API, with most of their capabilities.\n",
"\n",
"In this tutorial, we show in detail how to instantiate and train an `AutoNHITS` model with a custom search space with both `Tune` and `Optuna` backends, install and use `HYPEROPT` search algorithm, and use the model with optimal hyperparameters to forecast."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"You can run these experiments using GPU with Google Colab.\n",
"\n",
"<a href=\"https://colab.research.google.com/github/Nixtla/neuralforecast/blob/main/nbs/examples/Automatic_Hyperparameter_Tuning.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Install `Neuralforecast`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"# !pip install neuralforecast hyperopt"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Load Data\n",
"\n",
"In this example we will use the `AirPasengers`, a popular dataset with monthly airline passengers in the US from 1949 to 1960. Load the data, available at our `utils` methods in the required format. See https://nixtla.github.io/neuralforecast/examples/data_format.html for more details on the data input format."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>y</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1.0</td>\n",
" <td>1949-01-31</td>\n",
" <td>112.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1.0</td>\n",
" <td>1949-02-28</td>\n",
" <td>118.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>1949-03-31</td>\n",
" <td>132.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1949-04-30</td>\n",
" <td>129.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1.0</td>\n",
" <td>1949-05-31</td>\n",
" <td>121.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id ds y\n",
"0 1.0 1949-01-31 112.0\n",
"1 1.0 1949-02-28 118.0\n",
"2 1.0 1949-03-31 132.0\n",
"3 1.0 1949-04-30 129.0\n",
"4 1.0 1949-05-31 121.0"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from neuralforecast.utils import AirPassengersDF\n",
"\n",
"Y_df = AirPassengersDF\n",
"Y_df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Ray's `Tune` backend"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we show how to use the `Tune` backend. This backend is based on Ray's `Tune` library, which is a scalable framework for hyperparameter tuning. It is a popular library in the machine learning community, and it is used by many companies and research labs. If you plan to use the `Optuna` backend, you can skip this section."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.a Define hyperparameter grid"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Each `Auto` model contains a default search space that was extensively tested on multiple large-scale datasets. Search spaces are specified with dictionaries, where keys corresponds to the model's hyperparameter and the value is a `Tune` function to specify how the hyperparameter will be sampled. For example, use `randint` to sample integers uniformly, and `choice` to sample values of a list. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.a.1 Default hyperparameter grid\n",
"\n",
"The default search space dictionary can be accessed through the `get_default_config` function of the `Auto` model. This is useful if you wish to use the default parameter configuration but want to change one or more hyperparameter spaces without changing the other default values.\n",
"\n",
"To extract the default config, you need to define:\n",
"* `h`: forecasting horizon.\n",
"* `backend`: backend to use.\n",
"* `n_series`: Optional, the number of unique time series, required only for Multivariate models. \n",
"\n",
"In this example, we will use `h=12` and we use `ray` as backend. We will use the default hyperparameter space but only change `random_seed` range and `n_pool_kernel_size`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ray import tune\n",
"from neuralforecast.auto import AutoNHITS\n",
"\n",
"nhits_config = AutoNHITS.get_default_config(h = 12, backend=\"ray\") # Extract the default hyperparameter settings\n",
"nhits_config[\"random_seed\"] = tune.randint(1, 10) # Random seed\n",
"nhits_config[\"n_pool_kernel_size\"] = tune.choice([[2, 2, 2], [16, 8, 1]]) # MaxPool's Kernelsize"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.a.2 Custom hyperparameter grid\n",
"\n",
"More generally, users can define fully customized search spaces tailored for particular datasets and tasks, by fully specifying a hyperparameter search space dictionary.\n",
"\n",
"In the following example we are optimizing the `learning_rate` and two `NHITS` specific hyperparameters: `n_pool_kernel_size` and `n_freq_downsample`. Additionaly, we use the search space to modify default hyperparameters, such as `max_steps` and `val_check_steps`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"nhits_config = {\n",
" \"max_steps\": 100, # Number of SGD steps\n",
" \"input_size\": 24, # Size of input window\n",
" \"learning_rate\": tune.loguniform(1e-5, 1e-1), # Initial Learning rate\n",
" \"n_pool_kernel_size\": tune.choice([[2, 2, 2], [16, 8, 1]]), # MaxPool's Kernelsize\n",
" \"n_freq_downsample\": tune.choice([[168, 24, 1], [24, 12, 1], [1, 1, 1]]), # Interpolation expressivity ratios\n",
" \"val_check_steps\": 50, # Compute validation every 50 steps\n",
" \"random_seed\": tune.randint(1, 10), # Random seed\n",
" }"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-important}\n",
"Configuration dictionaries are not interchangeable between models since they have different hyperparameters. Refer to https://nixtla.github.io/neuralforecast/models.html for a complete list of each model's hyperparameters.\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.b Instantiate `Auto` model"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"To instantiate an `Auto` model you need to define:\n",
"\n",
"* `h`: forecasting horizon.\n",
"* `loss`: training and validation loss from `neuralforecast.losses.pytorch`.\n",
"* `config`: hyperparameter search space. If `None`, the `Auto` class will use a pre-defined suggested hyperparameter space. \n",
"* `search_alg`: search algorithm (from `tune.search`), default is random search. Refer to https://docs.ray.io/en/latest/tune/api_docs/suggestion.html for more information on the different search algorithm options.\n",
"* `backend`: backend to use, default is `ray`. If `optuna`, the `Auto` class will use the `Optuna` backend.\n",
"* `num_samples`: number of configurations explored."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"In this example we set horizon `h` as 12, use the `MAE` loss for training and validation, and use the `HYPEROPT` search algorithm. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ray.tune.search.hyperopt import HyperOptSearch\n",
"from neuralforecast.losses.pytorch import MAE\n",
"from neuralforecast.auto import AutoNHITS"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model = AutoNHITS(h=12,\n",
" loss=MAE(),\n",
" config=nhits_config,\n",
" search_alg=HyperOptSearch(),\n",
" backend='ray',\n",
" num_samples=10)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-tip}\n",
"The number of samples, `num_samples`, is a crucial parameter! Larger values will usually produce better results as we explore more configurations in the search space, but it will increase training times. Larger search spaces will usually require more samples. As a general rule, we recommend setting `num_samples` higher than 20. We set 10 in this example for demonstration purposes.\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.c Train model and predict with `Core` class"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we use the `Neuralforecast` class to train the `Auto` model. In this step, `Auto` models will automatically perform hyperparamter tuning training multiple models with different hyperparameters, producing the forecasts on the validation set, and evaluating them. The best configuration is selected based on the error on a validation set. Only the best model is stored and used during inference."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from neuralforecast import NeuralForecast"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Use the `val_size` parameter of the `fit` method to control the length of the validation set. In this case we set the validation set as twice the forecasting horizon."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Global seed set to 8\n"
]
}
],
"source": [
"%%capture\n",
"nf = NeuralForecast(models=[model], freq='M')\n",
"nf.fit(df=Y_df, val_size=24)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"The results of the hyperparameter tuning are available in the `results` attribute of the `Auto` model. Use the `get_dataframe` method to get the results in a pandas dataframe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>loss</th>\n",
" <th>time_this_iter_s</th>\n",
" <th>done</th>\n",
" <th>timesteps_total</th>\n",
" <th>episodes_total</th>\n",
" <th>training_iteration</th>\n",
" <th>trial_id</th>\n",
" <th>experiment_id</th>\n",
" <th>date</th>\n",
" <th>timestamp</th>\n",
" <th>...</th>\n",
" <th>config/input_size</th>\n",
" <th>config/learning_rate</th>\n",
" <th>config/loss</th>\n",
" <th>config/max_steps</th>\n",
" <th>config/n_freq_downsample</th>\n",
" <th>config/n_pool_kernel_size</th>\n",
" <th>config/random_seed</th>\n",
" <th>config/val_check_steps</th>\n",
" <th>config/valid_loss</th>\n",
" <th>logdir</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>21.173204</td>\n",
" <td>3.645993</td>\n",
" <td>False</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>2</td>\n",
" <td>e20dbd9b</td>\n",
" <td>f62650f116914e18889bb96963c6b202</td>\n",
" <td>2023-10-03_11-19-14</td>\n",
" <td>1696346354</td>\n",
" <td>...</td>\n",
" <td>24</td>\n",
" <td>0.000415</td>\n",
" <td>MAE()</td>\n",
" <td>100</td>\n",
" <td>[168, 24, 1]</td>\n",
" <td>[16, 8, 1]</td>\n",
" <td>7</td>\n",
" <td>50</td>\n",
" <td>MAE()</td>\n",
" <td>/Users/cchallu/ray_results/_train_tune_2023-10...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>33.843426</td>\n",
" <td>3.756614</td>\n",
" <td>False</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>2</td>\n",
" <td>75e09199</td>\n",
" <td>f62650f116914e18889bb96963c6b202</td>\n",
" <td>2023-10-03_11-19-22</td>\n",
" <td>1696346362</td>\n",
" <td>...</td>\n",
" <td>24</td>\n",
" <td>0.000068</td>\n",
" <td>MAE()</td>\n",
" <td>100</td>\n",
" <td>[24, 12, 1]</td>\n",
" <td>[16, 8, 1]</td>\n",
" <td>4</td>\n",
" <td>50</td>\n",
" <td>MAE()</td>\n",
" <td>/Users/cchallu/ray_results/_train_tune_2023-10...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>17.750280</td>\n",
" <td>8.573898</td>\n",
" <td>False</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>2</td>\n",
" <td>0dc5925a</td>\n",
" <td>f62650f116914e18889bb96963c6b202</td>\n",
" <td>2023-10-03_11-19-36</td>\n",
" <td>1696346376</td>\n",
" <td>...</td>\n",
" <td>24</td>\n",
" <td>0.001615</td>\n",
" <td>MAE()</td>\n",
" <td>100</td>\n",
" <td>[1, 1, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>8</td>\n",
" <td>50</td>\n",
" <td>MAE()</td>\n",
" <td>/Users/cchallu/ray_results/_train_tune_2023-10...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>24.573055</td>\n",
" <td>6.987517</td>\n",
" <td>False</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>2</td>\n",
" <td>352e03ff</td>\n",
" <td>f62650f116914e18889bb96963c6b202</td>\n",
" <td>2023-10-03_11-19-50</td>\n",
" <td>1696346390</td>\n",
" <td>...</td>\n",
" <td>24</td>\n",
" <td>0.003405</td>\n",
" <td>MAE()</td>\n",
" <td>100</td>\n",
" <td>[1, 1, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>5</td>\n",
" <td>50</td>\n",
" <td>MAE()</td>\n",
" <td>/Users/cchallu/ray_results/_train_tune_2023-10...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>474221.937500</td>\n",
" <td>4.912362</td>\n",
" <td>False</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>2</td>\n",
" <td>289bdd5e</td>\n",
" <td>f62650f116914e18889bb96963c6b202</td>\n",
" <td>2023-10-03_11-20-00</td>\n",
" <td>1696346400</td>\n",
" <td>...</td>\n",
" <td>24</td>\n",
" <td>0.080117</td>\n",
" <td>MAE()</td>\n",
" <td>100</td>\n",
" <td>[168, 24, 1]</td>\n",
" <td>[16, 8, 1]</td>\n",
" <td>5</td>\n",
" <td>50</td>\n",
" <td>MAE()</td>\n",
" <td>/Users/cchallu/ray_results/_train_tune_2023-10...</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 29 columns</p>\n",
"</div>"
],
"text/plain": [
" loss time_this_iter_s done timesteps_total episodes_total \\\n",
"0 21.173204 3.645993 False NaN NaN \n",
"1 33.843426 3.756614 False NaN NaN \n",
"2 17.750280 8.573898 False NaN NaN \n",
"3 24.573055 6.987517 False NaN NaN \n",
"4 474221.937500 4.912362 False NaN NaN \n",
"\n",
" training_iteration trial_id experiment_id \\\n",
"0 2 e20dbd9b f62650f116914e18889bb96963c6b202 \n",
"1 2 75e09199 f62650f116914e18889bb96963c6b202 \n",
"2 2 0dc5925a f62650f116914e18889bb96963c6b202 \n",
"3 2 352e03ff f62650f116914e18889bb96963c6b202 \n",
"4 2 289bdd5e f62650f116914e18889bb96963c6b202 \n",
"\n",
" date timestamp ... config/input_size \\\n",
"0 2023-10-03_11-19-14 1696346354 ... 24 \n",
"1 2023-10-03_11-19-22 1696346362 ... 24 \n",
"2 2023-10-03_11-19-36 1696346376 ... 24 \n",
"3 2023-10-03_11-19-50 1696346390 ... 24 \n",
"4 2023-10-03_11-20-00 1696346400 ... 24 \n",
"\n",
" config/learning_rate config/loss config/max_steps \\\n",
"0 0.000415 MAE() 100 \n",
"1 0.000068 MAE() 100 \n",
"2 0.001615 MAE() 100 \n",
"3 0.003405 MAE() 100 \n",
"4 0.080117 MAE() 100 \n",
"\n",
" config/n_freq_downsample config/n_pool_kernel_size config/random_seed \\\n",
"0 [168, 24, 1] [16, 8, 1] 7 \n",
"1 [24, 12, 1] [16, 8, 1] 4 \n",
"2 [1, 1, 1] [2, 2, 2] 8 \n",
"3 [1, 1, 1] [2, 2, 2] 5 \n",
"4 [168, 24, 1] [16, 8, 1] 5 \n",
"\n",
" config/val_check_steps config/valid_loss \\\n",
"0 50 MAE() \n",
"1 50 MAE() \n",
"2 50 MAE() \n",
"3 50 MAE() \n",
"4 50 MAE() \n",
"\n",
" logdir \n",
"0 /Users/cchallu/ray_results/_train_tune_2023-10... \n",
"1 /Users/cchallu/ray_results/_train_tune_2023-10... \n",
"2 /Users/cchallu/ray_results/_train_tune_2023-10... \n",
"3 /Users/cchallu/ray_results/_train_tune_2023-10... \n",
"4 /Users/cchallu/ray_results/_train_tune_2023-10... \n",
"\n",
"[5 rows x 29 columns]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results = nf.models[0].results.get_dataframe()\n",
"results.head()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we use the `predict` method to forecast the next 12 months using the optimal hyperparameters."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 113.97it/s]\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>AutoNHITS</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1.0</td>\n",
" <td>1961-01-31</td>\n",
" <td>442.346680</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1.0</td>\n",
" <td>1961-02-28</td>\n",
" <td>439.409821</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>1961-03-31</td>\n",
" <td>477.709930</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1961-04-30</td>\n",
" <td>503.884064</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1.0</td>\n",
" <td>1961-05-31</td>\n",
" <td>521.344421</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id ds AutoNHITS\n",
"0 1.0 1961-01-31 442.346680\n",
"1 1.0 1961-02-28 439.409821\n",
"2 1.0 1961-03-31 477.709930\n",
"3 1.0 1961-04-30 503.884064\n",
"4 1.0 1961-05-31 521.344421"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Y_hat_df = nf.predict()\n",
"Y_hat_df = Y_hat_df.reset_index()\n",
"Y_hat_df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. `Optuna` backend"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this section we show how to use the `Optuna` backend. `Optuna` is a lightweight and versatile platform for hyperparameter optimization. If you plan to use the `Tune` backend, you can skip this section."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.a Define hyperparameter grid"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Each `Auto` model contains a default search space that was extensively tested on multiple large-scale datasets. Search spaces are specified with a function that returns a dictionary, where keys corresponds to the model's hyperparameter and the value is a `suggest` function to specify how the hyperparameter will be sampled. For example, use `suggest_int` to sample integers uniformly, and `suggest_categorical` to sample values of a list. See https://optuna.readthedocs.io/en/stable/reference/generated/optuna.trial.Trial.html for more details."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.a.1 Default hyperparameter grid\n",
"\n",
"The default search space dictionary can be accessed through the `get_default_config` function of the `Auto` model. This is useful if you wish to use the default parameter configuration but want to change one or more hyperparameter spaces without changing the other default values.\n",
"\n",
"To extract the default config, you need to define:\n",
"* `h`: forecasting horizon.\n",
"* `backend`: backend to use.\n",
"* `n_series`: Optional, the number of unique time series, required only for Multivariate models. \n",
"\n",
"In this example, we will use `h=12` and we use `optuna` as backend. We will use the default hyperparameter space but only change `random_seed` range and `n_pool_kernel_size`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import optuna\n",
"optuna.logging.set_verbosity(optuna.logging.WARNING) # Use this to disable training prints from optuna"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"nhits_default_config = AutoNHITS.get_default_config(h = 12, backend=\"optuna\") # Extract the default hyperparameter settings\n",
"\n",
"def config_nhits(trial):\n",
" config = {**nhits_default_config(trial)}\n",
" config.update({\n",
" \"random_seed\": trial.suggest_int(\"random_seed\", 1, 10), \n",
" \"n_pool_kernel_size\": trial.suggest_categorical(\"n_pool_kernel_size\", [[2, 2, 2], [16, 8, 1]])\n",
" })\n",
" return config "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.a.2 Custom hyperparameter grid\n",
"\n",
"More generally, users can define fully customized search spaces tailored for particular datasets and tasks, by fully specifying a hyperparameter search space function.\n",
"\n",
"In the following example we are optimizing the `learning_rate` and two `NHITS` specific hyperparameters: `n_pool_kernel_size` and `n_freq_downsample`. Additionaly, we use the search space to modify default hyperparameters, such as `max_steps` and `val_check_steps`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def config_nhits(trial):\n",
" return {\n",
" \"max_steps\": 100, # Number of SGD steps\n",
" \"input_size\": 24, # Size of input window\n",
" \"learning_rate\": trial.suggest_loguniform(\"learning_rate\", 1e-5, 1e-1), # Initial Learning rate\n",
" \"n_pool_kernel_size\": trial.suggest_categorical(\"n_pool_kernel_size\", [[2, 2, 2], [16, 8, 1]]), # MaxPool's Kernelsize\n",
" \"n_freq_downsample\": trial.suggest_categorical(\"n_freq_downsample\", [[168, 24, 1], [24, 12, 1], [1, 1, 1]]), # Interpolation expressivity ratios\n",
" \"val_check_steps\": 50, # Compute validation every 50 steps\n",
" \"random_seed\": trial.suggest_int(\"random_seed\", 1, 10), # Random seed\n",
" }"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.b Instantiate `Auto` model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To instantiate an `Auto` model you need to define:\n",
"\n",
"* `h`: forecasting horizon.\n",
"* `loss`: training and validation loss from `neuralforecast.losses.pytorch`.\n",
"* `config`: hyperparameter search space. If `None`, the `Auto` class will use a pre-defined suggested hyperparameter space.\n",
"* `search_alg`: search algorithm (from `optuna.samplers`), default is TPESampler (Tree-structured Parzen Estimator). Refer to https://optuna.readthedocs.io/en/stable/reference/samplers/index.html for more information on the different search algorithm options.\n",
"* `backend`: backend to use, default is `ray`. If `optuna`, the `Auto` class will use the `Optuna` backend.\n",
"* `num_samples`: number of configurations explored."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model = AutoNHITS(h=12,\n",
" loss=MAE(),\n",
" config=config_nhits,\n",
" search_alg=optuna.samplers.TPESampler(),\n",
" backend='optuna',\n",
" num_samples=10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-important}\n",
"Configuration dictionaries and search algorithms for `Tune` and `Optuna` are not interchangeable! Use the appropriate type of search algorithm and custom configuration dictionary for each backend.\n",
":::"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.c Train model and predict with `Core` class"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use the `val_size` parameter of the `fit` method to control the length of the validation set. In this case we set the validation set as twice the forecasting horizon."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Global seed set to 6\n",
"Global seed set to 6\n",
"Global seed set to 1\n",
"Global seed set to 1\n",
"Global seed set to 7\n",
"Global seed set to 4\n",
"Global seed set to 9\n",
"Global seed set to 8\n",
"Global seed set to 7\n",
"Global seed set to 7\n",
"Global seed set to 6\n"
]
}
],
"source": [
"%%capture\n",
"nf = NeuralForecast(models=[model], freq='M')\n",
"nf.fit(df=Y_df, val_size=24)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The results of the hyperparameter tuning are available in the `results` attribute of the `Auto` model. Use the `trials_dataframe` method to get the results in a pandas dataframe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>number</th>\n",
" <th>value</th>\n",
" <th>datetime_start</th>\n",
" <th>datetime_complete</th>\n",
" <th>duration</th>\n",
" <th>params_learning_rate</th>\n",
" <th>params_n_freq_downsample</th>\n",
" <th>params_n_pool_kernel_size</th>\n",
" <th>params_random_seed</th>\n",
" <th>state</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>2.964735e+01</td>\n",
" <td>2023-10-23 19:13:30.251719</td>\n",
" <td>2023-10-23 19:13:33.007086</td>\n",
" <td>0 days 00:00:02.755367</td>\n",
" <td>0.000074</td>\n",
" <td>[24, 12, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>2</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1</td>\n",
" <td>2.790444e+03</td>\n",
" <td>2023-10-23 19:13:33.007483</td>\n",
" <td>2023-10-23 19:13:35.823089</td>\n",
" <td>0 days 00:00:02.815606</td>\n",
" <td>0.026500</td>\n",
" <td>[24, 12, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>10</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2</td>\n",
" <td>2.193000e+01</td>\n",
" <td>2023-10-23 19:13:35.823607</td>\n",
" <td>2023-10-23 19:13:38.599414</td>\n",
" <td>0 days 00:00:02.775807</td>\n",
" <td>0.000337</td>\n",
" <td>[168, 24, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>7</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>3</td>\n",
" <td>1.147799e+08</td>\n",
" <td>2023-10-23 19:13:38.600149</td>\n",
" <td>2023-10-23 19:13:41.440307</td>\n",
" <td>0 days 00:00:02.840158</td>\n",
" <td>0.059274</td>\n",
" <td>[1, 1, 1]</td>\n",
" <td>[16, 8, 1]</td>\n",
" <td>5</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4</td>\n",
" <td>2.140740e+01</td>\n",
" <td>2023-10-23 19:13:41.440833</td>\n",
" <td>2023-10-23 19:13:44.184860</td>\n",
" <td>0 days 00:00:02.744027</td>\n",
" <td>0.000840</td>\n",
" <td>[168, 24, 1]</td>\n",
" <td>[16, 8, 1]</td>\n",
" <td>5</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>5</td>\n",
" <td>1.606544e+01</td>\n",
" <td>2023-10-23 19:13:44.185291</td>\n",
" <td>2023-10-23 19:13:46.945672</td>\n",
" <td>0 days 00:00:02.760381</td>\n",
" <td>0.005477</td>\n",
" <td>[1, 1, 1]</td>\n",
" <td>[16, 8, 1]</td>\n",
" <td>8</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>6</td>\n",
" <td>1.301640e+04</td>\n",
" <td>2023-10-23 19:13:46.946108</td>\n",
" <td>2023-10-23 19:13:49.805633</td>\n",
" <td>0 days 00:00:02.859525</td>\n",
" <td>0.056746</td>\n",
" <td>[1, 1, 1]</td>\n",
" <td>[16, 8, 1]</td>\n",
" <td>3</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>7</td>\n",
" <td>4.972713e+01</td>\n",
" <td>2023-10-23 19:13:49.806278</td>\n",
" <td>2023-10-23 19:13:52.577180</td>\n",
" <td>0 days 00:00:02.770902</td>\n",
" <td>0.000021</td>\n",
" <td>[24, 12, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>9</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>8</td>\n",
" <td>2.138879e+01</td>\n",
" <td>2023-10-23 19:13:52.577678</td>\n",
" <td>2023-10-23 19:13:55.372792</td>\n",
" <td>0 days 00:00:02.795114</td>\n",
" <td>0.007136</td>\n",
" <td>[1, 1, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>9</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>9</td>\n",
" <td>2.094145e+01</td>\n",
" <td>2023-10-23 19:13:55.373149</td>\n",
" <td>2023-10-23 19:13:58.125058</td>\n",
" <td>0 days 00:00:02.751909</td>\n",
" <td>0.004655</td>\n",
" <td>[1, 1, 1]</td>\n",
" <td>[2, 2, 2]</td>\n",
" <td>6</td>\n",
" <td>COMPLETE</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" number value datetime_start datetime_complete \\\n",
"0 0 2.964735e+01 2023-10-23 19:13:30.251719 2023-10-23 19:13:33.007086 \n",
"1 1 2.790444e+03 2023-10-23 19:13:33.007483 2023-10-23 19:13:35.823089 \n",
"2 2 2.193000e+01 2023-10-23 19:13:35.823607 2023-10-23 19:13:38.599414 \n",
"3 3 1.147799e+08 2023-10-23 19:13:38.600149 2023-10-23 19:13:41.440307 \n",
"4 4 2.140740e+01 2023-10-23 19:13:41.440833 2023-10-23 19:13:44.184860 \n",
"5 5 1.606544e+01 2023-10-23 19:13:44.185291 2023-10-23 19:13:46.945672 \n",
"6 6 1.301640e+04 2023-10-23 19:13:46.946108 2023-10-23 19:13:49.805633 \n",
"7 7 4.972713e+01 2023-10-23 19:13:49.806278 2023-10-23 19:13:52.577180 \n",
"8 8 2.138879e+01 2023-10-23 19:13:52.577678 2023-10-23 19:13:55.372792 \n",
"9 9 2.094145e+01 2023-10-23 19:13:55.373149 2023-10-23 19:13:58.125058 \n",
"\n",
" duration params_learning_rate params_n_freq_downsample \\\n",
"0 0 days 00:00:02.755367 0.000074 [24, 12, 1] \n",
"1 0 days 00:00:02.815606 0.026500 [24, 12, 1] \n",
"2 0 days 00:00:02.775807 0.000337 [168, 24, 1] \n",
"3 0 days 00:00:02.840158 0.059274 [1, 1, 1] \n",
"4 0 days 00:00:02.744027 0.000840 [168, 24, 1] \n",
"5 0 days 00:00:02.760381 0.005477 [1, 1, 1] \n",
"6 0 days 00:00:02.859525 0.056746 [1, 1, 1] \n",
"7 0 days 00:00:02.770902 0.000021 [24, 12, 1] \n",
"8 0 days 00:00:02.795114 0.007136 [1, 1, 1] \n",
"9 0 days 00:00:02.751909 0.004655 [1, 1, 1] \n",
"\n",
" params_n_pool_kernel_size params_random_seed state \n",
"0 [2, 2, 2] 2 COMPLETE \n",
"1 [2, 2, 2] 10 COMPLETE \n",
"2 [2, 2, 2] 7 COMPLETE \n",
"3 [16, 8, 1] 5 COMPLETE \n",
"4 [16, 8, 1] 5 COMPLETE \n",
"5 [16, 8, 1] 8 COMPLETE \n",
"6 [16, 8, 1] 3 COMPLETE \n",
"7 [2, 2, 2] 9 COMPLETE \n",
"8 [2, 2, 2] 9 COMPLETE \n",
"9 [2, 2, 2] 6 COMPLETE "
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results = nf.models[0].results.trials_dataframe()\n",
"results.drop(columns='user_attrs_ALL_PARAMS')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we use the `predict` method to forecast the next 12 months using the optimal hyperparameters."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 112.75it/s]\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>AutoNHITS</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1.0</td>\n",
" <td>1961-01-31</td>\n",
" <td>445.272858</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1.0</td>\n",
" <td>1961-02-28</td>\n",
" <td>469.633423</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>1961-03-31</td>\n",
" <td>475.265289</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1961-04-30</td>\n",
" <td>483.228516</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1.0</td>\n",
" <td>1961-05-31</td>\n",
" <td>516.583496</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id ds AutoNHITS\n",
"0 1.0 1961-01-31 445.272858\n",
"1 1.0 1961-02-28 469.633423\n",
"2 1.0 1961-03-31 475.265289\n",
"3 1.0 1961-04-30 483.228516\n",
"4 1.0 1961-05-31 516.583496"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Y_hat_df_optuna = nf.predict()\n",
"Y_hat_df_optuna = Y_hat_df_optuna.reset_index()\n",
"Y_hat_df_optuna.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5. Plots"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we compare the forecasts produced by the `AutoNHITS` model with both backends."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABmcAAAKHCAYAAAB0L5wRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3hUZdrH8e9JJr2SQgoJoSMgIAKCqIBSFAVBFHUtwGJdXX117auuoC52dNeyu7oo2LuydkAUCypFkSotBEIKIaT3Sea8f0xmIKbCzGQS8vtcVy4m5zznOffMmcO65+a+H8M0TRMRERERERERERERERFpFT7eDkBERERERERERERERKQjUXJGRERERERERERERESkFSk5IyIiIiIiIiIiIiIi0oqUnBEREREREREREREREWlFSs6IiIiIiIiIiIiIiIi0IiVnREREREREREREREREWpGSMyIiIiIiIiIiIiIiIq1IyRkREREREREREREREZFWpOSMiIiIiIiIiIiIiIhIK1JyRkRERESOeV9//TWGYWAYBnPnzvV2OCIiIiIiItLBKTkjIiIiIu3CggULnAkWwzB48803vR1SnXh+/xMaGkrXrl2ZPHkyzz77LEVFRd4OV6RZaWlpTX6vG/qZNm2at8OWZsydO5e5c+eyaNEib4ciIiIiIrWUnBERERGRduHFF1+s8/vChQu9FEnLlJaWkp6ezieffMKf//xn+vTpwxdffOHtsESkA5o3bx7z5s1TckZERESkDbF4OwARERERkeb8+OOPbN68uc62L7/8krS0NLp169bs8WPHjsU0TQ9FZ/fBBx/U+b24uJj169fz8ssvk5uby/79+5k6dSorV65kxIgRHo1FxB1iY2N5/vnnmx2XkJDQCtGIiIiIiBxbDNPT/y9VRERERMRFV111Ff/9738B+OMf/8hLL70EwN/+9jfmzZvntbgMw3C+buw/qw8ePMikSZNYs2YNACNHjuSHH35olfhEjlRaWhrdu3cHICUlhbS0NO8GJG7h+LtqzJgxfP31194NRkREREQAtTUTERERkTautLSUt956C4Du3bvzj3/8g9DQUABeeuklbDabN8NrVnR0NIsXL3b+/uOPP7J3714vRiQiIiIiIiLepuSMiIiIiLRpb7/9NsXFxQBcfvnlhIWFcf755wOQnp7OsmXLmp3j66+/di5ePnfu3AbHdOvWDcMwnG3SKisrefbZZxk7diwJCQn4+vq2qIVaQ/r160fv3r2dv2/cuNH5uqKigiVLlnDjjTcyatQoYmNj8fPzIywsjN69e3P55Ze36D0CFBUV8cQTT3D66acTFxeHv78/4eHh9OzZk1GjRvGXv/yFzz//nKqqqgaPz87OZt68eZxyyinExMTg5+dHZGQkffr0YfTo0dx99918/fXXzSbE1q9fz//93/8xePBgoqKiCAgIIDExkXPOOYcXX3yR6urqJo93XKuxY8c6P6N//vOfnHzyyURHRxMUFETPnj255pprSE1NbdFnU1payvz58xk6dCgRERGEhYVx/PHHc/fdd5OVlQXA7NmznedurmKksLCQJ554gvHjx5OYmEhAQABRUVEMHTqUu+66i4yMjCaPb+hcH374IdOnTyclJYWAgIAG4/j222+ZM2cO/fr1IywsDH9/f+Lj4xk4cCDnnXcezz77LLt3727RZ+JplZWV/Otf/+Kss86q8xkNGTKE22+/vdk4G7pvd+zYwS233MKAAQOIjIxs9J6uqKjgP//5D5MnTyY5OZnAwEAiIiI4/vjjufHGG9m+fXuL30dubi4PP/ww48aNc76P4OBgevfuzYwZM1i4cCFFRUUNHrt9+3YWLFjAeeedR+/evQkNDcXf35/OnTszevRoHnzwQXJzc1sUx9Fce8fn57By5UrntsN/tBaNiIiIiBeYIiIiIiJt2CmnnGICJmDu3LnTNE3TXLFihXPbjBkzmp3jq6++co6/7777GhyTkpJiAmZKSoq5e/du8/jjj3ce4/hJSUmpc8zh+5ozatQo59jXXnvNub179+71ztPQz9SpU83i4uJG51+7dq0ZHx/fornWrFlT7/hPP/3UDAsLa9HxBw4caDCGiooKc86cOaZhGE0eP2DAAHPXrl2NvhfHuDFjxpipqanmwIEDG50rJCTEXL58eZOf/datW53Xt6Gf2NhY85tvvjFnzZrl3LZ79+5G53v77bfNqKioJt9jYGCguWjRokbnOPxc27ZtM88///wG53HEUVNTY15zzTUtuj7nnHNOk59HU3bv3t3o9/1IrFu3rsnPHDD9/f3Nxx57rNE5fn/fvvLKK2ZQUFC9eX5/T3/99ddmly5dmjy3r6+vOX/+/Gbfx9NPP22GhIQ0+5nPnj273rGLFy9u0fUKDw83P/7440ZjcOXat+QYwHzppZea/SxERERExL0siIiIiIi0Udu2beP7778H4NRTT6Vnz54AjB07lm7dupGWlsaSJUvIzc0lJibGLeesrKxk+vTpbNq0iZEjR3LBBReQnJxMQUFBnYqXI5WTk+N8HRkZ6XxdVlZGZGQkZ5xxBkOGDCElJYXg4GCKiorYsGEDb731FllZWSxZsoQ5c+bw9ttv15u7rKyMadOmkZ2dDcDQoUM577zz6NKlCyEhIeTn57N161a++uorfv3113rHZ2ZmcuGFF1JSUgLY16U455xziI+PJyAggNzcXDZt2sSXX37ZaMVBdXU1Z511lnM9i7i4OC6++GJOOOEEQkJCyMjI4IMPPuCbb75h8+bNjB49ml9++YXY2NhGP7OioiLOOecctm7dysSJE5k8eTLx8fFkZ2fz8ssvs3btWkpLS/nDH/7Ab7/9RlRUVL05Dhw4wBlnnOGsjunatStz5syhb9++lJSUsHTpUt59912mT5/O4MGDG43F4YUXXuCaa67BNE0sFguTJ0/mjDPOID4+ntLSUr7//ntee+01ysvLmT17Nv7+/vzhD39ocs6bbrqJzz77jJSUFGbOnMlxxx1HVVUVq1evJiAgAIBnnnmG//znPwCEhYVxwQUXMHToUGJjY6mqqmLfvn2sXbuW5cuXN/sePG3Tpk2MGTPG+X3q27cvl19+Ob169aKwsJBPP/2UJUuWUFVVxW233UZlZSV33313k3OuWrWKv//97xiGwaxZszjttNMIDQ0lNTWVpKQk57jPPvuMqVOnYrVaMQyD8ePHc+aZZ5KUlERVVRVr167l5ZdfpqCggL/+9a8A3HXXXQ2e88477+SRRx5x/n7qqacyefJkUlJSsNls7N27l++//55ly5Y1uOZUWVkZhmEwePBgRo8ezXHHHef8ju7bt4/ly5fz+eefU1RUxPnnn8+qVas48cQT683jyrX/4IMPADjvvPMAGDBgAA8++GC9cQ2dV0REREQ8zNvZIRERERGRxtx2223Of9n9wgsv1Nl37733Ovc9+eSTTc5zJJUzjp+HH3642fgOH9+ULVu21Bm7d+9e575PP/3UrKqqavTY0tJS87zzznMe++2339Yb88477zj333LLLU3GsnnzZjMnJ6fOtscee8x5/NNPP93k8T/99JNZXl5eb/udd97pnOMPf/iD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oEGMHz+eXr160alTJwICApzVAvfccw+bN292Vm/83v33389JJ53Eww8/zPfffw9ATk4O77//Pu+//z5gb5/0xBNPMGLEiHrHL168mHHjxvHkk0+yfv16APbu3cvevXt54403MAyDSZMmsWDBgnpJnoKCgiN+7w5NtWny8XGtC3NpaanzdUuSdk2NceU9NtWuC1r2nevatSu//PIL8+fP5+WXX+bgwYNUV1ezdu1a1q5dy5NPPkl4eDj/93//x9133+1MWrW24uJioG6rvKYcXv3hOLYhzX1GrlwfqPs9PDxB4kp1ykUXXcSnn34K2D+Pc845hyFDhpCYmEhwcLCz5dumTZu49957AZx/7x2uvVx7ERERETkySs6IiIiISJtimiYvvvii8/fHH3+cxx9/vEXHLly40OXkTGv629/+5kzMPPvss1x33XWNjv373//e7HyTJ09m8uTJ7N+/n2+//ZYffviBlStX8vPPP2OaJt9//z2nnXYan376KePHj693/MyZM5k5cyZ79+51Hv/VV1+xZcsWTNPk008/5dtvv+X77793roEDdR9g5+fnN1gh5A2HJwjKysqaHX94Muf3Dn+PTz31VJNr4XhKTEwMCxYs4LHHHmPdunWsWrWK77//nhUrVpCXl0dRUREPPPAA33//PcuWLXM5uXU0wsLCKCgoaPKzPFxJSUmdY4/W4dfnpptu4sknnzzqucLDw52vD4/vSHz//ffOxMzAgQNZunRpo5VEfn5+zc7XHq69iIiIiBwZ/RebiIiIiLQpK1euZNeuXUd17DfffMOOHTvcHJFnWK1Wvv76awCGDh3aZGIG6rZtak5cXBwXXHABTzzxBGvXriUtLY0LLrjAed6bb765yeO7du3KpZdeyjPPPMPmzZvZvHkzY8aMAezVDX/961/rjD+85ZRjIfW2wNGmCmjRdyo1NbXRfYe/x02bNrkWmIt8fX056aSTuOmmm3jnnXfYv38/b7/9NhEREQCsWLGCDz74wCuxJSQkAPbvSXZ2drPjt2/f7nx9+PU6Uu68PofP1dx6QY1ZunSp8/X8+fObbPG2e/fuFs/blq+9iIiIiBwZVc6IiIiISJuycOFC5+vzzjuPQYMGNXvM6tWr+eyzzwB48cUXeeihhzwWn7vk5uY6q2Z69erV5NjVq1c7Fzs/Gl27duX1119n5cqVHDhwgE2bNlFQUNDiCpf+/fvz/vvvExsbi81mq7NgOsDYsWP5+OOPAXj//fc55ZRTjjpWdxo+fDj//ve/Afjqq6+cCaqG5OTkNJlYGjNmDIZhYJomH3/8MVVVVfj7+7s95qNhsViYMWMGGRkZzsTbt99+y/nnn9/qsYwcOZKtW7cC8MUXXzBr1qxGxxYXF7Nq1SrA3rZs8ODBR33eE044gcjISAoKCvj222/Jzc1t0ZpFDRk9erTz9Ycffsjf/va3I57j8MRUc/e3o8LmaLT02ju+u0fTflFEREREPEOVMyIiIiLSZhQWFvLee+8B9n8h/txzzzF37txmf5566innHIsXL25w3Ya25vCWWzt37mxy7H333efy+fz8/OjSpYvzd0diqKWioqKc7Z5+v4bKxRdf7Fzn4t///nez76e1nHPOOc6WUa+99hoHDhxodOzTTz/d5PcmJiaGc845B7A/eH/iiSfcG6wbdO/e3fn6SK+vuxyeAHviiSeajOMf//iHs/3Zueee26L2Xo3x9fXlsssuA6CyspK77777qOc68cQTGTBgAAC//PILb7311hHP0dL7e9WqVXz++edHHuTvNHftHW3fWtpuTkREREQ8T8kZEREREWkzXn/9dcrLywGYOHFik62ADtenTx9GjhwJQFZWlkv/Er21hIeH06dPHwDWrVvHu+++W29MTU0NN998c7MPb//5z3/yzjvv1FnU/Pe+/fZbNmzYANjbNh1eVTBv3jy++OILbDZbo8e//vrrzkXXhwwZUmdfly5dnP9qv6ysjDPPPJNffvmlyZg3bdrEtdde2+QYV8XFxfGHP/wBsCf+Lr744gYfTn/yySc8+uijzc734IMPOpNQ99xzD//4xz+arEQoLCzkqaeeYvny5Uf5DuyysrK45ZZbmmzNZrVaef75552/n3DCCS6d82hNmjTJWQGzceNGrr766nrJPID//e9/PPDAA4A9sXL77be7fO6//vWvREVFAfD8889zxx13NHhuh/Lycl566SXefPPNOtsNw+DBBx90/n7FFVfw4YcfNjpPfn6+s0Whw/Dhw52v582bR0VFRb3jNmzYwIwZM5r8Drnr2juSN7/99pvz71gRERER8S61NRMRERGRNuPwlmYzZ848omNnzpzJjz/+6JxnypQpbo3NE2666SbnWjMXXnghF110EWPGjKFTp07s3LmT1157ja1bt3L88ccTEBDAunXrGpzn559/ZvHixURERHDmmWdy4oknkpSUhMViIScnh6+++oqPP/7YmXz5/ZoxX331FXPnzqVz586ceeaZnHDCCSQkJGAYBllZWXz22Wd1Egy/Px7siYtff/2Vzz77jNTUVIYNG8ZZZ53FGWecQZcuXTAMg4MHD7Jp0ya+/vprtm7diq+vr7PtmKc8/vjjLFu2jKysLFasWEH//v2ZM2cOxx13HCUlJSxdupR33nmHqKgoTjjhBL788kuABhdUHzx4MP/973+ZNWsWNpuNm266ieeee47zzjuPfv36ERISQnFxMbt27WL16tWsXLmSqqoqXnnlFZfeQ2VlJQsWLGDBggUMHTqU0047jf79+xMZGUlJSQm7du3ijTfecK6Z06NHDy6++GKXznm0DMPgtddeY+TIkZSUlPDSSy/xww8/MHPmTHr06EFRURGfffZZnXVR5s2bx4knnujyuRMSEnjnnXc455xzqKio4NFHH+W1115jxowZDBo0iLCwMEpLS9mzZw9r167lyy+/pKyszJkkOty0adO45ZZbeOKJJygtLeW8887j1FNPZfLkyaSkpGCaJunp6fzwww98/vnnXHTRRYwdO9Z5/PTp0+natSt79+5l7dq19O3blyuvvJJevXpRVlbGypUrefPNN7FarcyaNYvFixc3+J7cde3Hjx/Phg0bKC0tZcqUKcycOZPY2FgMwwBg4MCBdSrrRERERKQVmCIiIiIibcD69etNwATMiIgIs7y8/IiOz8vLMwMCAkzAtFgsZnZ2tnPfV1995Zz7vvvua/D4lJQUEzBTUlJafE7HnEf7n9U2m82cM2dOnXl+/zNw4EAzNTXVHDNmTKPn+uMf/9jkHI4fPz8/88EHH6x3/Omnn96i40NCQswXX3yx0fdjtVrN2267zfTz82vRfI191o79Y8aMafYzbOpzcdiyZYvZtWvXRuOIjo42v/76a/PSSy91bsvLy2t0vqVLl5pJSUkteo8BAQHmZ599Vm+OWbNmOcfs3r27yfeYlpbWonMB5vHHH2/u3Lmz2c+tMbt37272+rTE2rVrnfdUYz/+/v7mI4880ugcLblvG/Lzzz+bxx13XIs+L19fX/OFF15odK7HH3/cDAwMbHaeP/7xjw1+BjExMU2e++GHH27yfbrr2mdkZJhxcXGNHvvSSy+1+PMVEREREfdQ5YyIiIiItAmHV83MmDGDwMDAIzq+U6dOTJkyhXfffZfq6moWL17sllZJnmQYBgsXLuScc87h+eefZ+3atRQVFREdHU3fvn2ZMWMGV1xxRbOfxb///W9mz57NV199xXfffce2bds4cOAA1dXVhIeH07t3b8aOHcsVV1xB79696x3/8ccf89133/HVV1+xatUqdu7cSW5uLqZpEhkZyXHHHcf48eO58sorSUxMbDQOi8XCo48+yp///GdefPFFVqxYwY4dO8jLy8PHx4fo6Gj69OnDiBEjOPPMM+ssvO5J/fr1Y8uWLfzjH//g3XffZefOnZimSXJyMlOmTOHGG2+kS5cuPPzww8734VhfpyETJkxwVix88sknrF27lgMHDlBRUUFYWBjdunVj8ODBnHHGGUyZMoXIyEiX4k9JSWHv3r189dVXfPXVV/z888/s3buX4uJi/P39iY+PZ8iQIZx//vlceOGFWCze/795Q4cOZdu2bSxcuJAlS5awYcMGDh48SEhICCkpKUyYMIHrrruuzlop7jJkyBA2b97MBx98wJIlS/jxxx/Zv38/paWlhIaGkpyczMCBAzn99NOZMmVKk+0Tb7nlFi655BKef/55li5dyo4dO8jPz8ff358uXbpw4oknMmnSpDpr7Rz+GWzYsIEnnniCjz/+mD179mCxWEhMTOT000/n6quv5sQTT6zXEu1w7rr2iYmJ/PzzzzzxxBMsX76c3bt3U1JS0mRLNRERERHxLMPUf42JiIiIiEgHZ7PZiI+P58CBAwwePJj169d7OyQRERERETmG1W+kLCIiIiIi0sG89dZbHDhwAIDTTz/dy9GIiIiIiMixTskZERERERE5pv34449UVFQ0uv+7777j+uuvB8DHx4err766tUITEREREZEOyvvNiEVERERERDzo4Ycf5ptvvmHSpEkMGzbMuW5ORkYGy5cv5/PPP3euvXH77bfTr18/b4YrIiIiIiIdgNacERERERGRY9q0adNYsmRJk2MMw+CWW27hkUcewcdHDQZERERERMSzlJwREREREZFj2s6dO/nf//7HsmXL2LVrFwcPHqSoqIiwsDC6du3KmDFjuPrqqxkwYIC3QxURERERkQ5CyRkREREREREREREREZFWpDVnXGCz2cjMzCQsLAzDMLwdjoiIiIiIiIiIiIiIeJFpmhQXF5OYmNhky2QlZ1yQmZlJcnKyt8MQEREREREREREREZE2JD09naSkpEb3KznjgrCwMMD+IYeHh3s5GpGGWa1Wli5dysSJE/Hz8/N2OCLHLN1rIp6n+0zE83SfiXie7jMRz9N9JtI6dK81rKioiOTkZGf+oDFKzrjA0cosPDxcyRlps6xWK8HBwYSHh+svSREP0r0m4nm6z0Q8T/eZiOfpPhPxPN1nIq1D91rTmlsKpfGGZyIiIiIiIiIiIiIiIuJ2Ss6IiIiIiIiIiIiIiIi0IiVnREREREREREREREREWpGSMyIiIiIiIiIiIiIiIq1IyRkREREREREREREREZFWpOSMiIiIiIiIiIiIiIhIK7J4O4Cj0a1bN/bs2VNv+3XXXcezzz6LaZrMmzeP559/nvz8fEaMGMGzzz7LgAEDnGMrKyu59dZbeeONNygvL2fcuHE899xzJCUleTx+q9VKTU2Nx88jxzZfX1/8/Py8HYaIiIiIiIiIiIiIHKF2mZxZs2ZNneTGpk2bmDBhAjNmzADg0UcfZcGCBSxatIg+ffrw4IMPMmHCBLZt20ZYWBgAN910Ex999BFvvvkm0dHR3HLLLUyePJl169bh6+vrkbiLiorIzc2lsrLSI/NLxxMQEEBMTAzh4eHeDkVEREREREREREREWqhdJmdiY2Pr/P7www/Ts2dPxowZg2maPPXUU9x9991Mnz4dgMWLFxMXF8frr7/ONddcQ2FhIQsXLuSVV15h/PjxALz66qskJyezfPlyzjzzTLfHXFRUREZGBqGhocTExODn54dhGG4/j3QMpmlitVopLCwkIyMDQAkaERERERERERERkXaiXSZnDldVVcWrr77KX/7yFwzDIDU1lezsbCZOnOgcExAQwJgxY1i1ahXXXHMN69atw2q11hmTmJjI8ccfz6pVqxpNzlRWVtapeikqKgLsbcqsVmuTcebk5BASEkJiYqKSMuIWAQEBhISEkJGRwYEDBwgKCmpwnOO72dx3VERco3tNxPN0n4l4nu4zEc/TfSbiebrPRFqH7rWGtfTzaPfJmQ8//JCCggJmz54NQHZ2NgBxcXF1xsXFxTnXqcnOzsbf359OnTrVG+M4viEPPfQQ8+bNq7d96dKlBAcHN3qcj48PCQkJJCYmUlxc3KL3JdJSFouFnJwctmzZgs1ma3TcsmXLWjEqkY5L95qI5+k+E/E83Wcinqf7TMTzdJ+JtA7da3WVlZW1aFy7T84sXLiQSZMmkZiYWGf776tTTNNstmKluTF33XUXf/nLX5y/FxUVkZyczMSJE5tsKVVRUUF6ejoRERGNVjeIHC0/Pz8KCgo4/fTTCQgIqLffarWybNkyJkyYgJ+fnxciFOkYdK+JeJ7uMxHP030m4nm6z0Q8T/eZSOvQvdYwR8et5rTr5MyePXtYvnw577//vnNbfHw8YK+OSUhIcG7PyclxVtPEx8dTVVVFfn5+neqZnJwcRo0a1ej5AgICGnz47efn1+SXr6amBsMw8PX1xcfHp+VvUKQFfH19MQwDi8XS5Pewue+piLiH7jURz9N9JuJ5us9EPE/3mYjn6T4TaR261+pq6WfRrjMFL730Ep07d+acc85xbuvevTvx8fF1SqmqqqpYuXKlM/EydOhQ/Pz86ozJyspi06ZNTSZnREREREREREREREREXNVuK2dsNhsvvfQSs2bNwmI59DYMw+Cmm25i/vz59O7dm969ezN//nyCg4O55JJLAIiIiOCKK67glltuITo6mqioKG699VYGDhzI+PHjvfWWRERERERERERERESkA2i3yZnly5ezd+9e5syZU2/f7bffTnl5Oddddx35+fmMGDGCpUuXEhYW5hzz5JNPYrFYuPDCCykvL2fcuHEsWrQIX1/f1nwbIiIiIiIiIiIiIiLSwbTb5MzEiRMxTbPBfYZhMHfuXObOndvo8YGBgTz99NM8/fTTHopQRERERERERERERESkvna95oyIiIiIiIiIiIiIiEh7o+SMiIiIiIiIiIiIiIhIK1JyRkREREREREREREREpBUpOSNesWbNGgzD4JRTTml0zLx58zAMgwcffLAVIxMRERERERERERFpO2psNTz444M8vuZxb4cibqTkjHjF8OHDGTp0KKtWrWLz5s319ttsNl566SV8fX354x//6IUIRURERERERERERLzv+Y3P89a2t1i8ZTG55bneDkfcxOLtAARM06TcWuPtMFosyM8XwzBcnueaa67h6quv5r///S9PPvlknX1Lly5lz549TJkyhS5durh8LhEREREREREREZH2Zm32Wv7967+dv+8t2ktMUIwXIxJ3UXKmDSi31tD/b194O4wW23L/mQT7u/7VueSSS7j11lt55ZVXePjhhwkICHDu++9//wvAVVdd5fJ5RERERERERERERNqbgooC7vj2Dmymzbltb/FeTow70YtRibuorZl4TUhICJdeeikHDx7kgw8+cG7Pycnhf//7H4mJiZx99tlejFBERERERERERESk9Zmmyb2r7iWnLIdu4d2Y0mMKYK+ckWODKmfagCA/X7bcf6a3w2ixID9ft8117bXX8q9//YsXXniBiy++GIBFixZhtVqZM2cOvr7uO5eIiIiIiIiIiIhIe/D6b6/zdfrX+Pn48ejoR1mdvZqPUj9ib7GSM8cKJWfaAMMw3NImrD0aNGgQI0eO5KuvvmLXrl307NmThQsXYhgGV1xxhbfDExEREREREREREWlVv+X9xhNrnwDglmG30C+6H9ml2YAqZ44lamsmXnfttddimiYLFy5k5cqVbN++nQkTJtCtWzdvhyYiIiIiIiIiIiLSasqsZdy28jasNitjk8dyyXGXAJASngJAenE6pml6M0RxEyVnxOsuvPBCOnXqxKJFi/jXv/4FwFVXXeXlqERERERERERERERa1/yf5pNWlEbn4M48MOoBDMMAoEtYFwwMSqwl5FfmezlKcQclZ8TrgoKCmDlzJllZWbz11lvExsYydepUb4clIiIiIiIiIiIi0mo+Tv2YJbuW4GP48MhpjxAZGOncF+AbQHxIPKDWZscKJWekTbjmmmucr2fPno2fn58XoxERERERERERERFpPXuL9vLADw8AcO2gaxkWP6zemK5hXe1ji5WcORYoOSNtQr9+/UhMTATgyiuv9HI0IiIiIiIiIiIiIq3DWmPltm9uo6y6jKFxQ7l60NUNjusaXpucUeXMMUHJGWkTVq1aRWZmJmPGjKFPnz7eDkdERERERERERESkVTz181NsObiFiIAIHj7tYXx9fBscp8qZY4uSM9ImzJ8/H4A///nPXo5EREREREREREREpHX8lruZl7e8DMADJ97qXFemIcnhyQCkF6W3SmziWRZvByAd16pVq1i4cCGbNm1i9erVDB06lOnTp3s7LBEREREREREREZFW8cumNwA4payc09/4I3RfBMefD/2mQFBknbGOypk9xXswTRPDMFo5WnEnVc6I12zfvp0XX3yRrVu3MmXKFN5//318fPSVFBERERERERERkY5hV95vAPStBkwbpH4F//szPN4b3vgDbHwXqkoBSApLAqC4qpjC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bzc55zXXXAPYq2/efvttoqKimD59uhujFhEREREREREREWncroyfAOhprcGI7HrkE/iHQHgXAJIDowHYW6TWZu2RkjPSJp1wwglMnTqV6upqHn30Uef2Pn3sfRj//e9/1xn/7rvv8vLLLzc55/Tp04mNjeX555+nrKyMmTNnEhAQ4P7gRURERERERERERBqQmrMegB6+weDje3ST1FbPpPgEAVp3pr1SckbarLlz52IYBi+++CLZ2dmAveWZr68vd955J8OGDeOSSy5h+PDhzJgxg5tvvrnJ+fz9/fnjH//o/P3KK6/0aPwiIiIiIiIiIiIih0st2AVAj6C4o58kxr6GdnKNDYD04nSX45LWp+SMtFmDBw/mvPPOo6KiggULFgAwevRovvvuO8444wxSU1P5+OOP8ff357333uP6669vds5x48YBMGrUKAYMGODR+EVEREREREREREQOt6tsPwA9I3sd/STR9uRM1/ISAPYU7WlqtLRRFm8HIB2XaZrNjnnvvffqbRs5ciRffvnlUc357rvvAnDVVVe1IEIRERERERERERER96i2VZNWUwoG9Ig74egnirEndroW5kAIpBepcqY9UuWMdBh79uzh1VdfJSYmhosuusjb4YiIiIiIiIiIiEgHsq84HasBgTYbiV1OOvqJHJUzefaKmZzyHMqsZe4IUVqRkjNyzHvssce4/PLLGTFiBOXl5dx7770EBQV5OywRERERERERERHpQFKzfwGgu7Uan9oEy1GJSALfACKqq4jwCwNgX8k+d4QorUjJGTnmffLJJ7z66qtYLBbmzZvHDTfc4O2QREREREREREREpINJzV4HQA8jAPwCj34iH1+I7glA14BOgFqbtUdac0aOeV9//bW3QxAREREREREREZEOblf+dgB6Bsa4Pll0L8jZQrLhz0ZgT/Ee1+eUVqXKGRERERERERERERERD0stzQSgR0R31yeLqV13xloDwN6iva7PKa1KyRkREREREREREREREQ+ymTZ2VxcD0CN2oOsT1q5Z07W8CID0YrU1a2+UnBERERERERERERER8aCs0izKMbGYJsmJI1yf0FE5U7gfgL3Fqpxpb5ScERERERERERERERHxoF0HNgHQzWrF0vk41yeM7gVA18JsALJLs6mornB9Xmk1Ss6IiIiIiIiIiIiIiHjQ7qw1APSw+UJQJ9cnDIqEkFgibTbCLMEA7Cve5/q80mqUnBERERERERERERER8aBdB38DoGdAlPsmje6FAST7RQBqbdbeKDkjIiIiIiIiIiIiIuJBu4rTAegR1tV9k9a2Nksx/ABIrz2HtA9KzoiIiIiIiIiIiIgcIyqsNZim6e0w5DCmaZJqLQCgR8wA900c0xuA5CorAHuLVDnTnig5IyIiIiIiIiIiInIM2JlTzKC5S7nlnV+VoGlDDpQfoAQbPqZJt8Th7ps42p6c6VpWAMCe4j3um1s8TskZERERERERERERkWPAql0Hqaqx8f7PGbz/c4a3w5Fau/K2A9DVWo1/Z/dXznQtyAIgvUhtzdoTJWfE63Jzc7n33nsZMmQIkZGRBAcH06tXL66++mo2bdrk7fBERERERERERETahX355c7Xc/+3mYyC8iZGS2tJzVoNQI8aE8IT3Tdxp27gY6FreQkAWaVZVNVUuW9+8SglZ8Srli9fTu/evXnwwQfJyMhgzJgxTJ48GT8/P1544QVOOOEEHn74Ybeca/bs2RiGwddff+2W+URERERERERERNqSffllAFh8DIorq7n17V+x2dTezNt2HbD/A/QefhFgGO6b2NcPOnUjymYjxDcQE5N9JfvcN794lJIz4jVr1qzhnHPOobCwkIceeojMzEyWLFnC22+/zdatW/nkk08IDw/nrrvu4p///Ke3wxUREREREREREWnT0vPslTJ3TjqOID9ffkg9yKJVad4NSkgt3gtAj9Ak908e3QsD6GoJA9TarD1Rcka8wjRNZs2aRVVVFffffz933nknFoulzpizzz6bDz/8EMMwuOOOO9izRwtaiYiIiIiIiIiINMZROXNq7xj+ek4/AB75/Dd25hR7M6wOL7XyIAA9o49z/+TRvQBIxheAPUV6htpeKDkjXvHZZ5+xdetWunTpwh133NHouNGjRzNjxgwqKip49tlnndu7deuGYRiYpsk//vEP+vfvT2BgIF26dOHGG2+koKCgzjyGYbB48WIATj/9dAzDcP6kpaUBzbc9MwyDbt261dm2aNEiDMNg7ty57N27l0suuYTY2FiCgoIYNmwYH330Ub15TNPkjTfe4OKLL6ZPnz6EhIQQFhbGSSedxHPPPYfNZmv+AxQRERERERERETlMSWU1+WVWALpEBnHZiK6M7hNLZbWNm9/6FWuNnjl5Q15FHvlmNQDd4oe6/wQxvQHoWlkJwN7aKh1p+5ScEa/49NNPAZgxYwZ+fn5Njr3kkksAe0Ln92644QZuu+02kpKSmDp1KjU1NTz99NOMGTOG4uJD/yJg1qxZ9OzZE4AzzzyTWbNmOX9CQ0Ndfj9paWkMHz6c77//nlNPPZUhQ4awbt06pk2bxtKlS+uMrays5JJLLmHp0qV07tyZKVOmMGLECDZv3sz111/PnDlzXI5HREREREREREQ6FkfVTGSwH2GBfhiGwaPnDyIiyI+NGYU8s2KnlyPsmFILdgHQxVpNcNxA958gujY5U5oPQHqx2pq1F5bmh4inmaZJeXW5t8NosSBLEIaLC1etX78egKFDm88WO8Zs2bIFq9VaJ5nzyiuv8MMPPzjHlJSUMHXqVFasWMF9993HggULAHuFy+zZs9m1axd33nknY8eOdSn+31u8eDE33HADCxYscLZn+8c//sFNN93Egw8+yMSJE51jLRYL7733HpMnT8bf39+5/cCBA5x99tksXryYOXPmMHr0aLfGKCIiIiIiIiIixy7HejPJnYKd2+IjAnlg2vHc+MYvPPPVTs44rjODkyO9FGHHlJr9MwA9rNUQ1d39J3BUzhTuh5A49hapcqa9UHKmDSivLmfE6yO8HUaL/XTJTwT7BTc/sAkHD9r7LHbu3LnZsbGxsQDYbDby8vKIi4tz7vvzn/9cJ8ETGhrKM888w4ABA1i4cCEPPfQQAQEBLsXaEj169OCJJ56os27O9ddfz7x58/jxxx+pqqpyJmIsFgvTp0+vN0dsbCwPPfQQEyZMYMmSJUrOiIiIiIiIiIhIizkqZ5I6BdXZfu7gRJZuzubjDVnc/PZ6PrnhNIL8fb0RYoe0K+dXAHpaQsG36Q5CRyUkFgIi6Fpt7yKUWZqJtcaKnyfOJW6l5Ix4hWmadf5syVigXsXOxRdfXG98v379GDx4MOvXr2fDhg0MHz7cxWibN3bs2Hrt2SwWCz169GDdunUcPHiQhISEOvvXr1/P0qVL2bNnD2VlZZim6WzFtmPHDo/HLCIiIiIiIiIix459+bWVM1H1/1H1g9OOZ/XuPFIPlPLI578x99wBrR1eh7WrcDcAPYLjPXMCw4CYXsRkrCPQx48Km5Ws0iy6hnf1zPnEbZScaQOCLEH8dMlP3g6jxYIsQc0PakZMTAzbtm0jJyen2bEHDhwA7ImZTp061dmXkpLS4DHdunVj/fr1ZGZmuhxrSyQlJTW43bGeTWXtglwAVVVVzJ49mzfeeKPR+Q5fL0dERERERERERKQ56XkNV84ARAb78+gFg5j90hoWrUpjQv84TukV09ohdki7y+3PNnt06uO5k0T3xshYR5JvCDttBaQXpys50w74eDsAsScdgv2C282Pq+vNAAwePBiAdevWNTvWMWbAgAH1qlMa05KKnCNhs9ma3H8kn8mCBQt44403OP744/nss8/Yv38/VVVVmKbJtm3bAPfHLyIiIiIiIiIixzZn5UynhpcjGNu3M5eOsD+wv/WdXykst7ZabB1VUVUROab9H233iD/RcyeK7gVAkml/3L+veJ/nziVuo+SMeMWkSZMAePfdd7Fam/4fgtdffx2As846q96+PXv2NHjM3r32ha8SExNbHJNjTZiSkpJ6+9LT01s8T3M++OADAN544w3OOussOnfu7Ew6paamuu08IiIiIiIiIiLScaQ3subM4e4+px8p0cFkFVYw76PNrRVah5VaYH/W17m6mrC4gZ47UUxtcqbSnqBLL3bfs0zxHCVnxCvOPvts+vbtS0ZGBo888kij47755hveffdd/P39uf766+vtf+utt+pt++2331i/fj1hYWEMGjTIud2RfKmurm7wXI41YbZv315v39KlS5t+Q0cgPz8fgOTk5Hr73n77bbedR0REREREREREOobCcivFFfZnXl2aSM4E+1t4Yoa9o80Hv2RQYa1plfg6qtQDGwHoYbVCjGfbmgEkl+QBsK9ElTPtgZIz4hU+Pj4sWrQIPz8//va3v/HII49QU1P3fww+++wzpk2bhmmaPPzww3Tr1q3ePM888wy//PKL8/fS0lJuuOEGTNNkzpw5BAQEOPc5qmgcrcN+b8yYMQD861//4uDBg87tP//8M/fee+9Rv9ff69PH/hfxv//97zrb3333XV5++WW3nUdERERERERERDoGx3ozMaH+BPs3vcz40JROBPr5YJqwv6iiNcLrsHbv/xWAHgRCQKjnThTdEzBIKrevY63Kmfah3SZnMjIyuOyyy4iOjiY4OJgTTjihzvolpmkyd+5cEhMTCQoKYuzYsWzeXLdUr7KykhtuuIGYmBhCQkI499xz2bdPWcXWMnLkSP73v/8RHh7OnXfeSWJiItOmTeOiiy6i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u2TWJkASg+O8G0ht5YxPcTZJYUmA1p1pi5ScEREREREREREREWlH9uXbK2dcXW8GDl9zptzluTq6rMp8ABLCU7wbSG3lDEVZJIXakzNad6btUXJGREREREREREREpB3Z587KmdrkzP6iSpfn6ugya+zXJTGqj3cDqa2cwVpKcnBnAPaVqHKmrVFyRkRERERERERERKQdSa9dcyapk+uVM47kTEllNcUVVpfn67CqysjyMQFIjBvk3Vj8gyEwAoAkSyigtmZtkZIzIiIiIiIiIiIictTySqswTdPbYXQo7qycCfa3EB5oAbTujCvKcreR7+sLQEK0lytnAMLsrc2SDT9AyZm2SMkZEREREREREREROSrPfrWToQ8u4/Gl27wdSodhrbE514dJdkPlDEBChH2eLCVnjlp2zq8AhJoQ7h/u5WiAcHtrs6Rqe+I0vThdSdQ2RskZEREREREREREROWLPrNjBY19swzRhTVq+t8PpMLILK7CZEGDxITYswC1zOlqbqXLm6GUetCcoE3wCvRxJrdrKmS6V9hZ4JdYSCioLvBiQ/J7LyZmysjLKysoa3f/0009z2mmn0a9fP84++2w+/vhjV08pIiIiIiIiIiIiXvT0lzt4fOl25+96qN96HOvNdOkUhGEYbpkzoTY5o8qZo5dZuBuARP9I7wbiUFs5E1hygM5BnQG1NmtrXErOfPTRR4SFhZGYmEhxcXG9/XPmzOGmm25i1apVbNu2jS+++IKpU6fy6KOPunJaERERERERERER8ZKnv9zBE8vsiZnLRnYFaqs5bGqZ1Boc680ku2G9GQdn5UxRudvm7GgyS/cDkBAS5+VIaoXZkzMUZ5EUlgTYW5tJ2+FScuaLL77ANE2mTZtGWFhYnX3fffcdixYtAiA4OJghQ4YQGBiIaZrcc889bN682ZVTi4iIiIiIiIiISCv752GJmdvO7Mt9UwZgGFBVYyOvrMrL0XUM+/LtlTNJblpvBg5VzqgC6uhlVtpb+yWGpXg5klrh9rZmFGU6kzP7SlQ505a4lJz58ccfMQyD008/vd6+559/HoDExES2bt3KunXr+O2330hOTqampob//Oc/rpxaREREREREREREWtE/v9zBgtrEzO1n9eX603vh5+tDbKh93ZOsAj3Ybw3ptZUzSW6snIkLV1szl5gmWTb7Z5cQ3cfLwdQ6rHIm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MCpqKtiRv8OLgXVcLiVn+vTpw7333otpmjzwwAOMGDGCRx991Ln/888/55FHHmHcuHGMGDGC3bt3YxgGDz/8MAkJ7aAXn4iIiIiIiIiISAdgmia73ZCccSwmn11Ygc2mxeRddSg5463KGbWnA+DAdvj2cfvrSQ+zNPsHAMYmj8Xf19+LgR2B8Nrn8bWVMz6GDwNjBwJqbeYtFlcnuPfee7FarcyfP581a9awdu1aDMMA4LbbbnOOM00TwzD429/+xo033ujqaUVERERERERERMRNckuqKKmsxjAgOSr4qOeJCw/EMGoXky+rcq5dIkfH0dastZMzcbVJNq05A9hs8PFNUFMFvSZg6z+NZe9NBGBit4neje1IhNW2NautnAEYFDuIVZmr2JC7gYu4yEuBdVwuVc443H///fz4449Mnz6doKAgTNOs8+Pn58ekSZP49ttvue+++9xxShEREREREREREXGTtIP2qpnEiCAC/XyPep7DF5NXazPX5JVWkVtSCUCvzq3b1sxRObNfbc1g/auw53vwC4ZznmBD7kZyynII8Qvh5MSTvR1dy/2ucgZgUMwgQJUz3uJy5YzDsGHDePfdd6murmbLli3k5ORQU1NDdHQ0AwYMICgoyF2nEhERERERERERETdyR0szh8SIQA4UV5JZUM7xXSJcnq+jcrQ0S44KIiTAbY9xW8S55kxHT7CV5MDSe+2vT78bOqWwdM1bgL2lWYBvO6oMa6ByZmCMva1ZWlEaBRUFRAZGeiGwjsvtd7XFYmHQoEHunlZEREREREREREQ8JK02OdMt5uhbmjnERwTy675CslV14ZIdjvVmOrduSzOAhAj7P7TPLCinxmbi62O0egxtwud3QUUBJAyGEddiM20s27MMgIkp7ailGRxWOXMoORMZGEm38G6kFaWxMXcjpyWd5qXgOia3tDUTERERERERERGR9svR1qxbtOuVM4ce7Cs54wrHejO9W3m9GYDkTkGEBliosNqcFTwdzo7lsOldMHxgyj/A18LG3I1kl2YTbAlmVOIob0d4ZByVM2UHobrSuXlQbG1rs1y1NmttSs6IiIiIiIiIiEibsGN/MVe9vJbVu/O8HUqHszu3DHBPWzPHeiXZheUuz9WRbatNivSNb931ZgAsvj4M6RoJwNq0Dng/VpXCJzfbX4/4EyQOAWBZmr1qZkzyGAIt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",
"text/plain": [
"<Figure size 2000x700 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots(1, 1, figsize = (20, 7))\n",
"plot_df = pd.concat([Y_df, Y_hat_df]).reset_index()\n",
"\n",
"plt.plot(plot_df['ds'], plot_df['y'], label='y')\n",
"plt.plot(plot_df['ds'], plot_df['AutoNHITS'], label='Ray')\n",
"plt.plot(Y_hat_df_optuna['ds'], Y_hat_df_optuna['AutoNHITS'], label='Optuna')\n",
"\n",
"ax.set_title('AirPassengers Forecast', fontsize=22)\n",
"ax.set_ylabel('Monthly Passengers', fontsize=20)\n",
"ax.set_xlabel('Timestamp [t]', fontsize=20)\n",
"ax.legend(prop={'size': 15})\n",
"ax.grid()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### References\n",
"- [Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021). NHITS: Neural Hierarchical Interpolation for Time Series Forecasting. Accepted at AAAI 2023.](https://arxiv.org/abs/2201.12886)\n",
"- [James Bergstra, Remi Bardenet, Yoshua Bengio, and Balazs Kegl (2011). \"Algorithms for Hyper-Parameter Optimization\". In: Advances in Neural Information Processing Systems. url: https://proceedings.neurips.cc/paper/2011/file/86e8f7ab32cfd12577bc2619bc635690-Paper.pdf](https://proceedings.neurips.cc/paper/2011/file/86e8f7ab32cfd12577bc2619bc635690-Paper.pdf)\n",
"- [Kirthevasan Kandasamy, Karun Raju Vysyaraju, Willie Neiswanger, Biswajit Paria, Christopher R. Collins, Jeff Schneider, Barnabas Poczos, Eric P. Xing (2019). \"Tuning Hyperparameters without Grad Students: Scalable and Robust Bayesian Optimisation with Dragonfly\". Journal of Machine Learning Research. url: https://arxiv.org/abs/1903.06694](https://arxiv.org/abs/1903.06694)\n",
"- [Lisha Li, Kevin Jamieson, Giulia DeSalvo, Afshin Rostamizadeh, Ameet Talwalkar (2016). \"Hyperband: A Novel Bandit-Based Approach to Hyperparameter Optimization\". Journal of Machine Learning Research. url: https://arxiv.org/abs/1603.06560](https://arxiv.org/abs/1603.06560)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data Inputs\n",
"> Dataset input requirments"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"In this example we will go through the dataset input requirements of the `core.NeuralForecast` class.\n",
"\n",
"The `core.NeuralForecast` methods operate as global models that receive a set of time series rather than single series. The class uses cross-learning technique to fit flexible-shared models such as neural networks improving its generalization capabilities as shown by the M4 international forecasting competition (Smyl 2019, Semenoglou 2021).\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can run these experiments using GPU with Google Colab.\n",
"\n",
"<a href=\"https://colab.research.google.com/github/Nixtla/neuralforecast/blob/main/nbs/examples/Data_Format.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Long format"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Multiple time series"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Store your time series in a pandas dataframe in long format, that is, each row represents an observation for a specific series and timestamp. Let's see an example using the `datasetsforecast` library.\n",
"\n",
"`Y_df = pd.concat( [series1, series2, ...])`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"!pip install datasetsforecast"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"from datasetsforecast.m3 import M3"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 1.76M/1.76M [00:00<00:00, 5.55MiB/s]\n",
"INFO:datasetsforecast.utils:Successfully downloaded M3C.xls, 1757696, bytes.\n"
]
}
],
"source": [
"Y_df, *_ = M3.load('./data', group='Yearly')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>y</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Y1</td>\n",
" <td>1975-12-31</td>\n",
" <td>940.66</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Y1</td>\n",
" <td>1976-12-31</td>\n",
" <td>1084.86</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>Y10</td>\n",
" <td>1975-12-31</td>\n",
" <td>2160.04</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>Y10</td>\n",
" <td>1976-12-31</td>\n",
" <td>2553.48</td>\n",
" </tr>\n",
" <tr>\n",
" <th>40</th>\n",
" <td>Y100</td>\n",
" <td>1975-12-31</td>\n",
" <td>1424.70</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18260</th>\n",
" <td>Y97</td>\n",
" <td>1976-12-31</td>\n",
" <td>1618.91</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18279</th>\n",
" <td>Y98</td>\n",
" <td>1975-12-31</td>\n",
" <td>1164.97</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18280</th>\n",
" <td>Y98</td>\n",
" <td>1976-12-31</td>\n",
" <td>1277.87</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18299</th>\n",
" <td>Y99</td>\n",
" <td>1975-12-31</td>\n",
" <td>1870.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18300</th>\n",
" <td>Y99</td>\n",
" <td>1976-12-31</td>\n",
" <td>1307.20</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1290 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" unique_id ds y\n",
"0 Y1 1975-12-31 940.66\n",
"1 Y1 1976-12-31 1084.86\n",
"20 Y10 1975-12-31 2160.04\n",
"21 Y10 1976-12-31 2553.48\n",
"40 Y100 1975-12-31 1424.70\n",
"... ... ... ...\n",
"18260 Y97 1976-12-31 1618.91\n",
"18279 Y98 1975-12-31 1164.97\n",
"18280 Y98 1976-12-31 1277.87\n",
"18299 Y99 1975-12-31 1870.00\n",
"18300 Y99 1976-12-31 1307.20\n",
"\n",
"[1290 rows x 3 columns]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Y_df.groupby('unique_id').head(2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>y</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>Y1</td>\n",
" <td>1993-12-31</td>\n",
" <td>8407.84</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>Y1</td>\n",
" <td>1994-12-31</td>\n",
" <td>9156.01</td>\n",
" </tr>\n",
" <tr>\n",
" <th>38</th>\n",
" <td>Y10</td>\n",
" <td>1993-12-31</td>\n",
" <td>3187.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>39</th>\n",
" <td>Y10</td>\n",
" <td>1994-12-31</td>\n",
" <td>3058.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>58</th>\n",
" <td>Y100</td>\n",
" <td>1993-12-31</td>\n",
" <td>3539.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18278</th>\n",
" <td>Y97</td>\n",
" <td>1994-12-31</td>\n",
" <td>4507.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18297</th>\n",
" <td>Y98</td>\n",
" <td>1993-12-31</td>\n",
" <td>1801.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18298</th>\n",
" <td>Y98</td>\n",
" <td>1994-12-31</td>\n",
" <td>1710.00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18317</th>\n",
" <td>Y99</td>\n",
" <td>1993-12-31</td>\n",
" <td>2379.30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18318</th>\n",
" <td>Y99</td>\n",
" <td>1994-12-31</td>\n",
" <td>2723.00</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1290 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" unique_id ds y\n",
"18 Y1 1993-12-31 8407.84\n",
"19 Y1 1994-12-31 9156.01\n",
"38 Y10 1993-12-31 3187.00\n",
"39 Y10 1994-12-31 3058.00\n",
"58 Y100 1993-12-31 3539.00\n",
"... ... ... ...\n",
"18278 Y97 1994-12-31 4507.00\n",
"18297 Y98 1993-12-31 1801.00\n",
"18298 Y98 1994-12-31 1710.00\n",
"18317 Y99 1993-12-31 2379.30\n",
"18318 Y99 1994-12-31 2723.00\n",
"\n",
"[1290 rows x 3 columns]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Y_df.groupby('unique_id').tail(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`Y_df` is a dataframe with three columns: `unique_id` with a unique identifier for each time series, a column `ds` with the datestamp and a column `y` with the values of the series."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Single time series"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you have only one time series, you have to include the `unique_id` column. Consider, for example, the [AirPassengers](https://github.com/Nixtla/transfer-learning-time-series/blob/main/datasets/air_passengers.csv) dataset."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Y_df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/air_passengers.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this example `Y_df` only contains two columns: `timestamp`, and `value`. To use `NeuralForecast` we have to include the `unique_id` column and rename the previuos ones."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Y_df['unique_id'] = 1. # We can add an integer as identifier\n",
"Y_df = Y_df.rename(columns={'timestamp': 'ds', 'value': 'y'})\n",
"Y_df = Y_df[['unique_id', 'ds', 'y']]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>y</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1.0</td>\n",
" <td>1949-01-01</td>\n",
" <td>112</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1.0</td>\n",
" <td>1949-02-01</td>\n",
" <td>118</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>1949-03-01</td>\n",
" <td>132</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1949-04-01</td>\n",
" <td>129</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1.0</td>\n",
" <td>1949-05-01</td>\n",
" <td>121</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>139</th>\n",
" <td>1.0</td>\n",
" <td>1960-08-01</td>\n",
" <td>606</td>\n",
" </tr>\n",
" <tr>\n",
" <th>140</th>\n",
" <td>1.0</td>\n",
" <td>1960-09-01</td>\n",
" <td>508</td>\n",
" </tr>\n",
" <tr>\n",
" <th>141</th>\n",
" <td>1.0</td>\n",
" <td>1960-10-01</td>\n",
" <td>461</td>\n",
" </tr>\n",
" <tr>\n",
" <th>142</th>\n",
" <td>1.0</td>\n",
" <td>1960-11-01</td>\n",
" <td>390</td>\n",
" </tr>\n",
" <tr>\n",
" <th>143</th>\n",
" <td>1.0</td>\n",
" <td>1960-12-01</td>\n",
" <td>432</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>144 rows × 3 columns</p>\n",
"</div>"
],
"text/plain": [
" unique_id ds y\n",
"0 1.0 1949-01-01 112\n",
"1 1.0 1949-02-01 118\n",
"2 1.0 1949-03-01 132\n",
"3 1.0 1949-04-01 129\n",
"4 1.0 1949-05-01 121\n",
".. ... ... ...\n",
"139 1.0 1960-08-01 606\n",
"140 1.0 1960-09-01 508\n",
"141 1.0 1960-10-01 461\n",
"142 1.0 1960-11-01 390\n",
"143 1.0 1960-12-01 432\n",
"\n",
"[144 rows x 3 columns]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Y_df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"- [Slawek Smyl. (2019). \"A hybrid method of exponential smoothing and recurrent networks for time series forecasting\". International\n",
"Journal of Forecasting.](https://www.sciencedirect.com/science/article/pii/S0169207019301153)\n",
"- [Artemios-Anargyros Semenoglou, Evangelos Spiliotis, Spyros Makridakis, and Vassilios Assimakopoulos. (2021). Investigating the accuracy of cross-learning time series forecasting methods\". International\n",
"Journal of Forecasting.](https://www.sciencedirect.com/science/article/pii/S0169207020301850)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "neuralforecast",
"language": "python",
"name": "neuralforecast"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exogenous Variables"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Exogenous variables can provide additional information to greatly improve forecasting accuracy. Some examples include price or future promotions variables for demand forecasting, and weather data for electricity load forecast. In this notebook we show an example on how to add different types of exogenous variables to NeuralForecast models for making day-ahead hourly electricity price forecasts (EPF) for France and Belgium markets."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"All NeuralForecast models are capable of incorporating exogenous variables to model the following conditional predictive distribution:\n",
"$$\\mathbb{P}(\\mathbf{y}_{t+1:t+H} \\;|\\; \\mathbf{y}_{[:t]},\\; \\mathbf{x}^{(h)}_{[:t]},\\; \\mathbf{x}^{(f)}_{[:t+H]},\\; \\mathbf{x}^{(s)} )$$\n",
"\n",
"where the regressors are static exogenous $\\mathbf{x}^{(s)}$, historic exogenous $\\mathbf{x}^{(h)}_{[:t]}$, exogenous available at the time of the prediction $\\mathbf{x}^{(f)}_{[:t+H]}$ and autorregresive features $\\mathbf{y}_{[:t]}$. Depending on the [train loss](https://nixtla.github.io/neuralforecast/losses.pytorch.html), the model outputs can be point forecasts (location estimators) or uncertainty intervals (quantiles)."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"We will show you how to include exogenous variables in the data, specify variables to a model, and produce forecasts using future exogenous variables."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-important}\n",
"This Guide assumes basic knowledge on the NeuralForecast library. For a minimal example visit the [Getting Started](./Getting_Started.ipynb) guide.\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"You can run these experiments using GPU with Google Colab.\n",
"\n",
"<a href=\"https://colab.research.google.com/github/Nixtla/neuralforecast/blob/main/nbs/examples/Exogenous_Variables.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Libraries"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"!pip install neuralforecast"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Load data"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"The `df` dataframe contains the target and exogenous variables past information to train the model. The `unique_id` column identifies the markets, `ds` contains the datestamps, and `y` the electricity price.\n",
"\n",
"Include both historic and future temporal variables as columns. In this example, we are adding the system load (`system_load`) as historic data. For future variables, we include a forecast of how much electricity will be produced (`gen_forecast`) and day of week (`week_day`). Both the electricity system demand and offer impact the price significantly, including these variables to the model greatly improve performance, as we demonstrate in Olivares et al. (2022). \n",
"\n",
"The distinction between historic and future variables will be made later as parameters of the model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>y</th>\n",
" <th>gen_forecast</th>\n",
" <th>system_load</th>\n",
" <th>week_day</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>FR</td>\n",
" <td>2015-01-01 00:00:00</td>\n",
" <td>53.48</td>\n",
" <td>76905.0</td>\n",
" <td>74812.0</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>FR</td>\n",
" <td>2015-01-01 01:00:00</td>\n",
" <td>51.93</td>\n",
" <td>75492.0</td>\n",
" <td>71469.0</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>FR</td>\n",
" <td>2015-01-01 02:00:00</td>\n",
" <td>48.76</td>\n",
" <td>74394.0</td>\n",
" <td>69642.0</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>FR</td>\n",
" <td>2015-01-01 03:00:00</td>\n",
" <td>42.27</td>\n",
" <td>72639.0</td>\n",
" <td>66704.0</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>FR</td>\n",
" <td>2015-01-01 04:00:00</td>\n",
" <td>38.41</td>\n",
" <td>69347.0</td>\n",
" <td>65051.0</td>\n",
" <td>3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id ds y gen_forecast system_load week_day\n",
"0 FR 2015-01-01 00:00:00 53.48 76905.0 74812.0 3\n",
"1 FR 2015-01-01 01:00:00 51.93 75492.0 71469.0 3\n",
"2 FR 2015-01-01 02:00:00 48.76 74394.0 69642.0 3\n",
"3 FR 2015-01-01 03:00:00 42.27 72639.0 66704.0 3\n",
"4 FR 2015-01-01 04:00:00 38.41 69347.0 65051.0 3"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.read_csv('https://datasets-nixtla.s3.amazonaws.com/EPF_FR_BE.csv')\n",
"df['ds'] = pd.to_datetime(df['ds'])\n",
"df.head()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-tip}\n",
"Calendar variables such as day of week, month, and year are very useful to capture long seasonalities.\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABNYAAAHACAYAAABuwuWeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD/BklEQVR4nOzdd3gU1foH8O+mEHqvQaqCUqRIU5SmgBos116uvd5rRew/LNhAUREVG1cFG2DDTu+9Q+g1CYQSQklII8lmd35/hE1md6ec2Z3Znd39fp7HR7I7O3N2dubMmXfOeY9DkiQJREREREREREREZEhcuAtAREREREREREQUiRhYIyIiIiIiIiIiCgADa0RERERERERERAFgYI2IiIiIiIiIiCgADKwREREREREREREFgIE1IiIiIiIiIiKiADCwRkREREREREREFAAG1oiIiIiIiIiIiAKQEO4C2IHb7cbhw4dRq1YtOByOcBeHiIiIiIiIiIjCRJIk5OfnIzk5GXFx2n3SGFgDcPjwYbRo0SLcxSAiIiIiIiIiIpvIzMzEWWedpbkMA2sAatWqBaB8h9WuXTvMpTGH0+nEnDlzMHToUCQmJoa7OBQheNxQoHjsULB4DJEZeBxRoHjsUDB4/FCweAzZT15eHlq0aFERL9LCwBpQMfyzdu3aURVYq169OmrXrs0Tk4TxuKFA8dihYPEYIjPwOKJA8dihYPD4oWDxGLIvkXRhnLyAiIiIiIiIiIgoAAysERERERERERERBYCBNSIiIiIiIiIiogAwsEZERERERERERBQABtaIiIiIiIiIiIgCwMAaERERERERERFRABhYIyIiIiIiIiIiCgADa0RERERERERERAFgYI2IiIiIiIiIiCgADKwREREREREREREFgIE1IiIiIiIiIiKiADCwRkREREREREREFAAG1oiIiIiIiIiIiALAwBoRERERURCy84px76Q1mL/jaLiLQkRERCHGwBoRERERURBG/bUNC3cdw/3frAt3UYiIiCjEGFgjIiIiIgrCsfyScBeBiIiIwoSBNSIiIiIiIiIiogAwsEZERERERERERBQABtaIiIiIiIiIiIgCwMAaERERERERERFRABhYIyIiIiIiIiIiCgADa0RERERERERERAFgYI2IiIiIiIiIiCgADKwRERERRaGSMheO5ZeEuxhEREREUY2BNSIiIqIodOl7i9HrrXk4cKIo3EUhIiKiCHUwpwiFJWXhLoatMbBGREREFIUO5Z4GACzYeTTMJSEiIqJIlH68EJe8sxAXjpkf7qLYGgNrRERERERERETkZemeYwCA/GL2WNPCwBoRERFRFJPCXQAiIiKiKMbAGhERERFREBxwhLsIREREFCZhDawtWbIEV199NZKTk+FwOPD7779XvOd0OvH888/j/PPPR40aNZCcnIy77roLhw8f9lpHSUkJHn/8cTRs2BA1atTANddcg4MHD4b4mxARERFRrJLYL5CIiChmhTWwVlhYiK5du2LChAl+7xUVFWHDhg14+eWXsWHDBkyfPh27d+/GNddc47Xc8OHD8dtvv2HatGlYtmwZCgoKcNVVV8HlcoXqaxARERERERERUQxKCOfGr7zySlx55ZWK79WpUwdz5871eu3jjz9G7969ceDAAbRs2RKnTp3CV199he+++w6DBw8GAHz//fdo0aIF5s2bh8svv9zy70BERERkZxI7U1mOQ0GJiIhiV0TlWDt16hQcDgfq1q0LAFi/fj2cTieGDh1asUxycjI6d+6MFStWhKmURERERERERESRjY+NxIS1x5oRxcXFeOGFF3D77bejdu3aAICsrCxUqVIF9erV81q2SZMmyMrKUl1XSUkJSkpKKv7Oy8sDUJ7Xzel0WlD60PN8j2j5PhQaPG4oUDx2KFg8hqzjdrtiZr+G6zhyS26/MlBkYR1EweDxQ8Gy6zEkT7Flt7JZzcj3jYjAmtPpxK233gq3241PP/1Ud3lJkuBwqMdWx4wZg9dee83v9Tlz5qB69epBldVufIfTEongcUOB4rFDweIxZKbyZt627dsxI2dbmMsSWqE+jk6ejIfnuf6MGTNCum0yF+sgCgaPHwqW3Y6hrVkOAPEAYu/6VlRUJLys7QNrTqcTN998M9LT07FgwYKK3moA0LRpU5SWliInJ8er11p2djb69u2rus4XX3wRI0aMqPg7Ly8PLVq0wNChQ73WH8mcTifmzp2LIUOGIDExMdzFoQjB44YCxWOHgsVjyHxPrpwDAOjYsSNSLmoV5tKERriOo+8Or0Fafi4AICUlJWTbJfOwDqJg8PihYNn1GMpZfQC/pO8EEHvXN8/IRhG2Dqx5gmp79uzBwoUL0aBBA6/3e/TogcTERMydOxc333wzAODIkSPYunUrxo4dq7repKQkJCUl+b2emJhoq4PYDNH4nch6PG4oUDx2KFg8hswXHxcfc/s01MdRnKMybXGs7etowzqIgsHjh4Jlt2MoPj6+4t92KlcoGPm+YQ2sFRQUYO/evRV/p6enY9OmTahfvz6Sk5Nx4403YsOGDfj777/hcrkq8qbVr18fVapUQZ06dXD//ffj6aefRoMGDVC/fn0888wzOP/88ytmCSUiIiIiIiIiIoM0UmxRpbAG1tatW4dBgwZV/O0Znnn33Xdj1KhR+PPPPwEA3bp18/rcwoULMXDgQADABx98gISEBNx88804ffo0LrvsMkyePNkrskpEREQUq6RwF4CIiIgoioU1sDZw4EBIknpzT+s9j6pVq+Ljjz/Gxx9/bGbRiIiIiIiIiIiINMXpL0JERERERERERES+GFgjIiIiIiIiIiIKAANrRERERERERETkhVMXiGFgjYiIiCiKieSsJSIiIqLAMLBGREREREREREQUAAbWKKqs35+Du79eg73ZBeEuChERkS04HBzIQURERGQVBtYoqtzw2Qos3n0MD3yzNtxFISIisgUOBSUiIiKyDgNrFJUO5xaHuwhEREREREREFOUYWKOoJIFP54mIiIiIiIjIWgysERERERERERGRF6ZpFcPAGkUlppMhIiIiIiIiIqsxsEZEREQUxZbvPY7sfOYetRSf6BMREcUsBtYoKrHDGhERUbmFu47h4rcXhLsY0Y0NDyIiopjFwBoRERFRlHO6GPkhIiIisgIDa0RERERERERERAFgYI2IiIiIKBjMsUZERFHIwQucEAbWiIiIiIiCwZG2REREMYuBNYpKksQWLhEREREREVGgJD45EsLAGhERERFRMDhShoiIKGYlhLsARFZgXJ2IiIhChg0PIiKKIpIk4a1/dmDDgZxwFyUiMLBGREREREREREQAgEW7j+HLZenhLkbE4FBQikpMsUZEREQhw6GgREQURXIKS8NdhIjCwBoREREREREREQEAHHxgZAgDaxSVWBEQERFRyLCnPBERUcxiYI2iEoeCEhEREREREZHVGFgjIiIiIgoGe8oTERHFLAbWiIiIiIiIiIgIAODgEyNDGFgjIiIiIiIiIiIKAANrREREREREREQEgJMBGsXAGhERERERERERUQAYWCMiIiIiIiIiilAlZS689tc2LN1zLNxF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NSIiIiIiIiIiIhsYWCMiIiIiIiIiIrKBgTUiIiIiIiIiIiIbGFgjIiIiIiIiIiKygYE1IiIiIiIiIiIiGxhYIyIiIiIiIiIisoGBNSIiIiIiIiIiIhsYWCMiIiIiIuog5lWVAgCunto7uhkhIkoQnmhngIiIiIiIiCLj1pkDcMHo7ujZJT3aWSEiSggMrBEREREREXUQLpeAXl0zop0NIqKEwa6gRERERERERERENjCwRkREREREREREZAMDa0RERERERERERDYwsEZERERERERERGQDA2tEREREREREREQ2MLBGRERERERERERkAwNrRERERERERERENjCwRkREREREREREZAMDa0RERERERERERDYwsEZERERERERERGQDA2tEREREREREREQ2MLBGRERERERERERkAwNrRERERERERERENjCwRkREREREREREZIMn2hmIBaIoAgDq6+ujnBPnNDU14dixY6ivr4fX6412dihOsNyQXSw7FCqWIXICyxHZxbJDoWD5oVCxDMUef3zIHy/Sw8AagMOHDwMAiouLo5wTIiIiIiIiIiKKBYcPH0ZWVpbuMoJoJvyW4FpbW7Fnzx5kZGRAEIRoZ8cR9fX1KC4uxtdff43MzMxoZ4fiBMsN2cWyQ6FiGSInsByRXSw7FAqWHwoVy1DsEUURhw8fRmFhIVwu/VHU2GINgMvlQrdu3aKdjbDIzMzkiUmWsdyQXSw7FCqWIXICyxHZxbJDoWD5oVCxDMUWo5Zqfpy8gIiIiIiIiIiIyAYG1oiIiIiIiIiIiGxgYC1B+Xw+LF26FD6fL9pZoTjCckN2sexQqFiGyAksR2QXyw6FguWHQsUyFN84eQEREREREREREZENbLFGRERERERERERkAwNrRERERERERERENjCwRkREREREREREZAMDa0RERERERERERDYwsBZBK1aswMiRI5GRkYGuXbvi9NNPx44dO2TLiKKIZcuWobCwECkpKZg0aRI+/vhj2TKPPPIIJk2ahMzMTAiCgIMHDwatq7S0FIIgyP678cYbDfO4bds2TJw4ESkpKSgqKsLy5cshnd+irq4Oc+bMQd++feFyuXDNNdfY2hdkXiKUG6mNGzfC4/GgvLzc9D4gexKh7MybNy8oXUEQMHDgQHs7hSyJ9TJ0/PhxzJs3D4MHD4bH48Hpp5+uutyGDRtQ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XoZEURQ//vhjsba2Vjz11FPFSZMmtd+j/L744gsxNTVVvPbaa8Xt27eLjz76qOj1esW//e1vzu0o0hSpMiSKorho0SKxqKhI/Pe//y1++umn4vz588WuXbuK33//vWb+WPeJbYlSfqRYB4qcRCo/rAdFR6yXIVFkPShWMLAWQQBU/1u1alX7Mq2treLSpUvF/Px80efziRMmTBC3bdsmS2fp0qW66bz//vtiZWWlmJWVJSYnJ4t9+/YVly5dKh49etQwj1u3bhXHjx8v+nw+MT8/X1y2bFnQdM9q6y4pKQl195CGRCk3yrywUhl+iVJ2Dh48KKakpIiPPPJIyPuErImHMlRSUqKattRrr70mDhs2TExKShJLS0vFhx56KOR9Q+ZEqgyJoig2NjaK1113ndi1a1cxIyNDnDZtmvjRRx8Z5pF1n9iVKOVHmRfWgSIjUcoP60HREw9liPWg2CCI4omR64iIiIiIiIiIiMg0jrFGRERERERERERkAwNrRERERERERERENjCwRkREREREREREZAMDa0RERERERERERDYwsEZERERERERERGQDA2tEREREREREREQ2MLBGRERERERERERkAwNrRERERERERERENjCwRkRERJRg5s2bB0EQIAgCvF4v8vLyMH36dDz22GNobW01nc7jjz+O7Ozs8GWUiIiIKM4xsEZERESUgGbMmIG6ujrs2rULL730EiZPnoxFixZh5syZaG5ujnb2iIiIiBICA2tERERECcjn8yE/Px9FRUUYPnw4br75Zrzwwgt46aWX8PjjjwMAVq5cicGDByMtLQ3FxcVYuHAhjhw5AgB47bXXcPHFF+PQoUPtrd+WLVsGAGhsbMQNN9yAoqIipKWlobKyEq+99lp0NpSIiIgoihhYIyIiIuogpkyZgqFDh+K5554DALhcLtx///346KOP8Mc//hHr1q3DDTfcAACoqqrCb3/7W2RmZqKurg51dXW4/vrrAQAXX3wxNm7ciKeffhpbt27F2WefjRkzZuCzzz6L2rYRERERRYMgiqIY7UwQERERkXPmzZuHgwcP4u9//3vQd+eddx62bt2K7du3B333zDPP4PLLL8f+/fsBtI2xds011+DgwYPty+zcuRO9e/fGN998g8LCwvbPp02bhlGjRuHOO+90fHuIiIiIYpUn2hkgIiIiosgRRRGCIAAA1q9fjzvvvBPbt29HfX09mpubcfz4cRw9ehRpaWmqv//ggw8giiL69Okj+7yhoQG5ublhzz8RERFRLGFgjYiIiKgD+eSTT1BWVoavvvoKNTU1WLBgAW6//Xbk5OTgzTffxPz589HU1KT5+9bWVrjdbrz//vtwu92y79LT08OdfSIiIqKYwsAaERERUQexbt06bNu2Dddeey3ee+89NDc3495774XL1Tbs7l//+lfZ8klJSWhpaZF9NmzYMLS0tGDfvn0YP358xPJOREREFIsYWCMiIiJKQA0NDdi7dy9aWlrw3Xff4eWXX8aKFSswc+ZMzJ07F9u2bUNzczMeeOABnHrqqdi4cSMefvhhWRqlpaU4cuQIXn31VQwdOhSpqano06cPzj//fMydOxf33nsvhg0bhv3792PdunUYPHgwampqorTFRERERJHHWUGJiIiIEtDLL7+MgoIClJaWYsaMGVi/fj3uv/9+vPDCC3C73SgvL8fKlStx9913Y9CgQXjiiSewYsUKWRpVVVVYsGABzj33XHTp0gX33HMPAGDVqlWYO3currvuOvTt2xennXYa3nnnHRQXF0djU4mIiIiihrOCEhERERERERER2cAWa0RERERERERERDYwsEZERERERERERGQDA2tEREREREREREQ2MLBGRERERERERERkAwNrRERERERERERENjCwRkREREREREREZAMDa0RERERERERERDYwsEZERERERERERGQDA2tEREREREREREQ2MLBGRERERERERERkAwNrRERERERERERENjCwRkREREREREREZMP/B7FOGYynM6N2AAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 1500x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(15,5))\n",
"plt.plot(df[df['unique_id']=='FR']['ds'], df[df['unique_id']=='FR']['y'])\n",
"plt.xlabel('Date')\n",
"plt.ylabel('Price [EUR/MWh]')\n",
"plt.grid()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Add the static variables in a separate `static_df` dataframe. In this example, we are using one-hot encoding of the electricity market. The `static_df` must include one observation (row) for each `unique_id` of the `df` dataframe, with the different statics variables as columns."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>market_0</th>\n",
" <th>market_1</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>FR</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>BR</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id market_0 market_1\n",
"0 FR 1 0\n",
"1 BR 0 1"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"static_df = pd.read_csv('https://datasets-nixtla.s3.amazonaws.com/EPF_FR_BE_static.csv')\n",
"static_df.head()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Training with exogenous variables"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"We distinguish the exogenous variables by whether they reflect static or time-dependent aspects of the modeled data.\n",
"\n",
"* **Static exogenous variables**: \n",
"The static exogenous variables carry time-invariant information for each time series. When the model is built with global parameters to forecast multiple time series, these variables allow sharing information within groups of time series with similar static variable levels. Examples of static variables include designators such as identifiers of regions, groups of products, etc.\n",
"\n",
"* **Historic exogenous variables**:\n",
"This time-dependent exogenous variable is restricted to past observed values. Its predictive power depends on Granger-causality, as its past values can provide significant information about future values of the target variable $\\mathbf{y}$.\n",
"\n",
"* **Future exogenous variables**: \n",
"In contrast with historic exogenous variables, future values are available at the time of the prediction. Examples include calendar variables, weather forecasts, and known events that can cause large spikes and dips such as scheduled promotions."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"To add exogenous variables to the model, first specify the name of each variable from the previous dataframes to the corresponding model hyperparameter during initialization: `futr_exog_list`, `hist_exog_list`, and `stat_exog_list`. We also set `horizon` as 24 to produce the next day hourly forecasts, and set `input_size` to use the last 5 days of data as input. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from neuralforecast.auto import NHITS, BiTCN\n",
"from neuralforecast.core import NeuralForecast\n",
"\n",
"import logging\n",
"logging.getLogger(\"pytorch_lightning\").setLevel(logging.WARNING)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\pytorch_lightning\\utilities\\parsing.py:199: Attribute 'loss' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['loss'])`.\n",
"Seed set to 1\n",
"Seed set to 1\n"
]
}
],
"source": [
"horizon = 24 # day-ahead daily forecast\n",
"models = [NHITS(h = horizon,\n",
" input_size = 5*horizon,\n",
" futr_exog_list = ['gen_forecast', 'week_day'], # <- Future exogenous variables\n",
" hist_exog_list = ['system_load'], # <- Historical exogenous variables\n",
" stat_exog_list = ['market_0', 'market_1'], # <- Static exogenous variables\n",
" scaler_type = 'robust'),\n",
" BiTCN(h = horizon,\n",
" input_size = 5*horizon,\n",
" futr_exog_list = ['gen_forecast', 'week_day'], # <- Future exogenous variables\n",
" hist_exog_list = ['system_load'], # <- Historical exogenous variables\n",
" stat_exog_list = ['market_0', 'market_1'], # <- Static exogenous variables\n",
" scaler_type = 'robust',\n",
" ), \n",
" ]"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-tip}\n",
"When including exogenous variables always use a scaler by setting the `scaler_type` hyperparameter. The scaler will scale all the temporal features: the target variable `y`, historic and future variables.\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-important}\n",
"Make sure future and historic variables are correctly placed. Defining historic variables as future variables will lead to data leakage.\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, pass the datasets to the `df` and `static_df` inputs of the `fit` method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"nf = NeuralForecast(models=models, freq='H')\n",
"nf.fit(df=df,\n",
" static_df=static_df)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Forecasting with exogenous variables"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Before predicting the prices, we need to gather the future exogenous variables for the day we want to forecast. Define a new dataframe (`futr_df`) with the `unique_id`, `ds`, and future exogenous variables. There is no need to add the target variable `y` and historic variables as they won't be used by the model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>gen_forecast</th>\n",
" <th>week_day</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>FR</td>\n",
" <td>2016-11-01 00:00:00</td>\n",
" <td>49118.0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>FR</td>\n",
" <td>2016-11-01 01:00:00</td>\n",
" <td>47890.0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>FR</td>\n",
" <td>2016-11-01 02:00:00</td>\n",
" <td>47158.0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>FR</td>\n",
" <td>2016-11-01 03:00:00</td>\n",
" <td>45991.0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>FR</td>\n",
" <td>2016-11-01 04:00:00</td>\n",
" <td>45378.0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id ds gen_forecast week_day\n",
"0 FR 2016-11-01 00:00:00 49118.0 1\n",
"1 FR 2016-11-01 01:00:00 47890.0 1\n",
"2 FR 2016-11-01 02:00:00 47158.0 1\n",
"3 FR 2016-11-01 03:00:00 45991.0 1\n",
"4 FR 2016-11-01 04:00:00 45378.0 1"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"futr_df = pd.read_csv('https://datasets-nixtla.s3.amazonaws.com/EPF_FR_BE_futr.csv')\n",
"futr_df['ds'] = pd.to_datetime(futr_df['ds'])\n",
"futr_df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-important}\n",
"Make sure `futr_df` has informations for the entire forecast horizon. In this example, we are forecasting 24 hours ahead, so `futr_df` must have 24 rows for each time series.\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, use the `predict` method to forecast the day-ahead prices. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\utilsforecast\\processing.py:352: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.\n",
" freq = pd.tseries.frequencies.to_offset(freq)\n",
"c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\utilsforecast\\processing.py:404: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.\n",
" freq = pd.tseries.frequencies.to_offset(freq)\n",
"c:\\Users\\ospra\\OneDrive\\Phd\\Repositories\\neuralforecast\\neuralforecast\\tsdataset.py:91: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
" self.temporal = torch.tensor(temporal, dtype=torch.float)\n",
"c:\\Users\\ospra\\OneDrive\\Phd\\Repositories\\neuralforecast\\neuralforecast\\tsdataset.py:95: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
" self.static = torch.tensor(static, dtype=torch.float)\n",
"c:\\Users\\ospra\\miniconda3\\envs\\neuralforecast\\lib\\site-packages\\pytorch_lightning\\trainer\\connectors\\data_connector.py:441: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=19` in the `DataLoader` to improve performance.\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "35847892c983422d96ad9e8afee27afb",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Predicting: | | 0/? [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0cf2fb8d84e94f5e831826ca0f8362e3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Predicting: | | 0/? [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"c:\\Users\\ospra\\OneDrive\\Phd\\Repositories\\neuralforecast\\neuralforecast\\core.py:179: FutureWarning: In a future version the predictions will have the id as a column. You can set the `NIXTLA_ID_AS_COL` environment variable to adopt the new behavior and to suppress this warning.\n",
" warnings.warn(\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>ds</th>\n",
" <th>NHITS</th>\n",
" <th>BiTCN</th>\n",
" </tr>\n",
" <tr>\n",
" <th>unique_id</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>BE</th>\n",
" <td>2016-11-01 00:00:00</td>\n",
" <td>38.138920</td>\n",
" <td>41.105774</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BE</th>\n",
" <td>2016-11-01 01:00:00</td>\n",
" <td>34.647514</td>\n",
" <td>35.589905</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BE</th>\n",
" <td>2016-11-01 02:00:00</td>\n",
" <td>33.428795</td>\n",
" <td>33.034309</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BE</th>\n",
" <td>2016-11-01 03:00:00</td>\n",
" <td>32.428146</td>\n",
" <td>30.183418</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BE</th>\n",
" <td>2016-11-01 04:00:00</td>\n",
" <td>31.068453</td>\n",
" <td>29.396011</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" ds NHITS BiTCN\n",
"unique_id \n",
"BE 2016-11-01 00:00:00 38.138920 41.105774\n",
"BE 2016-11-01 01:00:00 34.647514 35.589905\n",
"BE 2016-11-01 02:00:00 33.428795 33.034309\n",
"BE 2016-11-01 03:00:00 32.428146 30.183418\n",
"BE 2016-11-01 04:00:00 31.068453 29.396011"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Y_hat_df = nf.predict(futr_df=futr_df)\n",
"Y_hat_df.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"plot_df = df[df['unique_id']=='FR'].tail(24*5).reset_index(drop=True)\n",
"Y_hat_df = Y_hat_df.reset_index(drop=False)\n",
"Y_hat_df = Y_hat_df[Y_hat_df['unique_id']=='FR']\n",
"\n",
"plot_df = pd.concat([plot_df, Y_hat_df ]).set_index('ds') # Concatenate the train and forecast dataframes\n",
"\n",
"plot_df[['y', 'NHITS', 'BiTCN']].plot(linewidth=2)\n",
"plt.axvline('2016-11-01', color='red')\n",
"plt.ylabel('Price [EUR/MWh]', fontsize=12)\n",
"plt.xlabel('Date', fontsize=12)\n",
"plt.grid()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"In summary, to add exogenous variables to a model make sure to follow the next steps:\n",
"\n",
"1. Add temporal exogenous variables as columns to the main dataframe (`df`).\n",
"2. Add static exogenous variables with the `static_df` dataframe.\n",
"3. Specify the name for each variable in the corresponding model hyperparameter.\n",
"4. If the model uses future exogenous variables, pass the future dataframe (`futr_df`) to the `predict` method."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## References"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"- [Kin G. Olivares, Cristian Challu, Grzegorz Marcjasz, Rafał Weron, Artur Dubrawski, Neural basis expansion analysis with exogenous variables: Forecasting electricity prices with NBEATSx, International Journal of Forecasting](https://www.sciencedirect.com/science/article/pii/S0169207022000413)\n",
"\n",
"- [Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021). NHITS: Neural Hierarchical Interpolation for Time Series Forecasting. Accepted at AAAI 2023.](https://arxiv.org/abs/2201.12886)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Getting Started\n",
"> Fit an LSTM and NHITS model"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook provides an example on how to start using the main functionalities of the NeuralForecast library. The `NeuralForecast` class allows users to easily interact with `NeuralForecast.models` PyTorch models. In this example we will forecast AirPassengers data with a classic `LSTM` and the recent `NHITS` models. The full list of available models is available [here](https://nixtla.github.io/neuralforecast/models.html).\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"You can run these experiments using GPU with Google Colab.\n",
"\n",
"<a href=\"https://colab.research.google.com/github/Nixtla/neuralforecast/blob/main/nbs/examples/Getting_Started.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Installing NeuralForecast"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"!pip install neuralforecast"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Loading AirPassengers Data\n",
"\n",
"The `core.NeuralForecast` class contains shared, `fit`, `predict` and other methods that take as inputs pandas DataFrames with columns `['unique_id', 'ds', 'y']`, where `unique_id` identifies individual time series from the dataset, `ds` is the date, and `y` is the target variable. \n",
"\n",
"In this example dataset consists of a set of a single series, but you can easily fit your model to larger datasets in long format."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>y</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1.0</td>\n",
" <td>1949-01-31</td>\n",
" <td>112.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1.0</td>\n",
" <td>1949-02-28</td>\n",
" <td>118.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>1949-03-31</td>\n",
" <td>132.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1949-04-30</td>\n",
" <td>129.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1.0</td>\n",
" <td>1949-05-31</td>\n",
" <td>121.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id ds y\n",
"0 1.0 1949-01-31 112.0\n",
"1 1.0 1949-02-28 118.0\n",
"2 1.0 1949-03-31 132.0\n",
"3 1.0 1949-04-30 129.0\n",
"4 1.0 1949-05-31 121.0"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from neuralforecast.utils import AirPassengersDF\n",
"\n",
"Y_df = AirPassengersDF # Defined in neuralforecast.utils\n",
"Y_df.head()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-important}\n",
"DataFrames must include all `['unique_id', 'ds', 'y']` columns.\n",
"Make sure `y` column does not have missing or non-numeric values. \n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Model Training"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Fit the models"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the `NeuralForecast.fit` method you can train a set of models to your dataset. You can define the forecasting `horizon` (12 in this example), and modify the hyperparameters of the model. For example, for the `LSTM` we changed the default hidden size for both encoder and decoders."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from neuralforecast import NeuralForecast\n",
"from neuralforecast.models import LSTM, NHITS, RNN"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"horizon = 12\n",
"\n",
"# Try different hyperparmeters to improve accuracy.\n",
"models = [LSTM(h=horizon, # Forecast horizon\n",
" max_steps=500, # Number of steps to train\n",
" scaler_type='standard', # Type of scaler to normalize data\n",
" encoder_hidden_size=64, # Defines the size of the hidden state of the LSTM\n",
" decoder_hidden_size=64,), # Defines the number of hidden units of each layer of the MLP decoder\n",
" NHITS(h=horizon, # Forecast horizon\n",
" input_size=2 * horizon, # Length of input sequence\n",
" max_steps=100, # Number of steps to train\n",
" n_freq_downsample=[2, 1, 1]) # Downsampling factors for each stack output\n",
" ]\n",
"nf = NeuralForecast(models=models, freq='M')\n",
"nf.fit(df=Y_df)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-tip}\n",
"The performance of Deep Learning models can be very sensitive to the choice of hyperparameters. Tuning the correct hyperparameters is an important step to obtain the best forecasts. The `Auto` version of these models, `AutoLSTM` and `AutoNHITS`, already perform hyperparameter selection automatically.\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Predict using the fitted models\n",
"\n",
"Using the `NeuralForecast.predict` method you can obtain the `h` forecasts after the training data `Y_df`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 50.58it/s]\n",
"Predicting DataLoader 0: 100%|██████████| 1/1 [00:00<00:00, 126.52it/s]\n"
]
}
],
"source": [
"Y_hat_df = nf.predict()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"The `NeuralForecast.predict` method returns a DataFrame with the forecasts for each `unique_id`, `ds`, and model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>LSTM</th>\n",
" <th>NHITS</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1.0</td>\n",
" <td>1961-01-31</td>\n",
" <td>424.380310</td>\n",
" <td>453.039185</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1.0</td>\n",
" <td>1961-02-28</td>\n",
" <td>442.092010</td>\n",
" <td>429.609192</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>1961-03-31</td>\n",
" <td>448.555664</td>\n",
" <td>498.796204</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1961-04-30</td>\n",
" <td>473.586609</td>\n",
" <td>509.536224</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1.0</td>\n",
" <td>1961-05-31</td>\n",
" <td>512.466370</td>\n",
" <td>524.131592</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" unique_id ds LSTM NHITS\n",
"0 1.0 1961-01-31 424.380310 453.039185\n",
"1 1.0 1961-02-28 442.092010 429.609192\n",
"2 1.0 1961-03-31 448.555664 498.796204\n",
"3 1.0 1961-04-30 473.586609 509.536224\n",
"4 1.0 1961-05-31 512.466370 524.131592"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Y_hat_df = Y_hat_df.reset_index()\n",
"Y_hat_df.head()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Plot Predictions"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we plot the forecasts of both models againts the real values."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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u+66VvvOnz/frc8rJibG+Pjjj9tdgyefvTv7AMYrr7zS6XshIiIiIt4VhIiIiIhID7V161ZWrFgBwCmnnMKgQYMAOO2008jKyiInJ4ePPvqI4uJi+vTp45Vz1tfXc8kll7Bx40bGjx/PL37xC/r3709ZWZlLxktXFRUVmeO4uDhzXFNTQ1xcHGeccQajR48mMzOTiIgIKioq2LBhA2+//TYFBQV89NFHXH/99bzzzjutjl1TU8NFF11EYWEhAGPGjOHiiy8mLS2NyMhISktL2bJlC0uWLOHHH39stX9+fj6XX345VVVVgL0vxbnnnktycjKhoaEUFxezceNGvvzyy3YzDhobGzn77LPNfhb9+vXjl7/8JccddxyRkZHs3buXBQsW8M0337Bp0yYmTpzIDz/8QFJSUrvvWUVFBeeeey5btmzhrLPO4rzzziM5OZnCwkJeffVV1q5dS3V1NVdeeSU///wzCQkJrY6xf/9+zjjjDDM7JiMjg+uvv55hw4ZRVVXFokWLeO+997jkkksYNWpUu2txeOmll7j55psxDIOgoCDOO+88zjjjDJKTk6murmbFihW88cYb1NbWct111xESEsKVV17Z4TFnzJjBZ599RmZmJtdeey1HHXUUDQ0NrF69mtDQUACefvppXnjhBQCio6P5xS9+wZgxY0hKSqKhoYG8vDzWrl3LF1980elr6G4bN25k0qRJ5vdp2LBhXHPNNQwePJjy8nI+/fRTPvroIxoaGrjnnnuor6/n/vvv7/CYK1eu5P/9v/+HxWJh+vTpnHrqqURFRZGdnU16ero577PPPuPCCy/EarVisViYPHkyU6dOJT09nYaGBtauXcurr75KWVkZf/7znwG477772jznn/70Jx555BHz8SmnnMJ5551HZmYmNpuN3bt3s2LFChYvXtxmz6mamhosFgujRo1i4sSJHHXUUeZ3NC8vjy+++IKFCxdSUVHBpZdeysqVKzn++ONbHceTz37BggUAXHzxxQAcffTRPPjgg63mtXVeEREREelm/o4OiYiIiIi055577jH/svull15y2fbXv/7V3PbEE090eJyuZM44fh5++OFO1+c8vyObN292mbt7925z26effmo0NDS0u291dbVx8cUXm/suW7as1Zx3333X3H7XXXd1uJZNmzYZRUVFLs/94x//MPd/6qmnOtz/u+++M2pra1s9/6c//ck8xpVXXmlUVVW1uf/TTz9tzrvqqqvanOP8XgUFBRnvvPNOqzmNjY3G+eefb8577LHH2jzWtddea84544wz2lzXxx9/bISEhLSZseLsxx9/NEJDQw3A6N+/v7F+/fo2z/nzzz8b6enpBmBER0cbBw4caDXHOXMGMC666KI231eHo48+2gCMhIQEIzc3t915dXV1xqpVq9rd3hlPM2dsNptx7LHHmseYPn16m9/vDz74wAgODjazWNauXdtqjvN1Cxh9+/Y1fvzxx3bPnZ+fb2Y0xcbGGl9++WW78xxrDAwMNLZs2dJqzocffmieNzIy0vjggw/aPe+BAweMJUuWtHp+48aNxvbt29vdzzAM44svvjAiIiIMwDjzzDPbnOONz97xWiZNmtThekRERETEdxScEREREZEeyWq1Gv369TPAXiKqrKzMZfuOHTvMG47HHHNMh8fqanDmwgsvdGuN7gRnSkpKjHHjxpnzxo8f79axnZWXl5ullW688cZW2x966CHz+Js2bery8Z1LJlVXV3d5/3379hlhYWEGYIwdO9ZobGzscP5VV11l3hjPy8trtd35ff3rX//a7nG2bt1qzmvrxnZhYaEZAIiNjTX27dvX7rH+8pe/dBqccQTJAgMDjXXr1nX4GhcvXtxhoM85OJOWltZhyTrDMMygkDtl/DzhHJxx5+fgm/0ff/yxy3VptVrbPdesWbPMuZdffnmr7QcHZxYsWNDh2u+44w5z7kcffdTh3J9//tkIDAw0AOOWW25x2Waz2cyACGC89dZbHR7LU86B5rauB2989grOiIiIiPQ8AYiIiIiI9ED/+9//2LdvHwAXXXQRsbGxLtsHDRrEKaecAtjLKK1evdpr57799tu7vM+HH37o8vP6669zzz33cNRRR/Hdd98BEBISwuOPP97lY8fExDBy5EgAVq1a1Wp7ZGSkOf7++++7fHxP93/77bepq6sD4O677yYwMLDD+ddeey0ATU1NfPnll+3OCwgI4A9/+EO724cOHUr//v0B2LRpU6vtn3zyCVarFYCrrrqKvn37tnus2267jaCg9qs+l5WV8dFHHwEwZcoURo8e3e5cgMmTJ5OamgrA559/3uHc66+/nqioqA7nOD6jn376iYaGhg7n+tP7779vju++++4O39MZM2YQEREB2K93x2fVloyMDC68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S5cuZf/+/WzcuJGysjK3M1xGjBjBBx98QFJSEjabzaVhOsBpp53Gxx9/DMAHH3zAySeffMhr9aYTTjiB559/HoAlS5aYAaq2FBUVdRhYmjRpEhaLBcMw+Pjjj2loaCAkJMTraz4UQUFBXHbZZezdu9cMvC1btoxLL73U52sZP348W7ZsAeDzzz9n+vTp7c6trKxk5cqVgL1s2ahRow75vMcddxxxcXGUlZWxbNkyiouL3epZ1JaJEyea4w8//JD/+7//6/IxnANTnV3fjgybQ+HuZ+/47h5K+UURERER6R7KnBERERGRHqO8vJz3338fsP+F+LPPPsvMmTM7/XnyySfNY8yfP7/Nvg09jXPJrR07dnQ4929/+5vH5wsODiYtLc187AgMuSshIcEs93RwD5Vf/vKXZp+L559/vtPX4yvnnnuuWTLqjTfeYP/+/e3Ofeqppzr83vTp04dzzz0XsN94nzNnjncX6wUDBgwwx139fL3FOQA2Z86cDtfxz3/+0yx/dsEFF7hV3qs9gYGBXH311QDU19dz//33H/Kxjj/+eI4++mgAfvjhB95+++0uH8Pd63vlypUsXLiw64s8SGefvaPsm7vl5kRERESk+yk4IyIiIiI9xptvvkltbS0AZ511VoelgJwNHTqU8ePHA1BQUODRX6L7SkxMDEOHDgXg+++/57333ms1p6mpiTvuuKPTm7f/+te/ePfdd12amh9s2bJlbNiwAbCXbXLOKpg1axaff/45Nput3f3ffPNNs+n66NGjXbalpaWZf7VfU1PD1KlT+eGHHzpc88aNG7nllls6nOOpfv36ceWVVwL2wN8vf/nLNm9Of/LJJzz66KOdHu/BBx80g1B/+ctf+Oc//9lhJkJ5eTlPPvkkX3zxxSG+AruCggLuuuuuDkuzWa1WXnzxRfPxcccd59E5D9W0adPMDJiffvqJm266qVUwD+C///0vDzzwAGAPrPzxj3/0+Nx//vOfSUhIAODFF1/k3nvvbfPcDrW1tbzyyiu89dZbLs9bLBYefPBB8/ENN9zAhx9+2O5xSktLzRKFDieccII5njVrFnV1da3227BhA5dddlmH3yFvffaO4M3PP/9s/o4VEREREf9SWTMRERER6TGcS5pde+21Xdr32muvZdWqVeZxzj//fK+urTvMmDHD7DVz+eWXc8UVVzBp0iTi4+PZsWMHb7zxBlu2bOGYY44hNDSU77//vs3jrFu3jvnz5xMbG8vUqVM5/vjjSU9PJygoiKKiIpYsWcLHH39sBl8O7hmzZMkSZs6cSd++fZk6dSrHHXccKSkpWCwWCgoK+Oyzz1wCDAfvD/bAxY8//shnn31GdnY2Y8eO5eyzz+aMM84gLS0Ni8XCgQMH2LhxI19//TVbtmwhMDDQLDvWXR577DEWL15MQUEBX331FSNGjOD666/nqKOOoqqqikWLFvHuu++SkJDAcccdx5dffgnQZkP1UaNG8e9//5vp06djs9mYMWMGzz77LBdffDHDhw8nMjKSyspKdu7cyerVq1m6dCkNDQ289tprHr2G+vp6Hn/8cR5//HHGjBnDqaeeyogRI4iLi6OqqoqdO3fyn//8x+yZM3DgQH75y196dM5DZbFYeOONNxg/fjxVVVW88sorfPvtt1x77bUMHDiQiooKPvvsM5e+KLNmzeL444/3+NwpKSm8++67nHvuudTV1fHoo4/yxhtvcNlll3HssccSHR1NdXU1ubm5rF27li+//JKamhozSOTsoosu4q677mLOnDlUV1dz8cUXc8opp3DeeeeRmZmJYRjs2bOHb7/9loULF3LFFVdw2mmnmftfcsklZGRksHv3btauXcuwYcO48cYbGTx4MDU1NSxdupS33noLq9XK9OnTmT9/fpuvyVuf/eTJk9mwYQPV1dWcf/75XHvttSQlJWGxWAAYOXKkS2adiIiIiPiAISIiIiLSA6xfv94ADMCIjY01amtru7R/SUmJERoaagBGUFCQUVhYaG5bsmSJeey//e1vbe6fmZlpAEZmZqbb53Qc81D/s9pmsxnXX3+9y3EO/hk5cqSRnZ1tTJo0qd1z/frXv+7wGI6f4OBg48EHH2y1/+mnn+7W/pGRkcbLL7/c7uuxWq3GPffcYwQHB7t1vPbea8f2SZMmdfoedvS+OGzevNnIyMhodx2JiYnG119/bVx11VXmcyUlJe0eb9GiRUZ6erpbrzE0NNT47LPPWh1j+vTp5pxdu3Z1+BpzcnLcOhdgHHPMMcaOHTs6fd/as2vXrk4/H3esXbvWvKba+wkJCTEeeeSRdo/hznXblnXr1hlHHXWUW+9XYGCg8dJLL7V7rMcee8wICwvr9Di//vWv23wP+vTp0+G5H3744Q5fp7c++7179xr9+vVrd99XXnnF7fdXRERERLxDmTMiIiIi0iM4Z81cdtllhIWFdWn/+Ph4zj//fN577z0aGxuZP3++V0oldSeLxcLcuXM599xzefHFF1m7di0VFRUkJiYybNgwLrvsMm644YZO34vnn3+e6667jiVLlrB8+XK2bt3K/v37aWxsJCYmhiFDhnDaaadxww03MGTIkFb7f/zxxyxfvpwlS5awcuVKduzYQXFxMYZhEBcXx1FHHcXkyZO58cYbSU1NbXcdQUFBPProo/z+97/n5Zdf5quvvmL79u2UlJQQEBBAYmIiQ4cOZdy4cUydOtWl8Xp3Gj58OJs3b+af//wn7733Hjt27MAwDPr378/555/P7bffTlpaGg8//LD5Ohz9ddoyZcoUM2Phk08+Ye3atezfv5+6ujqio6PJyspi1KhRnHHGGZx//vnExcV5tP7MzEx2797NkiVLWLJkCevWrWP37t1UVlYSEhJCcnIyo0eP5tJLL+Xyyy8nKMj//5s3ZswYtm7dyty5c/noo4/YsGEDBw4cIDIykszMTKZMmcKtt97q0ivFW0aPHs2mTZtYsGABH330EatWrWLfvn1UV1cTFRVF//79GTlyJKeffjrnn39+h+UT77rrLn71q1/x4osvsmjRIrZv305paSkhISGkpaVx/PHHM23aNJdeO87vwYYNG5gzZw4ff/wxubm5BAUFkZqayumnn85NN93E8ccf36okmjNvffapqamsW7eOOXPm8MUXX7Br1y6qqqo6LKkmIiIiIt3LYui/xkRERERE5Ahns9lITk5m//79jBo1ivXr1/t7SSIiIiIichhrXUhZRERERETkCPP222+zf/9+AE4//XQ/r0ZERERERA53Cs6IiIiIiMhhbdWqVdTV1bW7ffny5fzud78DICAggJtuuslXSxMRERERkSOU/4sRi4iIiIiIdKOHH36Yb775hmnTpjF27Fizb87evXv54osvWLhwodl7449//CPDhw/353JFREREROQIoJ4zIiIiIiJyWLvooov46KOPOpxjsVi46667eOSRRwgIUIEBERERERHpXgrOiIiIiIjIYW3Hjh3897//ZfHixezcuZMDBw5QUVFBdHQ0GRkZTJo0iZtuuomjjz7a30sVEREREZEjhIIzIiIiIiIiIiIiIiIiPqSeMx6w2Wzk5+cTHR2NxWLx93JERERERERERERERMSPDMOgsrKS1NTUDksmKzjjgfz8fPr37+/vZYiIiIiIiIiIiIiISA+yZ88e0tPT292u4IwHoqOjAdi1axcJCQl+Xo2IdIXVamXRokWcddZZBAcH+3s5ItIFun5Fei9dvyK9l65fkd5L169I76Xrt3eqqKigf//+ZvygPQrOeMBRyiw6OpqYmBg/r0ZEusJqtRIREUFMTIz+5SbSy+j6Fem9dP2K9F66fkV6L12/Ir2Xrt/erbNWKO0XPOvBsrKysFgsrX5+97vfAfaabjNnziQ1NZXw8HBOO+00Nm3a5HKM+vp6brvtNvr06UNkZCQXXHABeXl5/ng5IiIiIiIiIiIiIiJyBOmVwZk1a9ZQUFBg/ixevBiAyy67DIBHH32Uxx9/nKeffpo1a9aQnJzMlClTqKysNI8xY8YMFixYwFtvvcXy5cupqqrivPPOo6mpyS+vSUREREREREREREREjgy9sqxZUlKSy+OHH36YQYMGMWnSJAzD4Mknn+T+++/nkksuAWD+/Pn069ePN998k5tvvpny8nLmzp3La6+9xuTJkwF4/fXX6d+/P1988QVTp05t87z19fXU19ebjysqKgB7epnVau2Olyoi3cRxzeraFel9dP2K9F66fkV6L12/Ir2Xrl+R3kvXb+/k7udlMQzD6Oa1dKuGhgZSU1O58847+fOf/0x2djaDBg1i3bp1jB492px34YUXEhcXx/z58/nqq68488wzKSkpIT4+3pwzatQoLrroImbNmtXmuWbOnNnmtjfffJOIiAjvvzgREREREREREREREek1ampq+NWvfkV5eXmHvep7ZeaMsw8//JCysjKuu+46AAoLCwHo16+fy7x+/fqRm5trzgkJCXEJzDjmOPZvy3333cedd95pPq6oqKB///6cfvrpJCYmeuPliIiPWK1WFi9ezJQpU9RQTaSX0fUr0nvp+hXpvXT9ivReun5Fei9dv72To+JWZ3p9cGbu3LlMmzaN1NRUl+ctFovLY8MwWj13sM7mhIaGEhoa2ur54OBgXRwivZSuX5HeS9evSO+l61ek99L1K9J76foV6b10/fYu7n5WvTo4k5ubyxdffMEHH3xgPpecnAzYs2NSUlLM54uKisxsmuTkZBoaGigtLXXJnikqKuKkk07q9nVbrVaampq6/TzSOwQGBuqXq4iIiIiIiIiIiMgRpFcHZ1555RX69u3Lueeeaz43YMAAkpOTWbx4sdlzpqGhgaVLl/LII48AMGbMGIKDg1m8eDGXX345AAUFBWzcuJFHH32029ZbUVFBcXEx9fX13XYO6Z1CQ0Pp06dPhzUIRUREREREREREROTw0GuDMzabjVdeeYXp06cTFNTyMiwWCzNmzGD27NkMGTKEIUOGMHv2bCIiIvjVr34FQGxsLDfccAN33XUXiYmJJCQkcPfddzNy5EgmT57cLeutqKhg7969REVF0adPH4KDgzstsyaHP8MwsFqtlJeXs3fvXgAFaEREREREREREREQOc702OPPFF1+we/durr/++lbb/vjHP1JbW8utt95KaWkp48aNY9GiRURHR5tznnjiCYKCgrj88supra3lzDPPZN68eQQGBnbLeouLi4mKiiI9PV1BGXERHh5OdHQ0eXl5FBcXKzgjIiIiIiIiIiIicpjrtcGZs846C8Mw2txmsViYOXMmM2fObHf/sLAwnnrqKZ566qluWmELq9VKfX09ffr0UWBG2mSxWIiNjWXv3r1YrVb1oBERERERERERERE5jAX4ewFHgqamJgDdcJcOOb4fju+LiIiIiIiIiIiIiByeFJzxIWXNSEf0/RARERERERERERE5Mig4IyIiIiIiIiIiIiIi4kMKzoiIiIiIiIiIiIiIiPiQgjMiIiIiIiIiIiIiIiI+pOCMiIiIiIiIiIiIiIiIDyk4IyIiIiIiIiIiIiIi4kMKzoiIiIiIiIiIiIiIiPiQgjMiIiIiIiIiIiIiIuJXFQ0V1DfV+3sZPqPgjPjFmjVrsFgsnHzyye3OmTVrFhaLhQcffNCHKxMRERERERERERERX9pYvJEz3jmDiW9N5KUNL1HXWOfvJXU7BWfEL0444QTGjBnDypUr2bRpU6vtNpuNV155hcDAQH7961/7YYUiIiIiIiIiIiIi4gsLdy2kvqmemsYa/vXDv7jwwwv5bNdnGIbh76V1GwVnxG9uvvlmAP7973+32rZo0SJyc3M555xzSEtL8/XSRERERERERERERMRHcitzXR7nV+fzx2/+yDWfXcOG/Rv8tKruFeTvBYjd+U8tZ39l76inlxQdyv9uO8Xj4/zqV7/i7rvv5rXXXuPhhx8mNDTU3OYI2PzmN7/x+DwiIiIiIiIiIiIi0nPtqdgDQHBAMCcmn8iK/BUA/Lj/R6769CrOGXAOM46fQUpUij+X6VUKzvQQ+yvrKaw4/OvoOYuMjOSqq67iueeeY8GCBfzyl78EoKioiP/+97+kpqZyzjnn+HmVIiIiIiIiIiIiItJdbIaNPZX24ExGdAbPT3meZXnLeGztY2SXZwPw6a5P+XL3l1w74lpuHHkjEcER/lyyVyg400MkRYd2PqmH8OZab7nlFp577jleeuklMzgzb948rFYr119/PYGBgV47l4iIiIiIiIiIiIj0LIXVhTTYGgDIiMkA4NT0UxmfOp73tr3Hs+ufpay+jPqmel766SUW7FjA3WPv5tyB5/pz2R5TcKaH8EaZsN7o2GOPZfz48SxZsoSdO3cyaNAg5s6di8Vi4YYbbvD38kRERERERERERESkG+VWtPSbyYjOMMfBAcFcedSVnDPgHF7c8CJv/vwmjbZGimuL+dOyPzEwdiDDE4f7Y8leEeDvBYjccsstGIbB3LlzWbp0Kdu2bWPKlClkZWX5e2kiIiIiIiIiIiIi0o12V+w2x47MGWexobHcc8I9fHThR4xLGWc+/3PJzz5ZX3dRcEb87vLLLyc+Pp558+bx3HPPAfCb3/zGz6sSERERERERERERke6WW9mSOZMZk9nuvIyYDK4efrX5uKC6oFvX1d0UnBG/Cw8P59prr6WgoIC3336bpKQkLrzwQn8vS0RERERERERERES6mXPmTEfBGYCUyBRznF+V321r8gUFZ6RHuPnmm83xddddR3BwsB9XIyIiIiIiIiIiIiK+4Og5ExoYSt+Ivh3OTY1KNcfKnBHxguHDh5Oaar+wbrzxRj+vRkRERERERERERES6W6OtkbyqPAD6R/cnwNJxyCI6JJro4GhAmTMiXrFy5Ury8/OZNGkSQ4cO9fdyRERERERERERERKSbFVQX0GhrBDovaeaQEmUvbVZYU0iTranb1tbdFJyRHmH27NkA/P73v/fzSkRERERERERERETEF5z7zWTEZLi1j6O0WaOtkf21+7tlXb4Q5O8FyJFr5cqVzJ07l40bN7J69WrGjBnDJZdc4u9liYiIiIiIiIiIiIgPOPrNAGRGu5c5kxrp2ncmOTLZ6+vyBWXOiN9s27aNl19+mS1btnD++efzwQcfEBCgr6SIiIiIiIiIiIjIkWB35aFnzkDv7jujzBnxm+uuu47rrrvO38sQERERERERERERET9wyZxxt+dMZIo5Lqgu8PqafEVpCiIiIiIiIiIiIiIi4nOOnjPhQeEkhSe5tc/hkjmj4IyIiIiIiIiIiIiIiPiU1WZlb9VeADKiM7BYLG7t55w5k1+t4IyIiIiIiIiIiIiIiIhb8qvyaTKaAPf7zQAkhCUQFhhmHqO3UnBGRERERERERERERER86lD6zQBYLBZSouzZMwVVBRiG4fW1+YKCMyIiIiIiIiIiIiIi4lOOfjNgL2vWFamR9r4zdU11lNaXenVdvqLgjIiIiIiIiIiIiIiI+NShZs4AZuYM2LNneiMFZ0RERERERERERERExKf2VO4xx13pOQMtmTMA+dW9s++MgjMiIiIiIiIiIiIiIuJTjsyZyOBIEsMSu7RvapRTcKZKwRkREREREREREREREZEOWZusZsZLRnQGFoulS/srOCPiAYvF0qWLrqysjL/+9a8cd9xxREZGEh4eTkZGBhMnTuT+++9n/fr1AMybN888trs/M2fOBGDmzJnmc1OnTu1wPSNGjDDnzps37xDfBREREREREREREZEjS15VHjbDBnS93wxASmRLz5neWtYsyN8LEHFHbm4uEydOZPfu3URHR3PSSSfRt29fiouLWbt2LcuWLePAgQM8//zzDB48mOnTp7c6xvz58wG49NJLiYqKctl23HHHtZr/5ZdfUlhYSHJycqtt69atY8uWLd55cSIiIiIiIiIiIiJHkN0Vu81xV/vNACSFJxFkCaLRaKSgqsCbS/MZBWekV/j973/P7t27Oe+883j99deJjY01tzU2NrJ48WL27dsHwCmnnMIpp5zS6hiO4Mxjjz1GVlZWh+cbPXo0P/zwA2+99RYzZsxotf31118H4Pjjj2fdunWH+KpEREREREREREREjjyOfjNwaJkzgQGB9Ivsx96qvb02c0ZlzaTHq62tZeHChQA8+eSTLoEZgKCgIKZNm8Z1113ntXNecMEFxMTE8MYbb7Ta1tTUxFtvvcXQoUM54YQTvHZOERERERERERERkSPB7kqnzJnormfOQEvfmcqGSqoaqryyLl9ScEZ6vNLSUhobGwFISkryyTnDwsK49NJLWbt2LVu3bnXZ9uWXX1JQUMDVV1/tk7WIiIiIiIiIiIiIHE6cM2cOpawZQGpkqjnujdkzCs5Ij9enTx/CwsIAeP7553123quuugqgVfaM47Fju4iIiIiIiIiIiIi4z9FzJjo4mvjQ+EM6hiNzBiC/SsEZEa8LCQnhmmuuAeDee+/lhBNO4G9/+xsLFy6kvLy82857+umnk5aW5hKcqa2tZcGCBUyYMIGBAwd227lFREREREREREREDkf1TfUUVBcA9qwZi8VySMdJiUwxxwrOiHSTJ598kmuuuQaLxcLatWv5+9//zrRp00hMTOT0009n0aJFXj9nQEAAV155JdnZ2Xz77bcAfPjhh1RWVqqkmYiIiIiIiIiIiMghyKvMw8AADr2kGbhmzjiCPb1JkL8XIM1emARVRf5ehXui+sLNS316yoiICF599VXuv/9+3nvvPZYvX86aNWs4cOAAX3/9NV9//TVz5szhzjvv9Op5r776ah577DFef/11JkyYwOuvv05wcDBXXHGFV88jIiIiIiIiIiIiciRw7jeTGZN5yMdx6TnTCzNnFJzpKaqKoLL3fYF8bdiwYdx///0A2Gw2vv32W+677z6WLVvGvffey6WXXkpm5qFf0AcbNWoUI0eO5J133uH+++9n0aJFZsaOiIiIiIiIiIiIiHSNo98MQEb0oWfOJEcmY8GCgaHMGfFAVF9/r8B9PWStAQEBnHzyySxcuJCjjjqKPXv28Pnnn3PTTTd59TxXXXUVf/rTn7jhhhtobGxUSTMRERERERERERGRQ5Rb6Z3MmeDAYJIikiiqKVLmjHjAx2XCDicRERGceOKJ7Nmzh+LiYq8f/6qrruK+++5j4cKFxMTEcMEFF3j9HCIiIiIiIiIiIiJHAufMGU+CM2AvbVZUU8SBugPUNdYRFhTm6fJ8JsDfCxDxhp07dwKQmpraycyuS09P59xzzyUxMZGrr76asLDec4GLiIiIiIiIiIiI9CSOnjOxobHEhsZ6dKyUqBRz3NtKmyk4Iz1eWVkZ48aNY8GCBVitVpdtVquVBx98kPXr1xMeHs7ZZ5/dLWv43//+R3FxMc8880y3HF9ERERERERERETkcFfbWMu+mn0AZEZ73js8NbLlj/ULqnpXcEZlzcTvxo8f3+62O+64g6lTp7J69WouueQSYmJiGDNmDMnJyZSVlbF+/XoKCgoIDAzkueeeIzk52YcrFxERERERERERERF37ancY44zYjI8Pl5qVEtwJr+6d/WdUXBG/O67775rd1tBQQGxsbGsXLmShQsX8vXXX5Odnc2KFSsIDAwkIyODc889l9tuu41jjz3Wh6sWERERERERERERka5w7jfj9eBMlYIzIm4xDMPtuRMmTGDChAndfr6ZM2cyc+ZMt4/5/PPP8/zzz3uwKhEREREREREREZEjw+7KluBMq7JmpbkQFArR7ldHcilrpp4zIiIiIiIiIiIiIiIirpwzZzJjnIIzOcvhn6Pg2fFQvN3t4yVHtgRyelvmjIIzIiIiIiIiIiIiIiLS7XIrcs2xS1mzH14HDKgtha8fdvt4EcERxIfGA72v54yCMyIiIiIiIiIiIiIi0u0cmTMJYQlEh0S3bMhZ0TLe+D7s3+b2MVOiUgAoqinCarN6ZZ2+oOCMiIiIiIiIiIiIiIh0qxprDUW1RQBkRDtlzZTmQvlup5kGLHvM7eM6+s7YDBtFNUXeWKpPKDgjIiIiIiIiIiIiIiLdak/lHnPsUtIsd0XryT+9Cwd2unXc1KhUc9yb+s4oOCMiIiIiIiIiIiIiPZphGHz6UwHfZR/w91LkEDn3m8mMyWzZ4FzSbNCZ9n8aNvjGvewZ5+BMQXWBR2v0JQVnRERERERERERERKRH++SnAm59Yx1XvLiKjzf0nuwIabG7sqV0mWvmzHL7PwND4eIXICzO/njD21CS3elxUyJTzPHeqr3eWKpPKDgjIiIiIiIiIiIiIj3ad9kl5vi+939iT0mNH1cjh8Ilcya6OXOmfC+U5tjH6WMhKgkm/M7+2GiCZXM6Pa5L5kyVMmdERERERERERERERLwi1ykYU1nfyO//8wPWJpsfVyRdtbuijcwZ534zmSfb/3niTRAaax//+FZL8KYdzpkz+dW9J6tKwRkRERERERERERER6dEOzpT5cU8Zjy3a6qfVyKFwZM4khiUSGRxpfzJnecuErObgTHgcjP+tfWxrhOVPdHjcmJAY83jKnBERERERERERERER8YImm0FeqT04kxgZQnCgBYAXlmazdNt+fy5N3FTVUMWBugMAZMZktmxwZM4EBEP6iS3Pj78FQqLt4x/egLI97R7bYrGYpc0KqguwGb0jo0rBGRERERERERERERHpsQrKa7E2GQCMyYzn3rOPMrfd9c56iirr/LU0cdPuyjZKmlUWwoEd9nHa8RAS0bJDeDyMu9k+tlk7zZ5JjbQHZ6w2K8W1xV5bd3dScEZEREREREREREREeqzdB1pKmmUmRnDDKQM4fVgSAMVVDdz59o/YbIa/liducO43Y2bOtNVvxtmE30FIlH38w2tQvrfd47v0nanqHX1nFJwRERERERERERERkR5rt1O/mYyECCwWC49dNoq+0aEALN9RzPPf7PTX8sQNjn4zABnRzZkzOU7Bmaw2gjMRCXDib+zjpgZY8WS7x3eUNQN7abPeQMEZ8RuLxYLFYiE+Pp6ysrI258ycOROLxcLDDz/c5vMzZ8506xydPe947O5PVlaWy/Heffddpk6dSp8+fQgODqZv374ce+yx3HDDDbzxxhtuvR8iIiIiIiIiIiLSWq5zcCbR3vg9MSqUJ395HI5bfHMWbeP73FJ/LE/c4FzWrFXmjCUQ+o9re8cJt0Gw/TPn+/lQ0XbgJSWq92XOBPl7ASJlZWU88cQTzJo1y29rmD59eqvnli9fzs6dOxk1ahTHHXecy7Y+ffqY4+uuu4758+cDMHbsWAYMGEBTUxObNm3i5Zdf5o033uCqq67q1vWLiIiIiIiIiIgcrg7OnHE4aVAfbjt9MP/6agdNNoPb//MDn/7hVGLDg/2xTOmAc+ZM/+j+UF0M+3+2P5E6GkKj294xMhFOuAFW/gua6mHFP2Haw62mpUWmmePekjmj4Iz4VUBAAEFBQTz55JPMmDGD+Ph4v6xj3rx5rZ677rrr2LlzJxdddFG7GTrvv/8+8+fPJz4+nkWLFjF27FiX7du3b2fu3LndsGIREREREREREZEjg6PnTIAF0uLCXbbdfuYQvs0+wJqcUvaW1fKn9zfw7FXHt1lNR/zH0XOmb3hfIoIjYPvilo1tlTRzdtLtsPolaKyF71+BU+6A6H4uU3pj5ozKmolfBQcHc+ONN1JRUcHjjz/u7+V02QcffADA7373u1aBGYAhQ4a0KskmIiIiIiIiIiIi7nNkzqTEhhMS5HpLOygwgCd/OdrMlvlsYyFvrt7d6hjiPxUNFZTW20vOZcQ4+s0sb5mQeUrHB4hKsmfPADTW2bNoDpIYlkhooL0HkYIzIm7685//TGhoKP/85z8pKSnx93K6ZP/+/QAkJSX5eSUiIiIiIiIiIiKHn/IaK+W1VgAyEyPanJMWF86jvzjWfPz3/23m58IKn6xPOufImgGnfjM5jn4zAZAxvvODnHQ7BIXZx2vmQtV+l80Wi4WUSHv2TH51PoZheLzu7qbgjPhdWloav/nNb6isrGTOnDn+Xk6XpKenA/Daa69RXV3t59WIiIiIiIiIiIgcXnJLWu65OfebOdjUo5O5doL9xn99o43fv/kD9Y1N3b4+6ZxzcCYjJgNqSqBok/2J5GMhLKbzg0T3gzG/to8ba9vMnnEEZ2obaymvL/d43d1NwRnpEe677z7CwsJ46qmnOHDggL+X47brr78ei8XC2rVrGTBgADfffDOvvfYaO3fu9PfSREREREREREREej1HSTOAjHYyZxz+fM5wjkq2N5bfUVTFtzt7z33Gw1luZa45zozOhNyVLRuzOilp5uzkP0Bz6TLW/Nse5HGSGpVqjvOre35psyB/L0Dsrvj4Copri/29DLf0Ce/D2+e97dVjpqamctNNN/Gvf/2Lxx57jIceesit/WbNmsWsWbO8upauOOWUU3j11Ve5/fbb2b9/Py+++CIvvvgiAJmZmdx0003ceeedhIWF+W2NIiIiIiIiIiIivVXugZbgTGZCZIdzw4ID+fXJWdz7/k+Aa2BH/KdV5syWl1s2Zp7s/oFiUuD4a+yBGWsN5CyDEReam52DMwVVBYxIHOHRurtbrw3O7N27l3vvvZfPPvuM2tpahg4dyty5cxkzZgwAhmEwa9YsXnzxRUpLSxk3bhzPPPMMRx99tHmM+vp67r77bv7zn/9QW1vLmWeeybPPPmuWqvKl4tpiimqKfH7enuRPf/oTL774Ik8//TR33XUXffr06XSfUaNGcdxxx7W7ff78+V5cYduuvvpqLrzwQj744AO+/PJL1qxZw88//0xubi73338///3vf1myZAnh4eHdvhYREREREREREZHDyR7nzJkOypo5pMW1zNlbVtsta5KucQ7O9I/uDznLmx9ZIHNC1w6WMcEenAEo2eWyyVHWDJQ5021KS0s5+eSTOf300/nss8/o27cvO3fuJC4uzpzz6KOP8vjjjzNv3jyGDh3Kgw8+yJQpU9i6dSvR0fbUthkzZvC///2Pt956i8TERO666y7OO+88vv/+ewIDA336mvqEdx6I6Cm6a60pKSnccsstPPnkk/zjH//gkUce6XSfiy66iJkzZ7a73RfBGYDo6GimT5/O9OnTAcjLy+PZZ5/l0Ucf5bvvvuPxxx/n/vvv98laREREREREREREDhfOmTOdlTUDSItv+QPpvaUKzvQEjrJmyZHJhFnroNCe2US/YyA8vmsHSxjYMi7JdtnkUtasSsGZbvHII4/Qv39/XnnlFfO5rKwsc2wYBk8++ST3338/l1xyCWC/Sd+vXz/efPNNbr75ZsrLy5k7dy6vvfYakydPBuD111+nf//+fPHFF0ydOtWnr8nbZcJ6q3vvvZcXXniBZ555hrvvvtvfyzlk6enpzJ49m4aGBubMmcMnn3yi4IyIiIiIiIiIiEgXOUqTxYYHExse3On8lNiW9gLKnPG/8vpyyuvLgeZ+M7tXAYZ9Y1YXSpo5JAxoGZe6Zs6kRio40+3++9//MnXqVC677DKWLl1KWloat956K7/5zW8A2LVrF4WFhZx11lnmPqGhoUyaNImVK1dy88038/3332O1Wl3mpKamcswxx7By5co2gzP19fXU19ebjysqKgCwWq1YrdZ212u1WjEMA5vNhs1m8/j1H26c35O+fftyyy238MQTT/DII48QGWmvI+l4/xwMw2jzeXfO4c7zh3KOtkycOJE5c+ZQXFzc6TFsNhuGYWC1Wn2euXUkclyzHV27ItIz6foV6b10/Yr0Xrp+RXovXb/SmzU02igotwdYMhLC3foeBwJ9okIormogv7S2V3/3D4frd2fJTnOcHpVO065vcNz5bEwfj9HV1xYURVB4PJbaUowD2TQ67R8XHEegJZAmo4n8qny/vW/unrdXBmeys7N57rnnuPPOO/nzn//M6tWruf322wkNDeXaa6+lsLAQgH79+rns169fP3Jz7SlUhYWFhISEEB8f32qOY/+DPfTQQ202n1+yZAkREe2n1AUFBZGcnExVVRUNDQ1deq1HAkeQy+G3v/0tL7zwAs899xxXXHEFAHV1dS7zHEGy+vr6Vvu7c47OnoeWi6ijcxiGgcViafcYmzdvBuxBp87W2dDQQG1tLd988w2NjY0dzhXvWbx4sb+XICKHSNevSO+l61ek99L1K9J76fqV3qioFmyG/RZ2UF0Zn376qVv7RRJIMRaKKuv478efEhTQnavsfr35+l3fsN4cV+dVU5H7BY478ou3VdOQ7d5n6myiJZ54SqFiLws//ghbQEtGVTTRlFFGblmu298Xb6upqel8Er00OGOz2Rg7diyzZ88GYPTo0WzatInnnnuOa6+91px38E3zzm6kdzbnvvvu48477zQfV1RU0L9/f04//XQSExPbPWZdXR179uwhKiqKsLCw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fj75+flUV1fzww8/MGPGDIKDg4mKimLBggWUlpayZ88eHnnkEaKjo7HZbNx4443s2bOny+uor69ny5YtpKSkMGDAAJKTk11SvRoaGli6dKkZeBkzZgzBwcEucwoKCti4cWOHwRkRERERERERETk8zP50C0u22v/YODY8mLnXnUBsRMsNtdS4cHO8t0zN4XuKnftb+s0MSor06rHDggPpE2X/w2x95t63Ob8lm2B4SowfV+JqcN8oEiPt/YZW7yqhyebbpvC+YDNs7CjbAUBaVBoRwV1s0WEYsLW5hFlAEAye7OUV+khGc2Ezowny1gIwOG6wuXl76XafLsej4My+ffs455xzKCwsZMmSJcyZM4dRo0YRENBy2ICAAEaNGsXjjz/OkiVLKCws5JxzzqGgoIC0tDTuuecevv76a8LDw2loaODpp5/u9Lx33303S5cuZdeuXXz33Xf84he/oKKigunTp2OxWJgxYwazZ89mwYIFbNy4keuuu46IiAh+9atfARAbG8sNN9zAXXfdxZdffskPP/zA1VdfzciRI5k8uZd+sURERERERERExC3/Wb2bucvtf0UeFGDhuauPZ0Af1xv9zsGZfN2o7zGy97dkXwxM8n5zkLR4++deVFlPfWOT149/pDIMg80F9uBMckwYCc3BkJ7AYrEwfqC9ZUVlfaNLEOlwUVBdQG2j/ffY4PjBncxuw/6foczez53MkyAs1our86GMCS3j3fZSZrGhsfSLsFfc2l66HcPwXXDOo+DMnDlzKCws5M4772TChAmdzp8wYQJ33nknRUVF/OMf/zCfHz16NNdffz2GYbjV3CgvL48rr7ySYcOGcckllxASEsKqVavIzMwE4I9//CMzZszg1ltvZezYsezdu5dFixYRHd2SmvjEE09w0UUXcfnll3PyyScTERHB//73PwIDAw/hnRARERERERERkd5g5c5i/vrhRvPxAxcdw0mD+rSap+BMz+SSOdPX+8GZ9ObgjGFAQVmd149/pNpbVktlXSMAI1J7TtaMw/iBCeZ4VfYBP66ke+ws22mOnTNF3Lb1s5bxMM97sviNI3MGYPdKczgkfggAldZK9tXs89lyPArOfPTRR1gsFqZOner2PmeffTYAn3zyicvz06bZGxDl5OR0eoy33nqL/Px8Ghoa2Lt3L++//z4jRowwt1ssFmbOnElBQQF1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3333nXbu3KkZM2Zo7969GjhwYJneG1DR2Wr8StJrr71WrM3LL79cZvcFVAa2GL/t27cvdiwpKUn333+/oqOj1bJlyzK/R6CissX45fkVUDasMX5XrFih66+/Xj179tSqVau0evVqjRw5Uk5O5x7v8/zKARmwkGT89NNPlu2dO3cakowtW7ZY9uXn5xsBAQHG+PHji527YcMGo0aNGkZSUtIF/Xz22WdGSEiIUVBQYNm3fv16Q5Kxe/fuMrsfoDK51vHbpUsX4/HHHy/RNSZOnGj4+flZKWIAZ9li/J71888/GyaTycjNzS1t2ACMsh2/UVFRxvvvv2/liAGcZat/f3Nzc42QkBDjtddes0bYAIyyG788vwLK3rWO3zZt2hgvv/xyia7B8yvHUelnzlxOTk6OJMnDw8Oyz9nZWW5ublq2bJllX2Zmpu68806NHTtWYWFhF+3Hzc2tWCbT09NTkor1A8B6Sjp+Jenrr79WUFCQGjZsqGeeeUZpaWk2jRVAcWU1fk+dOqWvv/5a7du3l6ura9kED1Ry1h6///3vfxUYGKhmzZrp9ddfV25ubtneAFCJldW/v7/88otOnDjBJ++BMmSt8cvzK8D2SjJ+k5OT9ffffyskJETt27dXaGiounTpwrisAEjOXEa9evUUFRWlF154QadPn1Zubq7eeustHT16VElJSZZ2Tz75pNq3b6+bbrrpov1cd911Onr0qN5++23l5ubq9OnTevHFFyWpWD8ArKek4/euu+7SN998o0WLFulf//qXZsyYoQEDBtgxcgDWHr/PPfecvL29FRgYqAMHDujnn3+25e0AlYo1x+/jjz+u6dOna+HChRo5cqQ++OADjRgxwta3BFQaZfX385dffqlevXopIiLCFrcBVErWGr88vwJsryTjNyEhQZI0evRoPfDAA5ozZ47i4uLUrVu3S66NDsfgYu8AyjNXV1fNmDFDw4YNU0BAgJydndW9e3f17t3b0uaXX37RggULtH79+kv207BhQ02ePFlPPfWUXnjhBTk7O+uxxx5TaGionJ2dbXErQKVTkvErmevtntWoUSPFxsaqZcuWWrduneLi4mwdNgBZf/w+++yzGjZsmPbv369XX31V99xzj3799deLrhMHoHSsOX6ffPJJS5smTZqoatWqGjhwoGU2DQDrKou/nw8dOqQ//vhD3333nU3uAaisrDV+eX4F2F5Jxm9hYaEk6aGHHtK9994rSWrevLn+/PNPTZgwQW+++aZdYkfpMXPmClq0aKENGzbozJkzSkpK0pw5c3Ty5EnFxMRIkhYsWKC9e/fK399fLi4ucnEx57tuueUWxcfHW/oZNGiQjh49qsOHD+vkyZMaPXq0jh8/bukHgPVdafxeTFxcnFxdXfnkAWBn1hy/QUFBqlOnjnr06KHp06frt99+08qVK8v6FoBKq6z+/W3btq0kac+ePVaPGYCZtcfvxIkTFRgYqH79+pVl2ABkvfHL8yvA9q40fqtVqyZJatCgQbHz6tevrwMHDtg8XlgPyZkS8vPzU3BwsHbv3q01a9ZYSpg9//zz2rRpkzZs2GD5kqT3339fEydOvKCf0NBQValSRd9++608PDzUo0cPW94GUCldavxezNatW5WXl2f5hw+AfVl7/BqGIelcXV8AZcfa4/fsTHX+jQbKnjXGr2EYmjhxou655x7WegNsyFr//vL8CrC9S43f6OhohYeHa+fOncXa79q1S1FRUfYIFVZS6cuapaenF/v03b59+7RhwwYFBAQoMjJS33//vYKDgxUZGanNmzfr8ccfV//+/dWzZ09JUlhYmMLCwi7oNzIystinCsaOHav27durSpUqmjdvnp599lm99dZb8vf3L/N7BCqq0o7fvXv36uuvv9YNN9ygoKAgbdu2TU8//bSaN2+uDh06WPo9cOCATp06pQMHDqigoMCShK1du7aqVKli03sGKgpbjN9Vq1Zp1apV6tixo6pWraqEhAT93//9n2rVqqV27drZ5b6BisAW43fFihVauXKlunbtKj8/P61evVpPPvmk+vXrp8jISLvcN1AR2OrvZ8lcZWLfvn0aNmyYTe8RqKhsNX55fgVYX2nHr8lk0rPPPqtXXnlFTZs2VbNmzTR58mTt2LFDP/zwg6Vfnl85IKOSW7hwoSHpgq8hQ4YYhmEYH374oVGjRg3D1dXViIyMNF5++WUjJyfnsn1KMn766adi+wYPHmwEBAQYbm5uRpMmTYyvvvqqjO4IqDxKO34PHDhgdO7c2TI2a9WqZTz22GPGyZMni11nyJAhF73OwoULbXi3QMVii/G7adMmo2vXrkZAQIDh7u5uREdHGw8//LBx6NAhW98uUKHYYvyuXbvWaNOmjeHn52d4eHgYdevWNV555RUj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",
"text/plain": [
"<Figure size 2000x700 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots(1, 1, figsize = (20, 7))\n",
"plot_df = pd.concat([Y_df, Y_hat_df]).set_index('ds') # Concatenate the train and forecast dataframes\n",
"plot_df[['y', 'LSTM', 'NHITS']].plot(ax=ax, linewidth=2)\n",
"\n",
"ax.set_title('AirPassengers Forecast', fontsize=22)\n",
"ax.set_ylabel('Monthly Passengers', fontsize=20)\n",
"ax.set_xlabel('Timestamp [t]', fontsize=20)\n",
"ax.legend(prop={'size': 15})\n",
"ax.grid()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-tip}\n",
"For this guide we are using a simple `LSTM` model. More recent models, such as `RNN`, `GRU`, and `DilatedRNN` achieve better accuracy than `LSTM` in most settings. The full list of available models is available [here](https://nixtla.github.io/neuralforecast/models.html).\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"- [Boris N. Oreshkin, Dmitri Carpov, Nicolas Chapados, Yoshua Bengio (2020). \"N-BEATS: Neural basis expansion analysis for interpretable time series forecasting\". International Conference on Learning Representations.](https://arxiv.org/abs/1905.10437)<br>\n",
"- [Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021). NHITS: Neural Hierarchical Interpolation for Time Series Forecasting. Accepted at AAAI 2023.](https://arxiv.org/abs/2201.12886)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# How to add new Models to NeuralForecast\n",
"> Tutorial on how to add new models to NeuralForecast"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-warning}\n",
"\n",
"## Prerequisites\n",
"\n",
"This Guide assumes advanced familiarity with NeuralForecast.\n",
"\n",
"We highly recommend reading first the Getting Started and the NeuralForecast Map tutorials!\n",
"\n",
"Additionally, refer to the [CONTRIBUTING guide](https://github.com/Nixtla/neuralforecast/blob/main/CONTRIBUTING.md) for the basics how to contribute to NeuralForecast.\n",
"\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"This tutorial is aimed at contributors who want to add a new model to the NeuralForecast library. The library's existing modules handle optimization, training, selection, and evaluation of deep learning models. The `core` class simplifies building entire pipelines, both for industry and academia, on any dataset, with user-friendly methods such as `fit` and `predict`.\n",
"\n",
"<h4 style=\"text-align: center;\"> Adding a new model to NeuralForecast is simpler than building a new PyTorch model from scratch. You only need to write the forward method. </h4>\n",
"\n",
"**It has the following additional advantages:**\n",
"\n",
"* Existing modules in NeuralForecast already implement the essential training and evaluating aspects for deep learning models.\n",
"* Integrated with PyTorch-Lightning and Tune libraries for efficient optimization and distributed computation.\n",
"* The `BaseModel` classes provide common optimization components, such as early stopping and learning rate schedulers.\n",
"* Automatic performance tests are scheduled on Github to ensure quality standards.\n",
"* Users can easily compare the performance and computation of the new model with existing models.\n",
"* Opportunity for exposure to a large community of users and contributors."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### Example: simplified MLP model\n",
"\n",
"We will present the tutorial following an example on how to add a simplified version of the current `MLP` model, which does not include exogenous covariates.\n",
"\n",
"At a given timestamp $t$, the `MLP` model will forecast the next $h$ values of the univariate target time, $Y_{t+1:t+h}$, using as inputs the last $L$ historical values, given by $Y_{t-L:t}$. The following figure presents a diagram of the model."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"![Figure 1. Three layer MLP with autorregresive inputs.](../imgs_models/mlp.png)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 0. Preliminaries\n",
"\n",
"Follow our tutorial on contributing [here](https://github.com/Nixtla/neuralforecast/blob/main/CONTRIBUTING.md) to set up your development environment.\n",
"\n",
"Here is a short list of the most important steps:\n",
"\n",
"1. Create a fork of the `neuralforecast` library.\n",
"2. Clone the fork to your computer.\n",
"3. Set an environment with the `neuralforecast` library, core dependencies, and `nbdev` package to code your model in an interactive notebook."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Inherit the Base Class (`BaseWindows`)\n",
"\n",
"\n",
"The library contains **three** types of base models: `BaseWindows`, `BaseRecurrent`, and `BaseMultivariate`. In this tutorial, we will focus on the `BaseWindows` class, which is the most common type of model in the library, with models such as `NBEATS`, `NHITS`, `TFT`, and `PatchTST`. The main difference between the three types is the sampling procedure and input batch for the `forward` method, which determines the type of model. \n",
"\n",
":::{.callout-important}\n",
"\n",
"If you want to add a `BaseRecurrent` or `BaseMultivariate` model, please add an issue in our github.\n",
"\n",
":::\n",
"\n",
"### a. Sampling process\n",
"\n",
"During training, the base class receives a sample of time series of the dataset from the `TimeSeriesLoader` module. The `BaseWindows` models will sample individual windows of size `input_size+h`, starting from random timestamps.\n",
"\n",
"### b. `BaseWindows`' hyperparameters\n",
"\n",
"Get familiar with the hyperparameters specified in the base class, including `h` (horizon), `input_size`, and optimization hyperparameters such as `learning_rate`, `max_steps`, among others. The following list presents the hyperparameters related to the sampling of windows:\n",
" \n",
" * `h` (h): number of future values to predict.\n",
" * `input_size` (L): number of historic values to use as input for the model.\n",
" * `batch_size` (bs): number of time series sampled by the loader during training.\n",
" * `valid_batch_size` (v_bs): number of time series sampled by the loader during inference (validation and test).\n",
" * `windows_batch_size` (w_bs): number of individual windows sampled during training (from the previous time series) to form the batch.\n",
" * `inference_windows_batch_size` (i_bs): number of individual windows sampled during inference to form each batch. Used to control the GPU memory.\n",
"\n",
"### c. Input and Output batch shapes\n",
"\n",
"The `forward` method receives a batch of data in a dictionary with the following keys:\n",
"\n",
"- `insample_y`: historic values of the time series.\n",
"- `insample_mask`: mask indicating the available values of the time series (1 if available, 0 if missing).\n",
"- `futr_exog`: future exogenous covariates (if any).\n",
"- `hist_exog`: historic exogenous covariates (if any).\n",
"- `stat_exog`: static exogenous covariates (if any).\n",
"\n",
"The following table presents the shape for each tensor:\n",
"\n",
"| `tensor` | `BaseWindows` |\n",
"|-----------------|--------------------------|\n",
"| `insample_y` | (`w_bs`, `L`) |\n",
"| `insample_mask` | (`w_bs`, `L`) |\n",
"| `futr_exog` | (`w_bs`, `L`+`h`, `n_f`) |\n",
"| `hist_exog` | (`w_bs`, `L`, `n_h`) |\n",
"| `stat_exog` | (`w_bs`,`n_s`) |\n",
"\n",
"The `forward` function should return a single tensor with the forecasts of the next `h` timestamps for each window. Use the attributes of the `loss` class to automatically parse the output to the correct shape (see the example below). \n",
"\n",
":::{.callout-tip}\n",
"\n",
"Since we are using `nbdev`, you can easily add prints to the code and see the shapes of the tensors during training.\n",
"\n",
":::\n",
"\n",
"### d. `BaseWindows`' methods\n",
"\n",
"The `BaseWindows` class contains several common methods for all windows-based models, simplifying the development of new models by preventing code duplication. The most important methods of the class are:\n",
"\n",
"* `_create_windows`: parses the time series from the `TimeSeriesLoader` into individual windows of size `input_size+h`.\n",
"* `_normalization`: normalizes each window based on the `scaler` type.\n",
"* `_inv_normalization`: inverse normalization of the forecasts.\n",
"* `training_step`: training step of the model, called by PyTorch-Lightning's `Trainer` class during training (`fit` method).\n",
"* `validation_step`: validation step of the model, called by PyTorch-Lightning's `Trainer` class during validation.\n",
"* `predict_step`: prediction step of the model, called by PyTorch-Lightning's `Trainer` class during inference (`predict` method)."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Create the model file and class\n",
"\n",
"Once familiar with the basics of the `BaseWindows` class, the next step is creating your particular model.\n",
"\n",
"The main steps are:\n",
"\n",
"1. Create the file in the `nbs` folder (https://github.com/Nixtla/neuralforecast/tree/main/nbs). It should be named `models.YOUR_MODEL_NAME.ipynb`.\n",
"2. Add the header of the `nbdev` file.\n",
"3. Import libraries in the file. \n",
"4. Define the `__init__` method with the model's inherited and particular hyperparameters and instantiate the architecture.\n",
"5. Define the `forward` method, which recieves the input batch dictionary and returns the forecast."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### a. Model class"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"First, add the following **two cells** on top of the `nbdev` file.\n",
"\n",
"```python\n",
"#| default_exp models.mlp\n",
"```\n",
"\n",
":::{.callout-important}\n",
"\n",
"Change `mlp` to your model's name, using lowercase and underscores. When you later run `nbdev_export`, it will create a `YOUR_MODEL.py` script in the `neuralforecast/models/` directory.\n",
"\n",
":::\n",
"\n",
"```python\n",
"#| hide\n",
"%load_ext autoreload\n",
"%autoreload 2\n",
"```\n",
"\n",
"Next, add the dependencies of the model.\n",
"\n",
"```python\n",
"#| export\n",
"from typing import Optional\n",
"\n",
"import torch\n",
"import torch.nn as nn\n",
"\n",
"from neuralforecast.losses.pytorch import MAE\n",
"from neuralforecast.common._base_windows import BaseWindows\n",
"```\n",
"\n",
":::{.callout-tip}\n",
"\n",
"Don't forget to add the `#| export` tag on this cell.\n",
"\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, create the class with the `init` and `forward` methods. The following example shows the example for the simplified `MLP` model. We explain important details after the code."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"```python\n",
"#| export\n",
"class MLP(BaseWindows): # <<---- Inherits from BaseWindows\n",
" def __init__(self,\n",
" # Inhereted hyperparameters with no defaults\n",
" h,\n",
" input_size,\n",
" # Model specific hyperparameters\n",
" num_layers = 2,\n",
" hidden_size = 1024,\n",
" # Inhereted hyperparameters with defaults\n",
" exclude_insample_y = False,\n",
" loss = MAE(),\n",
" valid_loss = None,\n",
" max_steps: int = 1000,\n",
" learning_rate: float = 1e-3,\n",
" num_lr_decays: int = -1,\n",
" early_stop_patience_steps: int =-1,\n",
" val_check_steps: int = 100,\n",
" batch_size: int = 32,\n",
" valid_batch_size: Optional[int] = None,\n",
" windows_batch_size = 1024,\n",
" inference_windows_batch_size = -1,\n",
" step_size: int = 1,\n",
" scaler_type: str = 'identity',\n",
" random_seed: int = 1,\n",
" num_workers_loader: int = 0,\n",
" drop_last_loader: bool = False,\n",
" **trainer_kwargs):\n",
" # Inherit BaseWindows class\n",
" super(MLP, self).__init__(h=h,\n",
" input_size=input_size,\n",
" ..., # <<--- Add all inhereted hyperparameters\n",
" random_seed=random_seed,\n",
" **trainer_kwargs)\n",
"\n",
" # Architecture\n",
" self.num_layers = num_layers\n",
" self.hidden_size = hidden_size\n",
"\n",
" # MultiLayer Perceptron\n",
" layers = [nn.Linear(in_features=input_size, out_features=hidden_size)]\n",
" layers += [nn.ReLU()]\n",
" for i in range(num_layers - 1):\n",
" layers += [nn.Linear(in_features=hidden_size, out_features=hidden_size)]\n",
" layers += [nn.ReLU()]\n",
" self.mlp = nn.ModuleList(layers)\n",
"\n",
" # Adapter with Loss dependent dimensions\n",
" self.out = nn.Linear(in_features=hidden_size, \n",
" out_features=h * self.loss.outputsize_multiplier) ## <<--- Use outputsize_multiplier to adjust output size\n",
"\n",
" def forward(self, windows_batch): # <<--- Receives windows_batch dictionary\n",
" # Parse windows_batch\n",
" insample_y = windows_batch['insample_y'].clone()\n",
" # MLP\n",
" y_pred = self.mlp(y_pred)\n",
" # Reshape and map to loss domain\n",
" y_pred = y_pred.reshape(batch_size, self.h, self.loss.outputsize_multiplier)\n",
" y_pred = self.loss.domain_map(y_pred)\n",
" return y_pred\n",
"\n",
"```"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-tip}\n",
"\n",
"* Don't forget to add the `#| export` tag on each cell.\n",
"* Larger architectures, such as Transformers, might require splitting the `forward` by using intermediate functions.\n",
"\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Important notes\n",
"\n",
"The base class has many hyperparameters, and models must have default values for all of them (except `h` and `input_size`). If you are unsure of what default value to use, we recommend copying the default values from existing models for most optimization and sampling hyperparameters. You can change the default values later at any time.\n",
"\n",
"The `reshape` method at the end of the `forward` step is used to adjust the output shape. The `loss` class contains an `outputsize_multiplier` attribute to automatically adjust the output size of the forecast depending on the `loss`. For example, for the Multi-quantile loss (`MQLoss`), the model needs to output each quantile for each horizon.\n",
"\n",
"**Finally, always include `y_pred = self.loss.domain_map(y_pred)` at the end of the `forward`**. This is necessary to map the output to the domain (and shape) of the loss function. For example, if the loss function is the `MAE`, it maps the output of shape `(batch_size, h, 1)` to `(batch_size, h)`.\n",
"\n",
"### b. Tests and documentation\n",
"\n",
"`nbdev` allows for testing and documenting the model during the development process. It allows users to iterate the development within the notebook, testing the code in the same environment. Refer to existing models, such as the complete MLP model [here](https://github.com/Nixtla/neuralforecast/blob/main/nbs/models.mlp.ipynb). These files already contain the tests, documentation, and usage examples that were used during the development process.\n",
"\n",
"### c. Export the new model to the library with `nbdev`\n",
"\n",
"Following the CONTRIBUTING guide, the next step is to export the new model from the development notebook to the `neuralforecast` folder with the actual scripts.\n",
"\n",
"To export the model, run `nbdev_export` in your terminal. You should see a new file with your model in the `neuralforecast/models/` folder."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Core class and additional files\n",
"\n",
"Finally, add the model to the `core` class and additional files:\n",
"\n",
"1. Manually add the model in the following [init file](https://github.com/Nixtla/neuralforecast/blob/main/neuralforecast/models/__init__.py).\n",
"2. Add the model to the `core` class, using the `nbdev` file [here](https://github.com/Nixtla/neuralforecast/blob/main/nbs/core.ipynb):\n",
" \n",
" a. Add the model to the initial model list:\n",
" ```python\n",
" from neuralforecast.models import (\n",
" GRU, LSTM, RNN, TCN, DilatedRNN,\n",
" MLP, NHITS, NBEATS, NBEATSx,\n",
" TFT, VanillaTransformer,\n",
" Informer, Autoformer, FEDformer,\n",
" StemGNN, PatchTST\n",
" )\n",
" ```\n",
" b. Add the model to the `MODEL_FILENAME_DICT` dictionary (used for the `save` and `load` functions)."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Upload to GitHub\n",
"\n",
"Congratulations! The model is ready to be used in the library following the steps above. \n",
"\n",
"Follow our contributing guide's final steps to upload the model to GitHub: [here](https://github.com/Nixtla/neuralforecast/blob/main/CONTRIBUTING.md).\n",
"\n",
"One of the maintainers will review the PR, request changes if necessary, and merge it into the library."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Quick Checklist\n",
"\n",
"* Get familiar with the `BaseWindows` class hyperparameters and input/output shapes of the `forward` method.\n",
"* Create the notebook with your model class in the `nbs` folder: `models.YOUR_MODEL_NAME.ipynb`\n",
"* Add the header and import libraries.\n",
"* Implement `init` and `forward` methods.\n",
"* Export model with `nbdev_export`.\n",
"* Add model to this [init file](https://github.com/Nixtla/neuralforecast/blob/main/neuralforecast/models/__init__.py).\n",
"* Add the model to the `core ` class [here](https://github.com/Nixtla/neuralforecast/blob/main/nbs/core.ipynb).\n",
"* Follow the CONTRIBUTING guide to create the PR to upload the model.\n"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"id": "14f5686c-449b-4376-8c58-fc8141f4b0f8",
"metadata": {},
"source": [
"# Install\n",
"\n",
"> Install NeuralForecast with pip or conda"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "0f1d1483-6da7-4372-8390-84c9c280109e",
"metadata": {},
"source": [
"You can install the *released version* of `NeuralForecast` from the [Python package index](https://pypi.org) with:\n",
"\n",
"```shell\n",
"pip install neuralforecast\n",
"```\n",
"\n",
"or \n",
"\n",
"```shell\n",
"conda install -c conda-forge neuralforecast\n",
"``` \n",
"\n",
":::{.callout-tip}\n",
"Neural Forecasting methods profit from using GPU computation. Be sure to have Cuda installed.\n",
":::\n",
"\n",
":::{.callout-warning}\n",
"We are constantly updating neuralforecast, so we suggest fixing the version to avoid issues. `pip install neuralforecast==\"1.0.0\"`\n",
":::\n",
"\n",
":::{.callout-tip}\n",
"We recommend installing your libraries inside a python virtual or [conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/install/macos.html).\n",
":::\n",
"\n",
"## Extras\n",
"You can use the following extras to add optional functionality:\n",
"\n",
"* distributed training with spark: `pip install neuralforecast[spark]`\n",
"* saving and loading from S3: `pip install neuralforecast[aws]`\n",
"\n",
"#### User our env (optional)\n",
"\n",
"If you don't have a Conda environment and need tools like Numba, Pandas, NumPy, Jupyter, Tune, and Nbdev you can use ours by following these steps:\n",
"\n",
"1. Clone the NeuralForecast repo: \n",
"\n",
"```bash \n",
"$ git clone https://github.com/Nixtla/neuralforecast.git && cd neuralforecast\n",
"```\n",
"\n",
"2. Create the environment using the `environment.yml` file: \n",
"\n",
"```bash \n",
"$ conda env create -f environment.yml\n",
"```\n",
"\n",
"3. Activate the environment:\n",
"```bash\n",
"$ conda activate neuralforecast\n",
"```\n",
"\n",
"4. Install NeuralForecast Dev\n",
"```bash\n",
"$ pip install -e \".[dev]\"\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "b9084b7a",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"# Probabilistic Long-Horizon"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"Long-horizon forecasting is challenging because of the *volatility* of the predictions and the *computational complexity*. To solve this problem we created the [NHITS](https://arxiv.org/abs/2201.12886) model and made the code available [NeuralForecast library](https://nixtla.github.io/neuralforecast/models.nhits.html). `NHITS` specializes its partial outputs in the different frequencies of the time series through hierarchical interpolation and multi-rate input processing. We model the target time-series with Student's t-distribution. The `NHITS` will output the distribution parameters for each timestamp. \n",
"\n",
"In this notebook we show how to use `NHITS` on the [ETTm2](https://github.com/zhouhaoyi/ETDataset) benchmark dataset for probabilistic forecasting. This data set includes data points for 2 Electricity Transformers at 2 stations, including load, oil temperature.\n",
"\n",
"We will show you how to load data, train, and perform automatic hyperparameter tuning, **to achieve SoTA performance**, outperforming even the latest Transformer architectures for a fraction of their computational cost (50x faster)."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"You can run these experiments using GPU with Google Colab.\n",
"\n",
"<a href=\"https://colab.research.google.com/github/Nixtla/neuralforecast/blob/main/nbs/examples/LongHorizon_Probabilistic.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Libraries"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"!pip install neuralforecast datasetsforecast"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Load ETTm2 Data\n",
"\n",
"The `LongHorizon` class will automatically download the complete ETTm2 dataset and process it.\n",
"\n",
"It return three Dataframes: `Y_df` contains the values for the target variables, `X_df` contains exogenous calendar features and `S_df` contains static features for each time-series (none for ETTm2). For this example we will only use `Y_df`.\n",
"\n",
"If you want to use your own data just replace `Y_df`. Be sure to use a long format and have a simmilar structure than our data set."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"from datasetsforecast.long_horizon import LongHorizon"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" <div id=\"df-354ffb05-28c1-497a-81bb-fe74a34dbbc7\">\n",
" <div class=\"colab-df-container\">\n",
" <div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>unique_id</th>\n",
" <th>ds</th>\n",
" <th>y</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>HUFL</td>\n",
" <td>2016-07-01 00:00:00</td>\n",
" <td>-0.041413</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>HUFL</td>\n",
" <td>2016-07-01 00:15:00</td>\n",
" <td>-0.185467</td>\n",
" </tr>\n",
" <tr>\n",
" <th>57600</th>\n",
" <td>HULL</td>\n",
" <td>2016-07-01 00:00:00</td>\n",
" <td>0.040104</td>\n",
" </tr>\n",
" <tr>\n",
" <th>57601</th>\n",
" <td>HULL</td>\n",
" <td>2016-07-01 00:15:00</td>\n",
" <td>-0.214450</td>\n",
" </tr>\n",
" <tr>\n",
" <th>115200</th>\n",
" <td>LUFL</td>\n",
" <td>2016-07-01 00:00:00</td>\n",
" <td>0.695804</td>\n",
" </tr>\n",
" <tr>\n",
" <th>115201</th>\n",
" <td>LUFL</td>\n",
" <td>2016-07-01 00:15:00</td>\n",
" <td>0.434685</td>\n",
" </tr>\n",
" <tr>\n",
" <th>172800</th>\n",
" <td>LULL</td>\n",
" <td>2016-07-01 00:00:00</td>\n",
" <td>0.434430</td>\n",
" </tr>\n",
" <tr>\n",
" <th>172801</th>\n",
" <td>LULL</td>\n",
" <td>2016-07-01 00:15:00</td>\n",
" <td>0.428168</td>\n",
" </tr>\n",
" <tr>\n",
" <th>230400</th>\n",
" <td>MUFL</td>\n",
" <td>2016-07-01 00:00:00</td>\n",
" <td>-0.599211</td>\n",
" </tr>\n",
" <tr>\n",
" <th>230401</th>\n",
" <td>MUFL</td>\n",
" <td>2016-07-01 00:15:00</td>\n",
" <td>-0.658068</td>\n",
" </tr>\n",
" <tr>\n",
" <th>288000</th>\n",
" <td>MULL</td>\n",
" <td>2016-07-01 00:00:00</td>\n",
" <td>-0.393536</td>\n",
" </tr>\n",
" <tr>\n",
" <th>288001</th>\n",
" <td>MULL</td>\n",
" <td>2016-07-01 00:15:00</td>\n",
" <td>-0.659338</td>\n",
" </tr>\n",
" <tr>\n",
" <th>345600</th>\n",
" <td>OT</td>\n",
" <td>2016-07-01 00:00:00</td>\n",
" <td>1.018032</td>\n",
" </tr>\n",
" <tr>\n",
" <th>345601</th>\n",
" <td>OT</td>\n",
" <td>2016-07-01 00:15:00</td>\n",
" <td>0.980124</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-354ffb05-28c1-497a-81bb-fe74a34dbbc7')\"\n",
" title=\"Convert this dataframe to an interactive table.\"\n",
" style=\"display:none;\">\n",
" \n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
" width=\"24px\">\n",
" <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
" <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
" </svg>\n",
" </button>\n",
" \n",
" <style>\n",
" .colab-df-container {\n",
" display:flex;\n",
" flex-wrap:wrap;\n",
" gap: 12px;\n",
" }\n",
"\n",
" .colab-df-convert {\n",
" background-color: #E8F0FE;\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: #1967D2;\n",
" height: 32px;\n",
" padding: 0 0 0 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-convert:hover {\n",
" background-color: #E2EBFA;\n",
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: #174EA6;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert {\n",
" background-color: #3B4455;\n",
" fill: #D2E3FC;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert:hover {\n",
" background-color: #434B5C;\n",
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
" fill: #FFFFFF;\n",
" }\n",
" </style>\n",
"\n",
" <script>\n",
" const buttonEl =\n",
" document.querySelector('#df-354ffb05-28c1-497a-81bb-fe74a34dbbc7 button.colab-df-convert');\n",
" buttonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
"\n",
" async function convertToInteractive(key) {\n",
" const element = document.querySelector('#df-354ffb05-28c1-497a-81bb-fe74a34dbbc7');\n",
" const dataTable =\n",
" await google.colab.kernel.invokeFunction('convertToInteractive',\n",
" [key], {});\n",
" if (!dataTable) return;\n",
"\n",
" const docLinkHtml = 'Like what you see? Visit the ' +\n",
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
" + ' to learn more about interactive tables.';\n",
" element.innerHTML = '';\n",
" dataTable['output_type'] = 'display_data';\n",
" await google.colab.output.renderOutput(dataTable, element);\n",
" const docLink = document.createElement('div');\n",
" docLink.innerHTML = docLinkHtml;\n",
" element.appendChild(docLink);\n",
" }\n",
" </script>\n",
" </div>\n",
" </div>\n",
" "
],
"text/plain": [
" unique_id ds y\n",
"0 HUFL 2016-07-01 00:00:00 -0.041413\n",
"1 HUFL 2016-07-01 00:15:00 -0.185467\n",
"57600 HULL 2016-07-01 00:00:00 0.040104\n",
"57601 HULL 2016-07-01 00:15:00 -0.214450\n",
"115200 LUFL 2016-07-01 00:00:00 0.695804\n",
"115201 LUFL 2016-07-01 00:15:00 0.434685\n",
"172800 LULL 2016-07-01 00:00:00 0.434430\n",
"172801 LULL 2016-07-01 00:15:00 0.428168\n",
"230400 MUFL 2016-07-01 00:00:00 -0.599211\n",
"230401 MUFL 2016-07-01 00:15:00 -0.658068\n",
"288000 MULL 2016-07-01 00:00:00 -0.393536\n",
"288001 MULL 2016-07-01 00:15:00 -0.659338\n",
"345600 OT 2016-07-01 00:00:00 1.018032\n",
"345601 OT 2016-07-01 00:15:00 0.980124"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Change this to your own data to try the model\n",
"Y_df, _, _ = LongHorizon.load(directory='./', group='ETTm2')\n",
"Y_df['ds'] = pd.to_datetime(Y_df['ds'])\n",
"\n",
"# For this excercise we are going to take 960 timestamps as validation and test\n",
"n_time = len(Y_df.ds.unique())\n",
"val_size = 96*10\n",
"test_size = 96*10\n",
"\n",
"Y_df.groupby('unique_id').head(2)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-important}\n",
"DataFrames must include all `['unique_id', 'ds', 'y']` columns.\n",
"Make sure `y` column does not have missing or non-numeric values. \n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, plot the `HUFL` variable marking the validation and train splits."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 720x360 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# We are going to plot the temperature of the transformer \n",
"# and marking the validation and train splits\n",
"u_id = 'HUFL'\n",
"x_plot = pd.to_datetime(Y_df[Y_df.unique_id==u_id].ds)\n",
"y_plot = Y_df[Y_df.unique_id==u_id].y.values\n",
"\n",
"x_val = x_plot[n_time - val_size - test_size]\n",
"x_test = x_plot[n_time - test_size]\n",
"\n",
"fig = plt.figure(figsize=(10, 5))\n",
"fig.tight_layout()\n",
"\n",
"plt.plot(x_plot, y_plot)\n",
"plt.xlabel('Date', fontsize=17)\n",
"plt.ylabel('OT [15 min temperature]', fontsize=17)\n",
"\n",
"plt.axvline(x_val, color='black', linestyle='-.')\n",
"plt.axvline(x_test, color='black', linestyle='-.')\n",
"plt.text(x_val, 5, ' Validation', fontsize=12)\n",
"plt.text(x_test, 3, ' Test', fontsize=12)\n",
"\n",
"plt.grid()\n",
"plt.show()\n",
"plt.close()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Hyperparameter selection and forecasting\n",
"\n",
"The `AutoNHITS` class will automatically perform hyperparamter tunning using [Tune library](https://docs.ray.io/en/latest/tune/index.html), exploring a user-defined or default search space. Models are selected based on the error on a validation set and the best model is then stored and used during inference. \n",
"\n",
"The `AutoNHITS.default_config` attribute contains a suggested hyperparameter space. Here, we specify a different search space following the paper's hyperparameters. Notice that *1000 Stochastic Gradient Steps* are enough to achieve SoTA performance. Feel free to play around with this space."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ray import tune\n",
"\n",
"from neuralforecast.auto import AutoNHITS\n",
"from neuralforecast.core import NeuralForecast\n",
"\n",
"from neuralforecast.losses.pytorch import DistributionLoss\n",
"\n",
"import logging\n",
"logging.getLogger(\"pytorch_lightning\").setLevel(logging.WARNING)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"horizon = 96 # 24hrs = 4 * 15 min.\n",
"\n",
"# Use your own config or AutoNHITS.default_config\n",
"nhits_config = {\n",
" \"learning_rate\": tune.choice([1e-3]), # Initial Learning rate\n",
" \"max_steps\": tune.choice([1000]), # Number of SGD steps\n",
" \"input_size\": tune.choice([5 * horizon]), # input_size = multiplier * horizon\n",
" \"batch_size\": tune.choice([7]), # Number of series in windows\n",
" \"windows_batch_size\": tune.choice([256]), # Number of windows in batch\n",
" \"n_pool_kernel_size\": tune.choice([[2, 2, 2], [16, 8, 1]]), # MaxPool's Kernelsize\n",
" \"n_freq_downsample\": tune.choice([[168, 24, 1], [24, 12, 1], [1, 1, 1]]), # Interpolation expressivity ratios\n",
" \"activation\": tune.choice(['ReLU']), # Type of non-linear activation\n",
" \"n_blocks\": tune.choice([[1, 1, 1]]), # Blocks per each 3 stacks\n",
" \"mlp_units\": tune.choice([[[512, 512], [512, 512], [512, 512]]]), # 2 512-Layers per block for each stack\n",
" \"interpolation_mode\": tune.choice(['linear']), # Type of multi-step interpolation\n",
" \"random_seed\": tune.randint(1, 10),\n",
" \"scaler_type\": tune.choice(['robust']),\n",
" \"val_check_steps\": tune.choice([100])\n",
" }"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
":::{.callout-tip}\n",
"Refer to https://docs.ray.io/en/latest/tune/index.html for more information on the different space options, such as lists and continous intervals.m\n",
":::"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"To instantiate `AutoNHITS` you need to define:\n",
"\n",
"* `h`: forecasting horizon\n",
"* `loss`: training loss. Use the `DistributionLoss` to produce probabilistic forecasts.\n",
"* `config`: hyperparameter search space. If `None`, the `AutoNHITS` class will use a pre-defined suggested hyperparameter space.\n",
"* `num_samples`: number of configurations explored."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"models = [AutoNHITS(h=horizon,\n",
" loss=DistributionLoss(distribution='StudentT', level=[80, 90]), \n",
" config=nhits_config,\n",
" num_samples=5)]"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Fit the model by instantiating a `NeuralForecast` object with the following required parameters:\n",
"\n",
"* `models`: a list of models.\n",
"\n",
"* `freq`: a string indicating the frequency of the data. (See [panda's available frequencies](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases).)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Fit and predict\n",
"nf = NeuralForecast(\n",
" models=models,\n",
" freq='15min')"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"The `cross_validation` method allows you to simulate multiple historic forecasts, greatly simplifying pipelines by replacing for loops with `fit` and `predict` methods.\n",
"\n",
"With time series data, cross validation is done by defining a sliding window across the historical data and predicting the period following it. This form of cross validation allows us to arrive at a better estimation of our model’s predictive abilities across a wider range of temporal instances while also keeping the data in the training set contiguous as is required by our models.\n",
"\n",
"The `cross_validation` method will use the validation set for hyperparameter selection, and will then produce the forecasts for the test set."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"Y_hat_df = nf.cross_validation(df=Y_df, val_size=val_size,\n",
" test_size=test_size, n_windows=None)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Visualization"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we merge the forecasts with the `Y_df` dataset and plot the forecasts."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Y_hat_df = Y_hat_df.reset_index(drop=True)\n",
"Y_hat_df = Y_hat_df[(Y_hat_df['unique_id']=='OT') & (Y_hat_df['cutoff']=='2018-02-11 12:00:00')]\n",
"Y_hat_df = Y_hat_df.drop(columns=['y','cutoff'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plot_df = Y_df.merge(Y_hat_df, on=['unique_id','ds'], how='outer').tail(96*10+50+96*4).head(96*2+96*4)\n",
"\n",
"plt.plot(plot_df['ds'], plot_df['y'], c='black', label='True')\n",
"plt.plot(plot_df['ds'], plot_df['AutoNHITS-median'], c='blue', label='median')\n",
"plt.fill_between(x=plot_df['ds'], \n",
" y1=plot_df['AutoNHITS-lo-90'], y2=plot_df['AutoNHITS-hi-90'],\n",
" alpha=0.4, label='level 90')\n",
"plt.legend()\n",
"plt.grid()\n",
"plt.plot()"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## References\n",
"\n",
"[Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021). NHITS: Neural Hierarchical Interpolation for Time Series Forecasting. Accepted at AAAI 2023.](https://arxiv.org/abs/2201.12886)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "python3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
This source diff could not be displayed because it is too large. You can view the blob instead.
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