{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "47c3d1a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "!pip install -Uqq nixtla pyreadr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a2d9fbbc",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "from nixtla.utils import in_colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73e6dc8b",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "IN_COLAB = in_colab()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ffe4be2b",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "if not IN_COLAB:\n",
    "    from nixtla.utils import colab_badge\n",
    "    from itertools import product\n",
    "    from dotenv import load_dotenv"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0241d5c1-8d11-4cb9-9259-cda5fffa7ea8",
   "metadata": {},
   "source": [
    "# Bounded forecasts"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f73b521-05f2-4c53-b44c-d988bf8fe7b9",
   "metadata": {},
   "source": [
    "In forecasting, we often want to make sure the predictions stay within a certain range. For example, for predicting the sales of a product, we may require all forecasts to be positive. Thus, the forecasts may need to be bounded.\n",
    "\n",
    "With TimeGPT, you can create bounded forecasts by transforming your data prior to calling the forecast function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cdf86af8-08c0-4118-bd6b-0b88a6eac3f7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "[![](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Nixtla/nixtla/blob/main/nbs/docs/tutorials/13_bounded_forecasts.ipynb)"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#| echo: false\n",
    "if not IN_COLAB:\n",
    "    load_dotenv()\n",
    "    colab_badge('docs/tutorials/13_bounded_forecasts')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2997eb35",
   "metadata": {},
   "source": [
    "## 1. Import packages\n",
    "First, we install and import the required packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8a5181e9-634c-4002-9c22-d65f0701fa14",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "from nixtla import NixtlaClient"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9872d00d-ecb1-4a14-9813-bf0c56e70392",
   "metadata": {},
   "outputs": [],
   "source": [
    "nixtla_client = NixtlaClient(\n",
    "    # defaults to os.environ.get(\"NIXTLA_API_KEY\")\n",
    "    api_key = 'my_api_key_provided_by_nixtla'\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9c7b28a",
   "metadata": {},
   "source": [
    "> 👍 Use an Azure AI endpoint\n",
    ">\n",
    "> To use an Azure AI endpoint, set the `base_url` argument:\n",
    ">\n",
    "> `nixtla_client = NixtlaClient(base_url=\"you azure ai endpoint\", api_key=\"your api_key\")`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50eac17f-3c72-4f68-988a-1d5d877dff2b",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "if not IN_COLAB:\n",
    "    nixtla_client = NixtlaClient()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26b99aff-aa07-44a1-b0e1-e8301f7f62bf",
   "metadata": {},
   "source": [
    "## 2. Load data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c77268e7",
   "metadata": {},
   "source": [
    "We use the [annual egg prices](https://github.com/robjhyndman/fpp3package/tree/master/data) dataset from [Forecasting, Principles and Practices](https://otexts.com/fpp3/). We expect egg prices to be strictly positive, so we want to bound our forecasts to be positive. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fa6759e",
   "metadata": {},
   "source": [
    "::: {.callout-note}\n",
    "You can install `pyreadr` with `pip`:\n",
    "    \n",
    "```shell\n",
    "pip install pyreadr\n",
    "```\n",
    ":::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "31b1e602-f8ee-49c4-8819-fcc093d64ab1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pyreadr\n",
    "from pathlib import Path\n",
    "\n",
    "# Download and store the dataset\n",
    "url = 'https://github.com/robjhyndman/fpp3package/raw/master/data/prices.rda'\n",
    "dst_path = str(Path.cwd().joinpath('prices.rda'))\n",
    "result = pyreadr.read_r(pyreadr.download_file(url, dst_path), dst_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2c450a9",
   "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>ds</th>\n",
       "      <th>y</th>\n",
       "      <th>unique_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>84</th>\n",
       "      <td>1984-01-01</td>\n",
       "      <td>100.58</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>85</th>\n",
       "      <td>1985-01-01</td>\n",
       "      <td>76.84</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>86</th>\n",
       "      <td>1986-01-01</td>\n",
       "      <td>81.10</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>87</th>\n",
       "      <td>1987-01-01</td>\n",
       "      <td>69.60</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>88</th>\n",
       "      <td>1988-01-01</td>\n",
       "      <td>64.55</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>89</th>\n",
       "      <td>1989-01-01</td>\n",
       "      <td>80.36</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>90</th>\n",
       "      <td>1990-01-01</td>\n",
       "      <td>79.79</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>91</th>\n",
       "      <td>1991-01-01</td>\n",
       "      <td>74.79</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>92</th>\n",
       "      <td>1992-01-01</td>\n",
       "      <td>64.86</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>93</th>\n",
       "      <td>1993-01-01</td>\n",
       "      <td>62.27</td>\n",
       "      <td>eggs</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           ds       y unique_id\n",
       "84 1984-01-01  100.58      eggs\n",
       "85 1985-01-01   76.84      eggs\n",
       "86 1986-01-01   81.10      eggs\n",
       "87 1987-01-01   69.60      eggs\n",
       "88 1988-01-01   64.55      eggs\n",
       "89 1989-01-01   80.36      eggs\n",
       "90 1990-01-01   79.79      eggs\n",
       "91 1991-01-01   74.79      eggs\n",
       "92 1992-01-01   64.86      eggs\n",
       "93 1993-01-01   62.27      eggs"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Perform some preprocessing\n",
    "df = result['prices'][['year', 'eggs']]\n",
    "df = df.dropna().reset_index(drop=True)\n",
    "df = df.rename(columns={'year':'ds', 'eggs':'y'})\n",
    "df['ds'] = pd.to_datetime(df['ds'], format='%Y')\n",
    "df['unique_id'] = 'eggs'\n",
    "\n",
    "df.tail(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "301c932a",
   "metadata": {},
   "source": [
    "We can have a look at how the prices have evolved in the 20th century, demonstrating that the price is trending down."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "07dfce6b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 75200 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2932318f",
   "metadata": {},
   "source": [
    "## 3. Bounded forecasts with TimeGPT\n",
    "\n",
    "First, we transform the target data. In this case, we will log-transform the data prior to forecasting, such that we can only forecast positive prices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8a967678",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_transformed = df.copy()\n",
    "df_transformed['y'] = np.log(df_transformed['y'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b7f93bc",
   "metadata": {},
   "source": [
    "We will create forecasts for the next 10 years, and we include an 80, 90 and 99.5 percentile of our forecast distribution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dda23c8c",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: AS-JAN\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n"
     ]
    }
   ],
   "source": [
    "timegpt_fcst_with_transform = nixtla_client.forecast(df=df_transformed, h=10, freq='Y', level=[80, 90, 99.5])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b6067300",
   "metadata": {},
   "source": [
    "> 📘 Available models in Azure AI\n",
    ">\n",
    "> If you are using an Azure AI endpoint, please be sure to set `model=\"azureai\"`:\n",
    ">\n",
    "> `nixtla_client.forecast(..., model=\"azureai\")`\n",
    "> \n",
    "> For the public API, we support two models: `timegpt-1` and `timegpt-1-long-horizon`. \n",
    "> \n",
    "> By default, `timegpt-1` is used. Please see [this tutorial](https://docs.nixtla.io/docs/tutorials-long_horizon_forecasting) on how and when to use `timegpt-1-long-horizon`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "967836fa",
   "metadata": {},
   "source": [
    "After having created the forecasts, we need to inverse the transformation that we applied earlier. With a log-transformation, this simply means we need to exponentiate the forecasts:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8f6bf69",
   "metadata": {},
   "outputs": [],
   "source": [
    "cols_to_transform = [col for col in timegpt_fcst_with_transform if col not in ['unique_id', 'ds']]\n",
    "for col in cols_to_transform:\n",
    "    timegpt_fcst_with_transform[col] = np.exp(timegpt_fcst_with_transform[col])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85a370f1",
   "metadata": {},
   "source": [
    "Now, we can plot the forecasts. We include a number of prediction intervals, indicating the 80, 90 and 99.5 percentile of our forecast distribution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67e3933e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 71964 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(\n",
    "    df,\n",
    "    timegpt_fcst_with_transform,\n",
    "    level=[80, 90, 99.5],\n",
    "    max_insample_length=20\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a587baa1",
   "metadata": {},
   "source": [
    "The forecast and the prediction intervals look reasonable."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ddb67e5",
   "metadata": {},
   "source": [
    "Let's compare these forecasts to the situation where we don't apply a transformation. In this case, it may be possible to forecast a negative price."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4c73c041",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: AS-JAN\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n"
     ]
    }
   ],
   "source": [
    "timegpt_fcst_without_transform = nixtla_client.forecast(df=df, h=10, freq='Y', level=[80, 90, 99.5])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49e8f695",
   "metadata": {},
   "source": [
    "Indeed, we now observe prediction intervals that become negative:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "016a37c8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 68700 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(\n",
    "    df,\n",
    "    timegpt_fcst_without_transform,\n",
    "    level=[80, 90, 99.5],\n",
    "    max_insample_length=20\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e66e8c60",
   "metadata": {},
   "source": [
    "For example, in 1995:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32d6e583",
   "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>TimeGPT</th>\n",
       "      <th>TimeGPT-lo-99.5</th>\n",
       "      <th>TimeGPT-lo-90</th>\n",
       "      <th>TimeGPT-lo-80</th>\n",
       "      <th>TimeGPT-hi-80</th>\n",
       "      <th>TimeGPT-hi-90</th>\n",
       "      <th>TimeGPT-hi-99.5</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>eggs</td>\n",
       "      <td>1994-01-01</td>\n",
       "      <td>66.859756</td>\n",
       "      <td>43.103240</td>\n",
       "      <td>46.131448</td>\n",
       "      <td>49.319034</td>\n",
       "      <td>84.400479</td>\n",
       "      <td>87.588065</td>\n",
       "      <td>90.616273</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>eggs</td>\n",
       "      <td>1995-01-01</td>\n",
       "      <td>64.993477</td>\n",
       "      <td>-20.924112</td>\n",
       "      <td>-4.750041</td>\n",
       "      <td>12.275298</td>\n",
       "      <td>117.711656</td>\n",
       "      <td>134.736995</td>\n",
       "      <td>150.911066</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>eggs</td>\n",
       "      <td>1996-01-01</td>\n",
       "      <td>66.695808</td>\n",
       "      <td>6.499170</td>\n",
       "      <td>8.291150</td>\n",
       "      <td>10.177444</td>\n",
       "      <td>123.214173</td>\n",
       "      <td>125.100467</td>\n",
       "      <td>126.892446</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>eggs</td>\n",
       "      <td>1997-01-01</td>\n",
       "      <td>66.103325</td>\n",
       "      <td>17.304282</td>\n",
       "      <td>24.966939</td>\n",
       "      <td>33.032894</td>\n",
       "      <td>99.173756</td>\n",
       "      <td>107.239711</td>\n",
       "      <td>114.902368</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>eggs</td>\n",
       "      <td>1998-01-01</td>\n",
       "      <td>67.906517</td>\n",
       "      <td>4.995371</td>\n",
       "      <td>12.349648</td>\n",
       "      <td>20.090992</td>\n",
       "      <td>115.722042</td>\n",
       "      <td>123.463386</td>\n",
       "      <td>130.817663</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>eggs</td>\n",
       "      <td>1999-01-01</td>\n",
       "      <td>66.147575</td>\n",
       "      <td>29.162207</td>\n",
       "      <td>31.804460</td>\n",
       "      <td>34.585779</td>\n",
       "      <td>97.709372</td>\n",
       "      <td>100.490691</td>\n",
       "      <td>103.132943</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>eggs</td>\n",
       "      <td>2000-01-01</td>\n",
       "      <td>66.062637</td>\n",
       "      <td>14.671932</td>\n",
       "      <td>19.305822</td>\n",
       "      <td>24.183601</td>\n",
       "      <td>107.941673</td>\n",
       "      <td>112.819453</td>\n",
       "      <td>117.453343</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>eggs</td>\n",
       "      <td>2001-01-01</td>\n",
       "      <td>68.045769</td>\n",
       "      <td>3.915282</td>\n",
       "      <td>13.188964</td>\n",
       "      <td>22.950736</td>\n",
       "      <td>113.140802</td>\n",
       "      <td>122.902573</td>\n",
       "      <td>132.176256</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>eggs</td>\n",
       "      <td>2002-01-01</td>\n",
       "      <td>66.718903</td>\n",
       "      <td>-42.212631</td>\n",
       "      <td>-30.583703</td>\n",
       "      <td>-18.342726</td>\n",
       "      <td>151.780531</td>\n",
       "      <td>164.021508</td>\n",
       "      <td>175.650436</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>eggs</td>\n",
       "      <td>2003-01-01</td>\n",
       "      <td>67.344078</td>\n",
       "      <td>-86.239911</td>\n",
       "      <td>-44.959745</td>\n",
       "      <td>-1.506939</td>\n",
       "      <td>136.195095</td>\n",
       "      <td>179.647901</td>\n",
       "      <td>220.928067</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  unique_id          ds    TimeGPT  TimeGPT-lo-99.5  TimeGPT-lo-90  \\\n",
       "0      eggs  1994-01-01  66.859756        43.103240      46.131448   \n",
       "1      eggs  1995-01-01  64.993477       -20.924112      -4.750041   \n",
       "2      eggs  1996-01-01  66.695808         6.499170       8.291150   \n",
       "3      eggs  1997-01-01  66.103325        17.304282      24.966939   \n",
       "4      eggs  1998-01-01  67.906517         4.995371      12.349648   \n",
       "5      eggs  1999-01-01  66.147575        29.162207      31.804460   \n",
       "6      eggs  2000-01-01  66.062637        14.671932      19.305822   \n",
       "7      eggs  2001-01-01  68.045769         3.915282      13.188964   \n",
       "8      eggs  2002-01-01  66.718903       -42.212631     -30.583703   \n",
       "9      eggs  2003-01-01  67.344078       -86.239911     -44.959745   \n",
       "\n",
       "   TimeGPT-lo-80  TimeGPT-hi-80  TimeGPT-hi-90  TimeGPT-hi-99.5  \n",
       "0      49.319034      84.400479      87.588065        90.616273  \n",
       "1      12.275298     117.711656     134.736995       150.911066  \n",
       "2      10.177444     123.214173     125.100467       126.892446  \n",
       "3      33.032894      99.173756     107.239711       114.902368  \n",
       "4      20.090992     115.722042     123.463386       130.817663  \n",
       "5      34.585779      97.709372     100.490691       103.132943  \n",
       "6      24.183601     107.941673     112.819453       117.453343  \n",
       "7      22.950736     113.140802     122.902573       132.176256  \n",
       "8     -18.342726     151.780531     164.021508       175.650436  \n",
       "9      -1.506939     136.195095     179.647901       220.928067  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "timegpt_fcst_without_transform"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "585c8db9",
   "metadata": {},
   "source": [
    "This demonstrates the value of the log-transformation to obtain bounded forecasts with TimeGPT, which allows us to obtain better calibrated prediction intervals."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "deae1784",
   "metadata": {},
   "source": [
    "**References**\n",
    "\n",
    "* [Hyndman, Rob J., and George Athanasopoulos (2021). \"Forecasting: Principles and Practice (3rd Ed)\"](https://otexts.com/fpp3/)\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
