{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0255e7e1",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "!pip install -Uqq nixtla"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5294f415",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide \n",
    "from nixtla.utils import in_colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a4a24cfb",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide \n",
    "IN_COLAB = in_colab()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "282f5cd0",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "if not IN_COLAB:\n",
    "    from nixtla.utils import colab_badge\n",
    "    from dotenv import load_dotenv"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0241d5c1-8d11-4cb9-9259-cda5fffa7ea8",
   "metadata": {},
   "source": [
    "# Quantile forecasts"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0f73b521-05f2-4c53-b44c-d988bf8fe7b9",
   "metadata": {},
   "source": [
    "In forecasting, we are often interested in a distribution of predictions rather than only a point prediction, because we want to have a notion of the uncertainty around the forecast.\\\n",
    "\\\n",
    "To this end, we can create _quantile forecasts_.\\\n",
    "\\\n",
    "Quantile forecasts have an intuitive interpretation, as they present a specific percentile of the forecast distribution. This allows us to make statements such as 'we expect 90% of our observations of air passengers to be above 100'. This approach is helpful for planning under uncertainty, providing a spectrum of possible future values and helping users make more informed decisions by considering the full range of potential outcomes.\\\n",
    "\\\n",
    "With TimeGPT, we can create a distribution of forecasts, and extract the quantile forecasts for a specified percentile. For instance, the 25th and 75th quantiles give insights into the lower and upper quartiles of expected outcomes, respectively, while the 50th quantile, or median, offers a central estimate.\\\n",
    "\\\n",
    "TimeGPT uses [conformal prediction](https://en.wikipedia.org/wiki/Conformal_prediction) to produce the quantiles."
   ]
  },
  {
   "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/10_uncertainty_quantification_with_quantile_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/10_uncertainty_quantification_with_quantile_forecasts')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2997eb35",
   "metadata": {},
   "source": [
    "## 1. Import packages\n",
    "First, we import the required packages and initialize the Nixtla client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8a5181e9-634c-4002-9c22-d65f0701fa14",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from nixtla import NixtlaClient\n",
    "\n",
    "from IPython.display import display"
   ]
  },
  {
   "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": "1e0c97c2",
   "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": "code",
   "execution_count": null,
   "id": "31b1e602-f8ee-49c4-8819-fcc093d64ab1",
   "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>timestamp</th>\n",
       "      <th>value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1949-01-01</td>\n",
       "      <td>112</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1949-02-01</td>\n",
       "      <td>118</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1949-03-01</td>\n",
       "      <td>132</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1949-04-01</td>\n",
       "      <td>129</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1949-05-01</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    timestamp  value\n",
       "0  1949-01-01    112\n",
       "1  1949-02-01    118\n",
       "2  1949-03-01    132\n",
       "3  1949-04-01    129\n",
       "4  1949-05-01    121"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/air_passengers.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2932318f",
   "metadata": {},
   "source": [
    "## 3. Forecast with quantiles\n",
    "When using TimeGPT for time series forecasting, you can set the quantiles you want to predict. Here's how you could do it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "174db3ef-71ff-4bdf-92f3-e3277bb76c43",
   "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: MS\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\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>timestamp</th>\n",
       "      <th>TimeGPT</th>\n",
       "      <th>TimeGPT-q-10</th>\n",
       "      <th>TimeGPT-q-20</th>\n",
       "      <th>TimeGPT-q-30</th>\n",
       "      <th>TimeGPT-q-40</th>\n",
       "      <th>TimeGPT-q-50</th>\n",
       "      <th>TimeGPT-q-60</th>\n",
       "      <th>TimeGPT-q-70</th>\n",
       "      <th>TimeGPT-q-80</th>\n",
       "      <th>TimeGPT-q-90</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1961-01-01</td>\n",
       "      <td>437.837952</td>\n",
       "      <td>431.987091</td>\n",
       "      <td>435.043799</td>\n",
       "      <td>435.384363</td>\n",
       "      <td>436.402155</td>\n",
       "      <td>437.837952</td>\n",
       "      <td>439.273749</td>\n",
       "      <td>440.291541</td>\n",
       "      <td>440.632104</td>\n",
       "      <td>443.688812</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1961-02-01</td>\n",
       "      <td>426.062744</td>\n",
       "      <td>412.704956</td>\n",
       "      <td>414.832837</td>\n",
       "      <td>416.042432</td>\n",
       "      <td>421.719196</td>\n",
       "      <td>426.062744</td>\n",
       "      <td>430.406293</td>\n",
       "      <td>436.083057</td>\n",
       "      <td>437.292651</td>\n",
       "      <td>439.420532</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1961-03-01</td>\n",
       "      <td>463.116577</td>\n",
       "      <td>437.412564</td>\n",
       "      <td>444.234985</td>\n",
       "      <td>446.420233</td>\n",
       "      <td>450.705762</td>\n",
       "      <td>463.116577</td>\n",
       "      <td>475.527393</td>\n",
       "      <td>479.812921</td>\n",
       "      <td>481.998169</td>\n",
       "      <td>488.820590</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1961-04-01</td>\n",
       "      <td>478.244507</td>\n",
       "      <td>448.726837</td>\n",
       "      <td>455.428375</td>\n",
       "      <td>465.570038</td>\n",
       "      <td>469.879114</td>\n",
       "      <td>478.244507</td>\n",
       "      <td>486.609900</td>\n",
       "      <td>490.918976</td>\n",
       "      <td>501.060638</td>\n",
       "      <td>507.762177</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1961-05-01</td>\n",
       "      <td>505.646484</td>\n",
       "      <td>478.409872</td>\n",
       "      <td>493.154315</td>\n",
       "      <td>497.990848</td>\n",
       "      <td>499.138708</td>\n",
       "      <td>505.646484</td>\n",
       "      <td>512.154260</td>\n",
       "      <td>513.302121</td>\n",
       "      <td>518.138654</td>\n",
       "      <td>532.883096</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    timestamp     TimeGPT  TimeGPT-q-10  TimeGPT-q-20  TimeGPT-q-30  \\\n",
       "0  1961-01-01  437.837952    431.987091    435.043799    435.384363   \n",
       "1  1961-02-01  426.062744    412.704956    414.832837    416.042432   \n",
       "2  1961-03-01  463.116577    437.412564    444.234985    446.420233   \n",
       "3  1961-04-01  478.244507    448.726837    455.428375    465.570038   \n",
       "4  1961-05-01  505.646484    478.409872    493.154315    497.990848   \n",
       "\n",
       "   TimeGPT-q-40  TimeGPT-q-50  TimeGPT-q-60  TimeGPT-q-70  TimeGPT-q-80  \\\n",
       "0    436.402155    437.837952    439.273749    440.291541    440.632104   \n",
       "1    421.719196    426.062744    430.406293    436.083057    437.292651   \n",
       "2    450.705762    463.116577    475.527393    479.812921    481.998169   \n",
       "3    469.879114    478.244507    486.609900    490.918976    501.060638   \n",
       "4    499.138708    505.646484    512.154260    513.302121    518.138654   \n",
       "\n",
       "   TimeGPT-q-90  \n",
       "0    443.688812  \n",
       "1    439.420532  \n",
       "2    488.820590  \n",
       "3    507.762177  \n",
       "4    532.883096  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "quantiles = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]\n",
    "timegpt_quantile_fcst_df = nixtla_client.forecast(\n",
    "    df=df, h=12, \n",
    "    quantiles=quantiles, \n",
    "    time_col='timestamp', target_col='value',\n",
    ")\n",
    "timegpt_quantile_fcst_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6367adc2",
   "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": "f75f9fcc-24a5-44b5-b19d-8875360d7af3",
   "metadata": {},
   "source": [
    "TimeGPT will return forecasts in the format `TimeGPT-q-{int(100 * q)}` for each quantile `q`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a2e1bab-2352-4c8d-addd-3b74fdcbdb93",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 113440 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(\n",
    "    df, timegpt_quantile_fcst_df, \n",
    "    time_col='timestamp', target_col='value',\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f3917c3-b5d3-4950-9ff4-32627849d3e7",
   "metadata": {},
   "source": [
    "It's essential to note that the choice of the quantile (or quantiles) depends on your specific use case. For high-stakes predictions, you might lean towards more conservative quantiles, such as the 10th or 20th percentile, to ensure you're prepared for worse-case scenarios. On the other hand, if you're in a situation where the cost of over-preparation is high, you might choose a quantile closer to the median, like the 50th percentile, to balance being cautious and efficient.\n",
    "\n",
    "For instance, if you are managing inventory for a retail business during a big sale event, opting for a lower quantile might help you avoid running out of stock, even if it means you might overstock a bit. But if you are scheduling staff for a restaurant, you might go with a quantile closer to the middle to ensure you have enough staff on hand without significantly overstaffing.\n",
    "\n",
    "Ultimately, the choice comes down to understanding the balance between risk and cost in your specific context, and using quantile forecasts from TimeGPT allows you to tailor your strategy to fit that balance perfectly."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea3023d2-0c86-417c-ad19-a1a584910534",
   "metadata": {},
   "source": [
    "#### Historical Forecast"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c75269d-7cda-4bff-b18a-3a1193d8391e",
   "metadata": {},
   "source": [
    "You can also compute quantile forecasts for historical forecasts adding the `add_history=True` parameter as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e539081f-d5c5-4d82-b223-5b11cbd75503",
   "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: MS\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n",
      "INFO:nixtla.nixtla_client:Calling Historical Forecast Endpoint...\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>timestamp</th>\n",
       "      <th>TimeGPT</th>\n",
       "      <th>TimeGPT-q-10</th>\n",
       "      <th>TimeGPT-q-20</th>\n",
       "      <th>TimeGPT-q-30</th>\n",
       "      <th>TimeGPT-q-40</th>\n",
       "      <th>TimeGPT-q-50</th>\n",
       "      <th>TimeGPT-q-60</th>\n",
       "      <th>TimeGPT-q-70</th>\n",
       "      <th>TimeGPT-q-80</th>\n",
       "      <th>TimeGPT-q-90</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1951-01-01</td>\n",
       "      <td>135.483673</td>\n",
       "      <td>111.937768</td>\n",
       "      <td>120.020593</td>\n",
       "      <td>125.848879</td>\n",
       "      <td>130.828935</td>\n",
       "      <td>135.483673</td>\n",
       "      <td>140.138411</td>\n",
       "      <td>145.118467</td>\n",
       "      <td>150.946753</td>\n",
       "      <td>159.029579</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1951-02-01</td>\n",
       "      <td>144.442398</td>\n",
       "      <td>120.896493</td>\n",
       "      <td>128.979318</td>\n",
       "      <td>134.807604</td>\n",
       "      <td>139.787660</td>\n",
       "      <td>144.442398</td>\n",
       "      <td>149.097136</td>\n",
       "      <td>154.077192</td>\n",
       "      <td>159.905478</td>\n",
       "      <td>167.988304</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1951-03-01</td>\n",
       "      <td>157.191910</td>\n",
       "      <td>133.646004</td>\n",
       "      <td>141.728830</td>\n",
       "      <td>147.557116</td>\n",
       "      <td>152.537172</td>\n",
       "      <td>157.191910</td>\n",
       "      <td>161.846648</td>\n",
       "      <td>166.826703</td>\n",
       "      <td>172.654990</td>\n",
       "      <td>180.737815</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1951-04-01</td>\n",
       "      <td>148.769363</td>\n",
       "      <td>125.223458</td>\n",
       "      <td>133.306284</td>\n",
       "      <td>139.134570</td>\n",
       "      <td>144.114625</td>\n",
       "      <td>148.769363</td>\n",
       "      <td>153.424102</td>\n",
       "      <td>158.404157</td>\n",
       "      <td>164.232443</td>\n",
       "      <td>172.315269</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1951-05-01</td>\n",
       "      <td>140.472946</td>\n",
       "      <td>116.927041</td>\n",
       "      <td>125.009866</td>\n",
       "      <td>130.838152</td>\n",
       "      <td>135.818208</td>\n",
       "      <td>140.472946</td>\n",
       "      <td>145.127684</td>\n",
       "      <td>150.107740</td>\n",
       "      <td>155.936026</td>\n",
       "      <td>164.018852</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    timestamp     TimeGPT  TimeGPT-q-10  TimeGPT-q-20  TimeGPT-q-30  \\\n",
       "0  1951-01-01  135.483673    111.937768    120.020593    125.848879   \n",
       "1  1951-02-01  144.442398    120.896493    128.979318    134.807604   \n",
       "2  1951-03-01  157.191910    133.646004    141.728830    147.557116   \n",
       "3  1951-04-01  148.769363    125.223458    133.306284    139.134570   \n",
       "4  1951-05-01  140.472946    116.927041    125.009866    130.838152   \n",
       "\n",
       "   TimeGPT-q-40  TimeGPT-q-50  TimeGPT-q-60  TimeGPT-q-70  TimeGPT-q-80  \\\n",
       "0    130.828935    135.483673    140.138411    145.118467    150.946753   \n",
       "1    139.787660    144.442398    149.097136    154.077192    159.905478   \n",
       "2    152.537172    157.191910    161.846648    166.826703    172.654990   \n",
       "3    144.114625    148.769363    153.424102    158.404157    164.232443   \n",
       "4    135.818208    140.472946    145.127684    150.107740    155.936026   \n",
       "\n",
       "   TimeGPT-q-90  \n",
       "0    159.029579  \n",
       "1    167.988304  \n",
       "2    180.737815  \n",
       "3    172.315269  \n",
       "4    164.018852  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "timegpt_quantile_fcst_df = nixtla_client.forecast(\n",
    "    df=df, h=12, \n",
    "    quantiles=quantiles, \n",
    "    time_col='timestamp', target_col='value',\n",
    "    add_history=True,\n",
    ")\n",
    "timegpt_quantile_fcst_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b9dddbe-0c5a-4d21-abcf-f664e176c7a7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 214272 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(\n",
    "    df, timegpt_quantile_fcst_df, \n",
    "    time_col='timestamp', target_col='value',\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e46e6a70-e934-4957-a222-aeff463d019a",
   "metadata": {},
   "source": [
    "#### Cross Validation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfe31753-1895-494b-8ff0-e6d19e27e1f6",
   "metadata": {},
   "source": [
    "The `quantiles` argument can also be included in the `cross_validation` method, allowing comparing the performance of TimeGPT across different windows and different quantiles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f409493-8697-4262-9ed3-3b751f90b53c",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: MS\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: MS\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: MS\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: MS\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: MS\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\n",
      "INFO:nixtla.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtla.nixtla_client:Inferred freq: MS\n",
      "INFO:nixtla.nixtla_client:Restricting input...\n",
      "INFO:nixtla.nixtla_client:Calling Forecast Endpoint...\n",
      "INFO:nixtla.nixtla_client:Validating inputs...\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>timestamp</th>\n",
       "      <th>TimeGPT</th>\n",
       "      <th>TimeGPT-q-10</th>\n",
       "      <th>TimeGPT-q-20</th>\n",
       "      <th>TimeGPT-q-30</th>\n",
       "      <th>TimeGPT-q-40</th>\n",
       "      <th>TimeGPT-q-50</th>\n",
       "      <th>TimeGPT-q-60</th>\n",
       "      <th>TimeGPT-q-70</th>\n",
       "      <th>TimeGPT-q-80</th>\n",
       "      <th>TimeGPT-q-90</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1951-01-01</td>\n",
       "      <td>135.483673</td>\n",
       "      <td>111.937768</td>\n",
       "      <td>120.020593</td>\n",
       "      <td>125.848879</td>\n",
       "      <td>130.828935</td>\n",
       "      <td>135.483673</td>\n",
       "      <td>140.138411</td>\n",
       "      <td>145.118467</td>\n",
       "      <td>150.946753</td>\n",
       "      <td>159.029579</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1951-02-01</td>\n",
       "      <td>144.442398</td>\n",
       "      <td>120.896493</td>\n",
       "      <td>128.979318</td>\n",
       "      <td>134.807604</td>\n",
       "      <td>139.787660</td>\n",
       "      <td>144.442398</td>\n",
       "      <td>149.097136</td>\n",
       "      <td>154.077192</td>\n",
       "      <td>159.905478</td>\n",
       "      <td>167.988304</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1951-03-01</td>\n",
       "      <td>157.191910</td>\n",
       "      <td>133.646004</td>\n",
       "      <td>141.728830</td>\n",
       "      <td>147.557116</td>\n",
       "      <td>152.537172</td>\n",
       "      <td>157.191910</td>\n",
       "      <td>161.846648</td>\n",
       "      <td>166.826703</td>\n",
       "      <td>172.654990</td>\n",
       "      <td>180.737815</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1951-04-01</td>\n",
       "      <td>148.769363</td>\n",
       "      <td>125.223458</td>\n",
       "      <td>133.306284</td>\n",
       "      <td>139.134570</td>\n",
       "      <td>144.114625</td>\n",
       "      <td>148.769363</td>\n",
       "      <td>153.424102</td>\n",
       "      <td>158.404157</td>\n",
       "      <td>164.232443</td>\n",
       "      <td>172.315269</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1951-05-01</td>\n",
       "      <td>140.472946</td>\n",
       "      <td>116.927041</td>\n",
       "      <td>125.009866</td>\n",
       "      <td>130.838152</td>\n",
       "      <td>135.818208</td>\n",
       "      <td>140.472946</td>\n",
       "      <td>145.127684</td>\n",
       "      <td>150.107740</td>\n",
       "      <td>155.936026</td>\n",
       "      <td>164.018852</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    timestamp     TimeGPT  TimeGPT-q-10  TimeGPT-q-20  TimeGPT-q-30  \\\n",
       "0  1951-01-01  135.483673    111.937768    120.020593    125.848879   \n",
       "1  1951-02-01  144.442398    120.896493    128.979318    134.807604   \n",
       "2  1951-03-01  157.191910    133.646004    141.728830    147.557116   \n",
       "3  1951-04-01  148.769363    125.223458    133.306284    139.134570   \n",
       "4  1951-05-01  140.472946    116.927041    125.009866    130.838152   \n",
       "\n",
       "   TimeGPT-q-40  TimeGPT-q-50  TimeGPT-q-60  TimeGPT-q-70  TimeGPT-q-80  \\\n",
       "0    130.828935    135.483673    140.138411    145.118467    150.946753   \n",
       "1    139.787660    144.442398    149.097136    154.077192    159.905478   \n",
       "2    152.537172    157.191910    161.846648    166.826703    172.654990   \n",
       "3    144.114625    148.769363    153.424102    158.404157    164.232443   \n",
       "4    135.818208    140.472946    145.127684    150.107740    155.936026   \n",
       "\n",
       "   TimeGPT-q-90  \n",
       "0    159.029579  \n",
       "1    167.988304  \n",
       "2    180.737815  \n",
       "3    172.315269  \n",
       "4    164.018852  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "timegpt_cv_quantile_fcst_df = nixtla_client.cross_validation(\n",
    "    df=df, \n",
    "    h=12, \n",
    "    n_windows=5,\n",
    "    quantiles=quantiles, \n",
    "    time_col='timestamp', \n",
    "    target_col='value',\n",
    ")\n",
    "timegpt_quantile_fcst_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69ca8089-2b20-45b8-8c23-ffae6a457b86",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 118920 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 116928 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 118700 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 124224 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 123572 characters]",
      "text/plain": [
       "<Figure size 2400x350 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cutoffs = timegpt_cv_quantile_fcst_df['cutoff'].unique()\n",
    "for cutoff in cutoffs:\n",
    "    fig = nixtla_client.plot(\n",
    "        df.tail(100), \n",
    "        timegpt_cv_quantile_fcst_df.query('cutoff == @cutoff').drop(columns=['cutoff', 'value']),\n",
    "        time_col='timestamp', \n",
    "        target_col='value'\n",
    "    )\n",
    "    display(fig)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
