{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Overview \n", "\n", "In the 10x series of notebooks, we will look at Time Series modeling in pycaret using univariate data and no exogenous variables. We will use the famous airline dataset for illustration. Our plan of action is as follows:\n", "\n", "1. Perform EDA on the dataset to extract valuable insight about the process generating the time series. **(COMPLETED)**\n", "2. Model the dataset based on exploratory analysis (univariable model without exogenous variables). **(COMPLETED)**\n", "3. Use an automated approach (AutoML) to improve the performance. **(COMPLETED)**\n", "4. User customizations, potential pitfalls and how to overcome them. **(Covered in this notebook)**" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Only enable critical logging (Optional)\n", "import os\n", "os.environ[\"PYCARET_CUSTOM_LOGGING_LEVEL\"] = \"CRITICAL\"" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "System:\n", " python: 3.8.13 (default, Mar 28 2022, 06:59:08) [MSC v.1916 64 bit (AMD64)]\n", "executable: C:\\Users\\Nikhil\\.conda\\envs\\pycaret_dev_sktime_0p11_2\\python.exe\n", " machine: Windows-10-10.0.19044-SP0\n", "\n", "PyCaret required dependencies:\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\Nikhil\\.conda\\envs\\pycaret_dev_sktime_0p11_2\\lib\\site-packages\\_distutils_hack\\__init__.py:30: UserWarning: Setuptools is replacing distutils.\n", " warnings.warn(\"Setuptools is replacing distutils.\")\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " pip: 21.2.2\n", " setuptools: 61.2.0\n", " pycaret: 3.0.0\n", " ipython: Not installed\n", " ipywidgets: 7.7.0\n", " numpy: 1.21.6\n", " pandas: 1.4.2\n", " jinja2: 3.1.2\n", " scipy: 1.8.0\n", " joblib: 1.1.0\n", " sklearn: 1.0.2\n", " pyod: Installed but version unavailable\n", " imblearn: 0.9.0\n", " category_encoders: 2.4.1\n", " lightgbm: 3.3.2\n", " numba: 0.55.1\n", " requests: 2.27.1\n", " matplotlib: 3.5.2\n", " scikitplot: 0.3.7\n", " yellowbrick: 1.4\n", " plotly: 5.8.0\n", " kaleido: 0.2.1\n", " statsmodels: 0.13.2\n", " sktime: 0.11.4\n", " tbats: Installed but version unavailable\n", " pmdarima: 1.8.5\n", "\n", "PyCaret optional dependencies:\n", " shap: Not installed\n", " interpret: Not installed\n", " umap: Not installed\n", " pandas_profiling: Not installed\n", " explainerdashboard: Not installed\n", " autoviz: Not installed\n", " fairlearn: Not installed\n", " xgboost: Not installed\n", " catboost: Not installed\n", " kmodes: Not installed\n", " mlxtend: Not installed\n", " statsforecast: 0.5.5\n", " tune_sklearn: Not installed\n", " ray: Not installed\n", " hyperopt: Not installed\n", " optuna: Not installed\n", " skopt: Not installed\n", " mlflow: 1.25.1\n", " gradio: Not installed\n", " fastapi: Not installed\n", " uvicorn: Not installed\n", " m2cgen: Not installed\n", " evidently: Not installed\n", " nltk: Not installed\n", " pyLDAvis: Not installed\n", " gensim: Not installed\n", " spacy: Not installed\n", " wordcloud: Not installed\n", " textblob: Not installed\n", " psutil: 5.9.0\n", " fugue: Not installed\n", " streamlit: Not installed\n", " prophet: Not installed\n" ] } ], "source": [ "def what_is_installed():\n", " from pycaret import show_versions\n", " show_versions()\n", "\n", "try:\n", " what_is_installed()\n", "except ModuleNotFoundError:\n", " !pip install pycaret\n", " what_is_installed()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import time\n", "import numpy as np\n", "import pandas as pd\n", "\n", "from pycaret.datasets import get_data\n", "from pycaret.time_series import TSForecastingExperiment" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "y = get_data('airline', verbose=False)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# We want to forecast the next 12 months of data and we will use 3 fold cross-validation to test the models.\n", "fh = 12 # or alternately fh = np.arange(1,13)\n", "fold = 3" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# Global Plot Settings\n", "fig_kwargs={'renderer': 'notebook'}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# User Customizations\n", "\n", "Let's look at how users can customize various steps in the modeling process" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Prediction Customization\n", "\n", "### Forecast Horizon\n", "Sometimes users may wish to customize the forecast horizon after the model has been created. This can be done as follows." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs, session_id=42, verbose=False)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 cutoffMASERMSSEMAERMSEMAPESMAPER2
01956-120.44620.493313.028616.14850.03270.03340.9151
11957-120.59830.599318.292020.34420.05060.04910.8916
21958-121.00440.928028.699930.16690.06710.06970.7964
Meannan0.68300.673520.006922.21990.05010.05070.8677
SDnan0.23560.18516.51175.87460.01410.01480.0513
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model = exp.create_model(\"arima\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 ModelMASERMSSEMAERMSEMAPESMAPER2
0ARIMA0.49550.539515.086718.63800.03120.03120.9373
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y_pred
1960-01420.8767
1960-02397.1069
1960-03456.4335
1960-04442.6482
1960-05463.5822
1960-06513.0988
1960-07587.0872
1960-08596.4580
1960-09499.1383
1960-10442.0694
1960-11396.2036
1960-12438.5023
\n", "
" ], "text/plain": [ " y_pred\n", "1960-01 420.8767\n", "1960-02 397.1069\n", "1960-03 456.4335\n", "1960-04 442.6482\n", "1960-05 463.5822\n", "1960-06 513.0988\n", "1960-07 587.0872\n", "1960-08 596.4580\n", "1960-09 499.1383\n", "1960-10 442.0694\n", "1960-11 396.2036\n", "1960-12 438.5023" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Default prediction\n", "exp.predict_model(model)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y_pred
1960-01420.8767
1960-02397.1069
1960-03456.4335
1960-04442.6482
1960-05463.5822
1960-06513.0988
1960-07587.0872
1960-08596.4580
1960-09499.1383
1960-10442.0694
1960-11396.2036
1960-12438.5023
1961-01453.8109
1961-02429.5811
1961-03488.5351
1961-04474.4479
1961-05495.1374
1961-06544.4560
1961-07618.2840
1961-08627.5248
1961-09530.0999
1961-10472.9458
1961-11427.0110
1961-12469.2538
\n", "
" ], "text/plain": [ " y_pred\n", "1960-01 420.8767\n", "1960-02 397.1069\n", "1960-03 456.4335\n", "1960-04 442.6482\n", "1960-05 463.5822\n", "1960-06 513.0988\n", "1960-07 587.0872\n", "1960-08 596.4580\n", "1960-09 499.1383\n", "1960-10 442.0694\n", "1960-11 396.2036\n", "1960-12 438.5023\n", "1961-01 453.8109\n", "1961-02 429.5811\n", "1961-03 488.5351\n", "1961-04 474.4479\n", "1961-05 495.1374\n", "1961-06 544.4560\n", "1961-07 618.2840\n", "1961-08 627.5248\n", "1961-09 530.0999\n", "1961-10 472.9458\n", "1961-11 427.0110\n", "1961-12 469.2538" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Increased forecast horizon to 2 years instead of the original 1 year\n", "exp.predict_model(model, fh=24)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Prediction Interval\n", "\n", "#### NOTES: \n", "1. **When prediction intervals are requested, the default coverage = 0.9 corresponding to 90% coverage.** \n", "2. **Coverage is symmetrical around the median (alpha = 0.5). Hence a coverage of 0.9 corresponds to lower interval = 0.05 and an upper interval of 0.95 to give a total coverage between lower and upper interval = 0.9.**" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 ModelMASERMSSEMAERMSEMAPESMAPER2
0ARIMA0.49550.539515.086718.63800.03120.03120.9373
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y_predlowerupper
1960-01420.8767403.9466437.8067
1960-02397.1069375.3199418.8939
1960-03456.4335431.9786480.8884
1960-04442.6482416.5909468.7055
1960-05463.5822436.5252490.6392
1960-06513.0988485.4054540.7921
1960-07587.0872558.9843615.1902
1960-08596.4580568.0895624.8264
1960-09499.1383470.5969527.6796
1960-10442.0694413.4152470.7236
1960-11396.2036367.4756424.9315
1960-12438.5023409.7260467.2786
\n", "
" ], "text/plain": [ " y_pred lower upper\n", "1960-01 420.8767 403.9466 437.8067\n", "1960-02 397.1069 375.3199 418.8939\n", "1960-03 456.4335 431.9786 480.8884\n", "1960-04 442.6482 416.5909 468.7055\n", "1960-05 463.5822 436.5252 490.6392\n", "1960-06 513.0988 485.4054 540.7921\n", "1960-07 587.0872 558.9843 615.1902\n", "1960-08 596.4580 568.0895 624.8264\n", "1960-09 499.1383 470.5969 527.6796\n", "1960-10 442.0694 413.4152 470.7236\n", "1960-11 396.2036 367.4756 424.9315\n", "1960-12 438.5023 409.7260 467.2786" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# With Prediction Interval (default coverage = 0.9)\n", "exp.predict_model(model, return_pred_int=True)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 ModelMASERMSSEMAERMSEMAPESMAPER2
0ARIMA0.49550.539515.086718.63800.03120.03120.9373
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y_predlowerupper
1960-01420.8767407.6860434.0673
1960-02397.1069380.1320414.0818
1960-03456.4335437.3800475.4870
1960-04442.6482422.3463462.9502
1960-05463.5822442.5013484.6631
1960-06513.0988491.5221534.6754
1960-07587.0872565.1915608.9830
1960-08596.4580574.3553618.5606
1960-09499.1383476.9009521.3756
1960-10442.0694419.7441464.3946
1960-11396.2036373.8208418.5863
1960-12438.5023416.0819460.9227
\n", "
" ], "text/plain": [ " y_pred lower upper\n", "1960-01 420.8767 407.6860 434.0673\n", "1960-02 397.1069 380.1320 414.0818\n", "1960-03 456.4335 437.3800 475.4870\n", "1960-04 442.6482 422.3463 462.9502\n", "1960-05 463.5822 442.5013 484.6631\n", "1960-06 513.0988 491.5221 534.6754\n", "1960-07 587.0872 565.1915 608.9830\n", "1960-08 596.4580 574.3553 618.5606\n", "1960-09 499.1383 476.9009 521.3756\n", "1960-10 442.0694 419.7441 464.3946\n", "1960-11 396.2036 373.8208 418.5863\n", "1960-12 438.5023 416.0819 460.9227" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# With Prediction Interval (custom coverage = 0.8, corresponding to lower and upper quantiles of 0.1 and 0.9 respectively)\n", "# The point estimate remains the same as before.\n", "# But the lower and upper intervals are now narrower since we are OK with a lower coverage.\n", "exp.predict_model(model, return_pred_int=True, coverage=0.8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Sometimes, users may wish to get the point estimates at values other than the mean/median. In such cases, they can specify the alpha (quantile) value for the point estimate directly.**\n", "\n", "**NOTE: Not all models support this feature. If this is used with models that do not support it, an error is raised. If you want to only use models that support this feature, you must set `point_alpha` to a floating point value in the `setup` stage (see below).**" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 ModelMASERMSSEMAERMSEMAPESMAPER2
0ARIMA0.43350.516813.200417.85490.02920.02870.9425
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y_pred
1960-01426.2742
1960-02404.0529
1960-03464.2301
1960-04450.9556
1960-05472.2083
1960-06521.9277
1960-07596.0468
1960-08605.5022
1960-09508.2376
1960-10451.2047
1960-11405.3624
1960-12447.6766
\n", "
" ], "text/plain": [ " y_pred\n", "1960-01 426.2742\n", "1960-02 404.0529\n", "1960-03 464.2301\n", "1960-04 450.9556\n", "1960-05 472.2083\n", "1960-06 521.9277\n", "1960-07 596.0468\n", "1960-08 605.5022\n", "1960-09 508.2376\n", "1960-10 451.2047\n", "1960-11 405.3624\n", "1960-12 447.6766" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# With Custom Point Estimate (alpha = 0.7)\n", "# The point estimate is now higher than before since we are asking for the\n", "# 70% percentile as the point estimate), vs. mean/median before.\n", "exp.predict_model(model, alpha=0.7)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 cutoffMASERMSSEMAERMSEMAPESMAPER2
01956-120.71370.844020.841227.62620.05130.05330.7516
11957-120.66780.703820.417223.89180.05570.05390.8505
21958-120.71980.763020.566924.80240.04570.04710.8624
Meannan0.70040.770220.608425.44010.05090.05140.8215
SDnan0.02320.05750.17561.58980.00410.00310.0497
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 ModelMASERMSSEMAERMSEMAPESMAPER2
0LinearRegression0.79930.927524.337632.04180.04750.04930.8147
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y_predlowerupper
1960-01399.5740NaNNaN
1960-02384.6911NaNNaN
1960-03420.8922NaNNaN
1960-04412.8696NaNNaN
1960-05438.3520NaNNaN
1960-06494.9357NaNNaN
1960-07556.8907NaNNaN
1960-08558.1492NaNNaN
1960-09503.6881NaNNaN
1960-10449.0433NaNNaN
1960-11405.1229NaNNaN
1960-12431.7701NaNNaN
\n", "
" ], "text/plain": [ " y_pred lower upper\n", "1960-01 399.5740 NaN NaN\n", "1960-02 384.6911 NaN NaN\n", "1960-03 420.8922 NaN NaN\n", "1960-04 412.8696 NaN NaN\n", "1960-05 438.3520 NaN NaN\n", "1960-06 494.9357 NaN NaN\n", "1960-07 556.8907 NaN NaN\n", "1960-08 558.1492 NaN NaN\n", "1960-09 503.6881 NaN NaN\n", "1960-10 449.0433 NaN NaN\n", "1960-11 405.1229 NaN NaN\n", "1960-12 431.7701 NaN NaN" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# For models that do not produce a prediction interval --> returns NA values\n", "model_no_pred_int = exp.create_model(\"lr_cds_dt\")\n", "exp.predict_model(model_no_pred_int, return_pred_int=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Forecast Plotting Customization\n", "\n", "Similar to the prediction customization, we can customize the forecast plots as well." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Regular Plot\n", "exp.plot_model(model)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Modified Plot (zoom into the plot to see differences between the 2 plots)\n", "exp.plot_model(model, data_kwargs={\"alpha\": 0.7, \"coverage\": 0.8})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Enforce Prediction Intervals\n", "\n", "In some use cases, it is important to have prediction intervals. Users may wish to restrict the modeling to only those models that support prediction intervals.\n", "\n", "* Specifying `point_alpha` to any floating point value restricts the models to only those that provide a prediction interval. The value that is specified corresponds to the quantile of the point prediction that is returned.\n", "* This also adds an extra metric called `COVERAGE`.\n", "* `COVERAGE` gives the percentage of actuals that are within the prediction interval." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 DescriptionValue
0session_id3833
1TargetNumber of airline passengers
2ApproachUnivariate
3Exogenous VariablesNot Present
4Original data shape(144, 1)
5Transformed data shape(144, 1)
6Transformed train set shape(132, 1)
7Transformed test set shape(12, 1)
8Rows with missing values0.0%
9Fold GeneratorExpandingWindowSplitter
10Fold Number3
11Enforce Prediction IntervalTrue
12Seasonal Period(s) Tested12
13Seasonality PresentTrue
14Seasonalities Detected[12]
15Primary Seasonality12
16Target Strictly PositiveTrue
17Target White NoiseNo
18Recommended d1
19Recommended Seasonal D1
20PreprocessFalse
21CPU Jobs-1
22Use GPUFalse
23Log ExperimentFalse
24Experiment Namets-default-name
25USI17db
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameReferenceTurbo
ID
arimaARIMAsktime.forecasting.arima.ARIMATrue
auto_arimaAuto ARIMAsktime.forecasting.arima.AutoARIMATrue
etsETSsktime.forecasting.ets.AutoETSTrue
thetaTheta Forecastersktime.forecasting.theta.ThetaForecasterTrue
tbatsTBATSsktime.forecasting.tbats.TBATSFalse
batsBATSsktime.forecasting.bats.BATSFalse
\n", "
" ], "text/plain": [ " Name Reference Turbo\n", "ID \n", "arima ARIMA sktime.forecasting.arima.ARIMA True\n", "auto_arima Auto ARIMA sktime.forecasting.arima.AutoARIMA True\n", "ets ETS sktime.forecasting.ets.AutoETS True\n", "theta Theta Forecaster sktime.forecasting.theta.ThetaForecaster True\n", "tbats TBATS sktime.forecasting.tbats.TBATS False\n", "bats BATS sktime.forecasting.bats.BATS False" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exp = TSForecastingExperiment()\n", "\n", "# We can see that specifying a value for point_alpha enables `Enforce Prediction Interval` in the grid (and limits the models).\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs, point_alpha=0.5)\n", "exp.models()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 ModelMASERMSSEMAERMSEMAPESMAPER2COVERAGETT (Sec)
etsETS0.59320.620117.421420.47420.04400.04450.88840.66670.1933
arimaARIMA0.68300.673520.006922.21990.05010.05070.86770.63891.5467
auto_arimaAuto ARIMA0.71810.711421.029723.46610.05250.05310.85090.69442.7633
thetaTheta Forecaster0.97291.030628.319233.86390.06700.07000.67100.63890.0500
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "best_model = exp.compare_models()\n", "\n", "# # To enable slower models such as prophet, BATS and TBATS, add turbo=False\n", "# best_model = exp.compare_models(turbo=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Types of Window Splitters\n", "\n", "Various window splitters are available for performing the cross validation.\n", "\n", "### Sliding Window Splitter" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs, fold_strategy='sliding', verbose=False)\n", "exp.plot_model(plot=\"cv\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expanding/Rolling Window\n", "\n", "* They are identical" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs, fold_strategy='expanding', verbose=False)\n", "exp.plot_model(plot=\"cv\")" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs, fold_strategy='rolling', verbose=False)\n", "exp.plot_model(plot=\"cv\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Error Handling due to lack of data\n", "\n", "Sometimes, there are not enough data points available to perform the experiment. In such cases, pycaret will warn you accordingly." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Not Enough Data Points, set a lower number of folds or fh\n" ] } ], "source": [ "try:\n", " exp = TSForecastingExperiment()\n", " exp.setup(data=y[:30], fh=12, fold=3, fig_kwargs=fig_kwargs)\n", "except ValueError as error:\n", " print(error)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 DescriptionValue
0session_id5965
1TargetNumber of airline passengers
2ApproachUnivariate
3Exogenous VariablesNot Present
4Original data shape(30, 1)
5Transformed data shape(30, 1)
6Transformed train set shape(24, 1)
7Transformed test set shape(6, 1)
8Rows with missing values0.0%
9Fold GeneratorExpandingWindowSplitter
10Fold Number3
11Enforce Prediction IntervalFalse
12Seasonal Period(s) Tested12
13Seasonality PresentFalse
14Seasonalities Detected[1]
15Primary Seasonality1
16Target Strictly PositiveTrue
17Target White NoiseNo
18Recommended d1
19Recommended Seasonal D0
20PreprocessFalse
21CPU Jobs-1
22Use GPUFalse
23Log ExperimentFalse
24Experiment Namets-default-name
25USI2a8f
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "try:\n", " exp = TSForecastingExperiment()\n", " exp.setup(data=y[:30], fh=6, fold=3, fig_kwargs=fig_kwargs)\n", "except ValueError as error:\n", " print(error)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tuning Customization" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 DescriptionValue
0session_id42
1TargetNumber of airline passengers
2ApproachUnivariate
3Exogenous VariablesNot Present
4Original data shape(144, 1)
5Transformed data shape(144, 1)
6Transformed train set shape(132, 1)
7Transformed test set shape(12, 1)
8Rows with missing values0.0%
9Fold GeneratorExpandingWindowSplitter
10Fold Number3
11Enforce Prediction IntervalFalse
12Seasonal Period(s) Tested12
13Seasonality PresentTrue
14Seasonalities Detected[12]
15Primary Seasonality12
16Target Strictly PositiveTrue
17Target White NoiseNo
18Recommended d1
19Recommended Seasonal D1
20PreprocessFalse
21CPU Jobs-1
22Use GPUFalse
23Log ExperimentFalse
24Experiment Namets-default-name
25USIf401
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs, session_id=42)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 cutoffMASERMSSEMAERMSEMAPESMAPER2
01956-120.71370.844020.841227.62620.05130.05330.7516
11957-120.66780.703820.417223.89180.05570.05390.8505
21958-120.71980.763020.566924.80240.04570.04710.8624
Meannan0.70040.770220.608425.44010.05090.05140.8215
SDnan0.02320.05750.17561.58980.00410.00310.0497
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model = exp.create_model(\"lr_cds_dt\")" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 cutoffMASERMSSEMAERMSEMAPESMAPER2
01956-120.31570.36999.218412.10770.02330.02350.9523
11957-121.00090.983530.601133.38980.08340.07940.7079
21958-120.47870.488213.678615.86820.03200.03250.9437
Meannan0.59840.613917.832720.45520.04620.04520.8680
SDnan0.29230.26589.21049.27410.02650.02450.1132
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "BaseCdsDtForecaster(regressor=LinearRegression(n_jobs=-1), sp=12,\n", " window_length=12)\n", "BaseCdsDtForecaster(degree=2, deseasonal_model='multiplicative',\n", " regressor=LinearRegression(fit_intercept=False, n_jobs=-1,\n", " normalize=True),\n", " sp=12, window_length=23)\n" ] } ], "source": [ "# Random Grid Search (default)\n", "tuned_model = exp.tune_model(model)\n", "print(model)\n", "print(tuned_model)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "exp.plot_model([model, tuned_model], data_kwargs={\"labels\": [\"Original\", \"Tuned\"]})" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 cutoffMASERMSSEMAERMSEMAPESMAPER2
01956-120.82521.002024.097532.79980.05870.06160.6498
11957-120.71150.748721.753025.41770.05830.05710.8307
21958-120.72030.829620.581826.96840.04450.04590.8373
Meannan0.75230.860122.144128.39530.05390.05490.7726
SDnan0.05160.10561.46173.17810.00660.00660.0869
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "BaseCdsDtForecaster(regressor=LinearRegression(n_jobs=-1), sp=12,\n", " window_length=12)\n", "BaseCdsDtForecaster(regressor=LinearRegression(n_jobs=-1), sp=12,\n", " window_length=12)\n" ] } ], "source": [ "# Fixed Grid Search\n", "tuned_model = exp.tune_model(model, search_algorithm=\"grid\")\n", "print(model)\n", "print(tuned_model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Observations:**\n", "* In this case, the tuning resulted in worse metrics than the original model (this is possible).\n", "* Hence, pycaret returned the original model as the best one since `choose_better=True` by default.\n", "* If the user does not want this behavior, they can set `choose_better=False`" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 cutoffMASERMSSEMAERMSEMAPESMAPER2
01956-120.82521.002024.097532.79980.05870.06160.6498
11957-120.71150.748721.753025.41770.05830.05710.8307
21958-120.72030.829620.581826.96840.04450.04590.8373
Meannan0.75230.860122.144128.39530.05390.05490.7726
SDnan0.05160.10561.46173.17810.00660.00660.0869
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "BaseCdsDtForecaster(regressor=LinearRegression(n_jobs=-1), sp=12,\n", " window_length=12)\n", "BaseCdsDtForecaster(regressor=LinearRegression(fit_intercept=False, n_jobs=-1,\n", " normalize=True),\n", " sp=12)\n" ] } ], "source": [ "tuned_model = exp.tune_model(model, search_algorithm=\"grid\", choose_better=False)\n", "print(model)\n", "print(tuned_model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes, there are time constraints on the tuning so users may wish to adjust the number of hyperparameters that are tried using the `n_iter` argument." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 cutoffMASERMSSEMAERMSEMAPESMAPER2
01956-120.31570.36999.218412.10770.02330.02350.9523
11957-121.00090.983530.601133.38980.08340.07940.7079
21958-120.47870.488213.678615.86820.03200.03250.9437
Meannan0.59840.613917.832720.45520.04620.04520.8680
SDnan0.29230.26589.21049.27410.02650.02450.1132
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "BaseCdsDtForecaster(regressor=LinearRegression(n_jobs=-1), sp=12,\n", " window_length=12)\n", "BaseCdsDtForecaster(degree=2, deseasonal_model='multiplicative',\n", " regressor=LinearRegression(fit_intercept=False, n_jobs=-1,\n", " normalize=True),\n", " sp=12, window_length=23)\n" ] } ], "source": [ "tuned_model = exp.tune_model(model, n_iter=5)\n", "print(model)\n", "print(tuned_model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "More information about tunuing in pycaret time series can be found here:\n", " \n", "1. **[Basic Tuning](https://github.com/pycaret/pycaret/discussions/1791)**\n", "2. **[Advanced Tuning](https://github.com/pycaret/pycaret/discussions/1795)**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting Renderer\n", "\n", "Sometimes the plotly renderer if not detected correctly for the environment. In such cases, the users can manually specify the render in pycaret" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Renderer 'plotly_mimetype+notebook' is not a valid Plotly renderer. Valid renderers are:\n", " Renderers configuration\n", "-----------------------\n", " Default renderer: 'plotly_mimetype+notebook'\n", " Available renderers:\n", " ['plotly_mimetype', 'jupyterlab', 'nteract', 'vscode',\n", " 'notebook', 'notebook_connected', 'kaggle', 'azure', 'colab',\n", " 'cocalc', 'databricks', 'json', 'png', 'jpeg', 'jpg', 'svg',\n", " 'pdf', 'browser', 'firefox', 'chrome', 'chromium', 'iframe',\n", " 'iframe_connected', 'sphinx_gallery', 'sphinx_gallery_png']\n", "\n", "When data exceeds a certain threshold (determined by `big_data_threshold`), the renderer is switched to a static one to prevent notebooks from being slowed down.\n", "This renderer may need to be installed manually by users.\n", "Alternately:\n", "Option 1: Users can increase `big_data_threshold` in either `setup` (globally) or `plot_model` (plot specific). Examples.\n", "\t>>> setup(..., fig_kwargs={'big_data_threshold': 1000})\n", "\t>>> plot_model(..., fig_kwargs={'big_data_threshold': 1000})\n", "Option 2: Users can specify any plotly renderer directly in either `setup` (globally) or `plot_model` (plot specific). Examples.\n", "\t>>> setup(..., fig_kwargs={'renderer': 'notebook'})\n", "\t>>> plot_model(..., fig_kwargs={'renderer': 'colab'})\n", "Refer to the docstring in `setup` for more details.\n" ] } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, verbose=False)\n", "exp.plot_model(plot=\"cv\")" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs={'renderer': 'notebook'}, verbose=False)\n", "exp.plot_model(plot=\"cv\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Users can also specify the renderer for specific plot types" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "image/png": "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CCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdAQKvu7Wj5wgggAACCCCAAAIRBAi8EZA4BQEEEEAAAQQQQMBdgf8Hx9Ail9YI/yUAAAAASUVORK5CYII=" }, "metadata": {}, "output_type": "display_data" } ], "source": [ "exp.plot_model(fig_kwargs={'renderer': 'png'})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Seasonal Period\n", "\n", "* Setting the seasonal period for time series models is one of the most important aspects that can dictate how accurate the model are.\n", "* By default, pycaret will try to derive the seasonal period from the index. \n", "* When this can not be done, seasonal period needs to be provided manually by the user.\n", "* Even when the seasonal period can be derived from the index, users can always override this manually by specyig the seasonal period." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 DescriptionValue
0session_id641
1TargetNumber of airline passengers
2ApproachUnivariate
3Exogenous VariablesNot Present
4Original data shape(144, 1)
5Transformed data shape(144, 1)
6Transformed train set shape(132, 1)
7Transformed test set shape(12, 1)
8Rows with missing values0.0%
9Fold GeneratorExpandingWindowSplitter
10Fold Number3
11Enforce Prediction IntervalFalse
12Seasonal Period(s) Tested12
13Seasonality PresentTrue
14Seasonalities Detected[12]
15Primary Seasonality12
16Target Strictly PositiveTrue
17Target White NoiseNo
18Recommended d1
19Recommended Seasonal D1
20PreprocessFalse
21CPU Jobs-1
22Use GPUFalse
23Log ExperimentFalse
24Experiment Namets-default-name
25USI325d
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Observations:**\n", "\n", "* The default Seasinal Period derived from index = 12\n", "\n", "Users can change this based on EDA. e.g. lets change it to 36" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 DescriptionValue
0session_id955
1TargetNumber of airline passengers
2ApproachUnivariate
3Exogenous VariablesNot Present
4Original data shape(144, 1)
5Transformed data shape(144, 1)
6Transformed train set shape(132, 1)
7Transformed test set shape(12, 1)
8Rows with missing values0.0%
9Fold GeneratorExpandingWindowSplitter
10Fold Number3
11Enforce Prediction IntervalFalse
12Seasonal Period(s) Tested36
13Seasonality PresentFalse
14Seasonalities Detected[1]
15Primary Seasonality1
16Target Strictly PositiveTrue
17Target White NoiseNo
18Recommended d1
19Recommended Seasonal D0
20PreprocessFalse
21CPU Jobs-1
22Use GPUFalse
23Log ExperimentFalse
24Experiment Namets-default-name
25USI546a
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exp = TSForecastingExperiment()\n", "exp.setup(data=y, fh=fh, fold=fold, seasonal_period=36, fig_kwargs=fig_kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Observations:**\n", " \n", "* In this case, the user specified a seasonal period of 36, but a seasonality test at this period did not detect seasonality.\n", "* Hence a seasonality of 1 will be used for modeling." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
x
0173.786244
1174.850941
2175.435101
3174.807199
4174.872474
\n", "
" ], "text/plain": [ " x\n", "0 173.786244\n", "1 174.850941\n", "2 175.435101\n", "3 174.807199\n", "4 174.872474" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "y = get_data(\"1\", folder=\"time_series/ar1\")" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The index of your 'data' is of type ''. If the 'data' index is not of one of the following types: , , then 'seasonal_period' must be provided. Refer to docstring for options.\n" ] } ], "source": [ "try:\n", " exp = TSForecastingExperiment()\n", " exp.setup(data=y, fh=fh, fold=fold, fig_kwargs=fig_kwargs)\n", "except ValueError as error:\n", " print(error)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Observations:**\n", "* The frequency/seasonal period could not be derived from the index. Hence the user needs to specify this manually.\n", "* The user can specify an arbitrary seasonal period at first (as below), perform EDA to deterine the appropriate seasonal period for modeling.\n" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 DescriptionValue
0session_id5965
1Targetx
2ApproachUnivariate
3Exogenous VariablesNot Present
4Original data shape(340, 1)
5Transformed data shape(340, 1)
6Transformed train set shape(328, 1)
7Transformed test set shape(12, 1)
8Rows with missing values0.0%
9Fold GeneratorExpandingWindowSplitter
10Fold Number3
11Enforce Prediction IntervalFalse
12Seasonal Period(s) Tested3
13Seasonality PresentTrue
14Seasonalities Detected[3]
15Primary Seasonality3
16Target Strictly PositiveTrue
17Target White NoiseNo
18Recommended d1
19Recommended Seasonal D0
20PreprocessFalse
21CPU Jobs-1
22Use GPUFalse
23Log ExperimentFalse
24Experiment Namets-default-name
25USI41bc
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eda = TSForecastingExperiment()\n", "eda.setup(data=y, fh=fh, fold=fold, seasonal_period=3, fig_kwargs=fig_kwargs)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "eda.plot_model(plot=\"diagnostics\", fig_kwargs={\"height\": 600, \"width\": 1000})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Observations:**\n", "* We see wandering behavior in the dataset but no real seasonal pattern.\n", "* We should reser the seasonal period to 1 for the modeling." ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 DescriptionValue
0session_id5108
1Targetx
2ApproachUnivariate
3Exogenous VariablesNot Present
4Original data shape(340, 1)
5Transformed data shape(340, 1)
6Transformed train set shape(328, 1)
7Transformed test set shape(12, 1)
8Rows with missing values0.0%
9Fold GeneratorExpandingWindowSplitter
10Fold Number3
11Enforce Prediction IntervalFalse
12Seasonal Period(s) Tested1
13Seasonality PresentFalse
14Seasonalities Detected[1]
15Primary Seasonality1
16Target Strictly PositiveTrue
17Target White NoiseNo
18Recommended d1
19Recommended Seasonal D0
20PreprocessFalse
21CPU Jobs-1
22Use GPUFalse
23Log ExperimentFalse
24Experiment Namets-default-name
25USIcf16
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eda = TSForecastingExperiment()\n", "eda.setup(data=y, fh=fh, fold=fold, seasonal_period=1, fig_kwargs=fig_kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**That's it for this notebook. If you would like to see other demonstrations, feel free to open an issue on [GitHub](https://github.com/pycaret/pycaret/issues).** " ] } ], "metadata": { "interpreter": { "hash": "83be8a105015beb0be3130957f981d91e0431cfb610106a7fbaabcd7fd8062ab" }, "kernelspec": { "display_name": "pycaret_sktime_0p11_2", "language": "python", "name": "pycaret_sktime_0p11_2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.13" } }, "nbformat": 4, "nbformat_minor": 2 }