{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ea57e70",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "!pip install -Uqq nixtla"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a5dad94",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide \n",
    "from nixtla.utils import in_colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c16af54",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide \n",
    "IN_COLAB = in_colab()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "49489d94",
   "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": "41bd465f-638b-4fc0-9a4b-1a93207a8ca5",
   "metadata": {},
   "source": [
    "# Multiple series forecasting"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "752a293c-d477-45e7-93d9-23fc15a23c8f",
   "metadata": {},
   "source": [
    "TimeGPT provides a robust solution for multi-series forecasting, which involves analyzing multiple data series concurrently, rather than a single one. The tool can be fine-tuned using a broad collection of series, enabling you to tailor the model to suit your specific needs or tasks.\n",
    "\n",
    "Note that the forecasts are still univariate. This means that although TimeGPT is a global model, it won't consider the inter-feature relationships within the target series. However, TimeGPT does support the use of exogenous variables such as categorical variables (e.g., category, brand), numerical variables (e.g., temperature, prices), or even special holidays.\n",
    "\n",
    "Let's see this in action."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "efa9185e-77b0-4e30-a4da-dc3f6a05da90",
   "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/05_multiple_series.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/05_multiple_series')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8fb870f5",
   "metadata": {},
   "source": [
    "## 1. Import packages\n",
    "First, we install and import the required packages and initialize the Nixtla client."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61e6a645",
   "metadata": {},
   "source": [
    "As always, we start off by intializing an instance of `NixtlaClient`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab7c94f5-3a29-4ae2-a8cb-7826dea92f3a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from nixtla import NixtlaClient"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4e8e00b3-df4d-49df-815c-58ebe3543974",
   "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": "1b9f9d3f",
   "metadata": {},
   "source": [
    "> 👍 Use an Azure AI endpoint\n",
    "> \n",
    "> To use an Azure AI endpoint, remember to set also 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": "7b21c50f-fa94-49ba-b9c4-358d980dd462",
   "metadata": {},
   "outputs": [],
   "source": [
    "#| hide\n",
    "if not IN_COLAB:\n",
    "    nixtla_client = NixtlaClient()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c1519c9",
   "metadata": {},
   "source": [
    "## 2. Load the data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2bd0934b-8b12-4c33-be3c-6b8d2bf86f54",
   "metadata": {},
   "source": [
    "The following dataset contains prices of different electricity markets in Europe. \n",
    "\n",
    "Mutliple series are automatically detected in TimeGPT using the `unique_id` column. This column contains labels for each series. If there are multiple unique values in that column, then it knows it is handling a multi-series scneario.\n",
    "\n",
    "In this particular case, the `unique_id` column contains the value BE, DE, FR, JPM, and NP."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c9dea998-2507-4409-b063-2b06f38c0aba",
   "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>BE</td>\n",
       "      <td>2016-12-01 00:00:00</td>\n",
       "      <td>72.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-01 01:00:00</td>\n",
       "      <td>65.80</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-01 02:00:00</td>\n",
       "      <td>59.99</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-01 03:00:00</td>\n",
       "      <td>50.69</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-01 04:00:00</td>\n",
       "      <td>52.58</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  unique_id                   ds      y\n",
       "0        BE  2016-12-01 00:00:00  72.00\n",
       "1        BE  2016-12-01 01:00:00  65.80\n",
       "2        BE  2016-12-01 02:00:00  59.99\n",
       "3        BE  2016-12-01 03:00:00  50.69\n",
       "4        BE  2016-12-01 04:00:00  52.58"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/electricity-short.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a96a6b8-827a-40ba-b9dd-78281d82a2fc",
   "metadata": {},
   "source": [
    "Let's plot this series using [`NixtlaClient`](https://nixtlaverse.nixtla.io/nixtla/nixtla_client.html#nixtlaclient):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0462374-2d4c-4975-bb23-21b5bfc94d9a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 335212 characters]",
      "text/plain": [
       "<Figure size 2400x1050 with 6 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51d11ba4",
   "metadata": {},
   "source": [
    "## 3. Forecasting Multiple Series"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1dbe558a-ac0f-475b-abd6-838121863307",
   "metadata": {},
   "source": [
    "To forecast all series at once, we simply pass the dataframe to the `df` argument. TimeGPt will automatically forecast all series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "09211e3a-15e5-4b37-8da2-36d515186771",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:nixtlats.nixtla_client:Validating inputs...\n",
      "INFO:nixtlats.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtlats.nixtla_client:Inferred freq: H\n",
      "INFO:nixtlats.nixtla_client:Restricting input...\n",
      "INFO:nixtlats.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>unique_id</th>\n",
       "      <th>ds</th>\n",
       "      <th>TimeGPT</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",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-31 00:00:00</td>\n",
       "      <td>46.151176</td>\n",
       "      <td>36.660478</td>\n",
       "      <td>38.337019</td>\n",
       "      <td>53.965334</td>\n",
       "      <td>55.641875</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-31 01:00:00</td>\n",
       "      <td>42.426598</td>\n",
       "      <td>31.602231</td>\n",
       "      <td>33.976724</td>\n",
       "      <td>50.876471</td>\n",
       "      <td>53.250964</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-31 02:00:00</td>\n",
       "      <td>40.242889</td>\n",
       "      <td>30.439970</td>\n",
       "      <td>33.634985</td>\n",
       "      <td>46.850794</td>\n",
       "      <td>50.045809</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-31 03:00:00</td>\n",
       "      <td>38.265339</td>\n",
       "      <td>26.841481</td>\n",
       "      <td>31.022093</td>\n",
       "      <td>45.508585</td>\n",
       "      <td>49.689197</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-31 04:00:00</td>\n",
       "      <td>36.618801</td>\n",
       "      <td>18.541384</td>\n",
       "      <td>27.981346</td>\n",
       "      <td>45.256256</td>\n",
       "      <td>54.696218</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  unique_id                   ds    TimeGPT  TimeGPT-lo-90  TimeGPT-lo-80  \\\n",
       "0        BE  2016-12-31 00:00:00  46.151176      36.660478      38.337019   \n",
       "1        BE  2016-12-31 01:00:00  42.426598      31.602231      33.976724   \n",
       "2        BE  2016-12-31 02:00:00  40.242889      30.439970      33.634985   \n",
       "3        BE  2016-12-31 03:00:00  38.265339      26.841481      31.022093   \n",
       "4        BE  2016-12-31 04:00:00  36.618801      18.541384      27.981346   \n",
       "\n",
       "   TimeGPT-hi-80  TimeGPT-hi-90  \n",
       "0      53.965334      55.641875  \n",
       "1      50.876471      53.250964  \n",
       "2      46.850794      50.045809  \n",
       "3      45.508585      49.689197  \n",
       "4      45.256256      54.696218  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "timegpt_fcst_multiseries_df = nixtla_client.forecast(df=df, h=24, level=[80, 90])\n",
    "timegpt_fcst_multiseries_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3bdd241",
   "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": "code",
   "execution_count": null,
   "id": "1f7773f0-a5e3-4314-891e-3acc9b558acb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 353896 characters]",
      "text/plain": [
       "<Figure size 2400x1050 with 6 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(df, timegpt_fcst_multiseries_df, max_insample_length=365, level=[80, 90])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd689e11",
   "metadata": {},
   "source": [
    "From the figure above, we can see that the model effectively generated predictions for each unique series in the dataset."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32b60af1-fa48-4de8-bcee-73aff1e4e709",
   "metadata": {},
   "source": [
    "## Historical forecast"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a790ca0-b995-4c1a-a0e4-4e5c8b8df9eb",
   "metadata": {},
   "source": [
    "You can also compute prediction intervals for historical forecasts adding the `add_history=True`.\n",
    "\n",
    "To specify the confidence interval, we use the `level` argument. Here, we pass the list `[80, 90]`. This will compute a 80% and 90% confidence interval."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0efc9a95-06ef-474f-b164-a82af9301d1a",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:nixtlats.nixtla_client:Validating inputs...\n",
      "INFO:nixtlats.nixtla_client:Preprocessing dataframes...\n",
      "INFO:nixtlats.nixtla_client:Inferred freq: H\n",
      "INFO:nixtlats.nixtla_client:Calling Forecast Endpoint...\n",
      "INFO:nixtlats.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>unique_id</th>\n",
       "      <th>ds</th>\n",
       "      <th>TimeGPT</th>\n",
       "      <th>TimeGPT-lo-80</th>\n",
       "      <th>TimeGPT-lo-90</th>\n",
       "      <th>TimeGPT-hi-80</th>\n",
       "      <th>TimeGPT-hi-90</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-06 00:00:00</td>\n",
       "      <td>55.756332</td>\n",
       "      <td>42.066476</td>\n",
       "      <td>38.185593</td>\n",
       "      <td>69.446188</td>\n",
       "      <td>73.327072</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-06 01:00:00</td>\n",
       "      <td>52.820206</td>\n",
       "      <td>39.130350</td>\n",
       "      <td>35.249466</td>\n",
       "      <td>66.510062</td>\n",
       "      <td>70.390946</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-06 02:00:00</td>\n",
       "      <td>46.851070</td>\n",
       "      <td>33.161214</td>\n",
       "      <td>29.280331</td>\n",
       "      <td>60.540926</td>\n",
       "      <td>64.421810</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-06 03:00:00</td>\n",
       "      <td>50.640892</td>\n",
       "      <td>36.951036</td>\n",
       "      <td>33.070152</td>\n",
       "      <td>64.330748</td>\n",
       "      <td>68.211632</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>BE</td>\n",
       "      <td>2016-12-06 04:00:00</td>\n",
       "      <td>52.420410</td>\n",
       "      <td>38.730554</td>\n",
       "      <td>34.849670</td>\n",
       "      <td>66.110266</td>\n",
       "      <td>69.991150</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  unique_id                   ds    TimeGPT  TimeGPT-lo-80  TimeGPT-lo-90  \\\n",
       "0        BE  2016-12-06 00:00:00  55.756332      42.066476      38.185593   \n",
       "1        BE  2016-12-06 01:00:00  52.820206      39.130350      35.249466   \n",
       "2        BE  2016-12-06 02:00:00  46.851070      33.161214      29.280331   \n",
       "3        BE  2016-12-06 03:00:00  50.640892      36.951036      33.070152   \n",
       "4        BE  2016-12-06 04:00:00  52.420410      38.730554      34.849670   \n",
       "\n",
       "   TimeGPT-hi-80  TimeGPT-hi-90  \n",
       "0      69.446188      73.327072  \n",
       "1      66.510062      70.390946  \n",
       "2      60.540926      64.421810  \n",
       "3      64.330748      68.211632  \n",
       "4      66.110266      69.991150  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "timegpt_fcst_multiseries_with_history_df = nixtla_client.forecast(df=df, h=24, level=[80, 90], add_history=True)\n",
    "timegpt_fcst_multiseries_with_history_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d753b2e0",
   "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": "code",
   "execution_count": null,
   "id": "dbc3ad3a-378d-4f22-9cdd-f53ee62d0e8f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 718024 characters]",
      "text/plain": [
       "<Figure size 2400x1050 with 6 Axes>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nixtla_client.plot(\n",
    "    df, \n",
    "    timegpt_fcst_multiseries_with_history_df.groupby('unique_id').tail(365 + 24), \n",
    "    max_insample_length=365, \n",
    "    level=[80, 90],\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a48df7da",
   "metadata": {},
   "source": [
    "In the figure above, we now see the historical predictions made by TimeGPT for each series, along with the 80% and 90% confidence intervals."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c2adb0d1",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
