diff --git a/configuration.ipynb b/configuration.ipynb index 6c9ba9c9..c7123bf2 100644 --- a/configuration.ipynb +++ b/configuration.ipynb @@ -103,7 +103,7 @@ "source": [ "import azureml.core\n", "\n", - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/automl_env.yml b/how-to-use-azureml/automated-machine-learning/automl_env.yml index 7c555234..c0477d43 100644 --- a/how-to-use-azureml/automated-machine-learning/automl_env.yml +++ b/how-to-use-azureml/automated-machine-learning/automl_env.yml @@ -21,8 +21,9 @@ dependencies: - pip: # Required packages for AzureML execution, history, and data preparation. - - azureml-widgets~=1.32.0 + - azureml-widgets~=1.33.0 - pytorch-transformers==1.0.0 - spacy==2.1.8 - https://aka.ms/automl-resources/packages/en_core_web_sm-2.1.0.tar.gz - - -r https://automlresources-prod.azureedge.net/validated-requirements/1.32.0/validated_win32_requirements.txt [--no-deps] + - -r https://automlresources-prod.azureedge.net/validated-requirements/1.33.0/validated_win32_requirements.txt [--no-deps] + - arch==4.14 diff --git a/how-to-use-azureml/automated-machine-learning/automl_env_linux.yml b/how-to-use-azureml/automated-machine-learning/automl_env_linux.yml index 696e97d4..e84b0d66 100644 --- a/how-to-use-azureml/automated-machine-learning/automl_env_linux.yml +++ b/how-to-use-azureml/automated-machine-learning/automl_env_linux.yml @@ -21,8 +21,9 @@ dependencies: - pip: # Required packages for AzureML execution, history, and data preparation. - - azureml-widgets~=1.32.0 + - azureml-widgets~=1.33.0 - pytorch-transformers==1.0.0 - spacy==2.1.8 - https://aka.ms/automl-resources/packages/en_core_web_sm-2.1.0.tar.gz - - -r https://automlresources-prod.azureedge.net/validated-requirements/1.32.0/validated_linux_requirements.txt [--no-deps] + - -r https://automlresources-prod.azureedge.net/validated-requirements/1.33.0/validated_linux_requirements.txt [--no-deps] + - arch==4.14 diff --git a/how-to-use-azureml/automated-machine-learning/automl_env_mac.yml b/how-to-use-azureml/automated-machine-learning/automl_env_mac.yml index a637bab9..25f81982 100644 --- a/how-to-use-azureml/automated-machine-learning/automl_env_mac.yml +++ b/how-to-use-azureml/automated-machine-learning/automl_env_mac.yml @@ -22,8 +22,9 @@ dependencies: - pip: # Required packages for AzureML execution, history, and data preparation. - - azureml-widgets~=1.32.0 + - azureml-widgets~=1.33.0 - pytorch-transformers==1.0.0 - spacy==2.1.8 - https://aka.ms/automl-resources/packages/en_core_web_sm-2.1.0.tar.gz - - -r https://automlresources-prod.azureedge.net/validated-requirements/1.32.0/validated_darwin_requirements.txt [--no-deps] + - -r https://automlresources-prod.azureedge.net/validated-requirements/1.33.0/validated_darwin_requirements.txt [--no-deps] + - arch==4.14 diff --git a/how-to-use-azureml/automated-machine-learning/classification-bank-marketing-all-features/auto-ml-classification-bank-marketing-all-features.ipynb b/how-to-use-azureml/automated-machine-learning/classification-bank-marketing-all-features/auto-ml-classification-bank-marketing-all-features.ipynb index 7d636e48..0faa779d 100644 --- a/how-to-use-azureml/automated-machine-learning/classification-bank-marketing-all-features/auto-ml-classification-bank-marketing-all-features.ipynb +++ b/how-to-use-azureml/automated-machine-learning/classification-bank-marketing-all-features/auto-ml-classification-bank-marketing-all-features.ipynb @@ -86,7 +86,6 @@ "import azureml.core\n", "from azureml.core.experiment import Experiment\n", "from azureml.core.workspace import Workspace\n", - "from azureml.automl.core.featurization import FeaturizationConfig\n", "from azureml.core.dataset import Dataset\n", "from azureml.train.automl import AutoMLConfig\n", "from azureml.interpret import ExplanationClient" @@ -105,7 +104,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, @@ -599,27 +598,21 @@ "from azureml.automl.core.onnx_convert import OnnxConvertConstants\n", "from azureml.train.automl import constants\n", "\n", - "if sys.version_info < OnnxConvertConstants.OnnxIncompatiblePythonVersion:\n", - " python_version_compatible = True\n", - "else:\n", - " python_version_compatible = False\n", - "\n", - "import onnxruntime\n", "from azureml.automl.runtime.onnx_convert import OnnxInferenceHelper\n", "\n", "def get_onnx_res(run):\n", " res_path = 'onnx_resource.json'\n", " run.download_file(name=constants.MODEL_RESOURCE_PATH_ONNX, output_file_path=res_path)\n", " with open(res_path) as f:\n", - " onnx_res = json.load(f)\n", - " return onnx_res\n", + " result = json.load(f)\n", + " return result\n", "\n", - "if python_version_compatible:\n", + "if sys.version_info < OnnxConvertConstants.OnnxIncompatiblePythonVersion:\n", " test_df = test_dataset.to_pandas_dataframe()\n", " mdl_bytes = onnx_mdl.SerializeToString()\n", - " onnx_res = get_onnx_res(best_run)\n", + " onnx_result = get_onnx_res(best_run)\n", "\n", - " onnxrt_helper = OnnxInferenceHelper(mdl_bytes, onnx_res)\n", + " onnxrt_helper = OnnxInferenceHelper(mdl_bytes, onnx_result)\n", " pred_onnx, pred_prob_onnx = onnxrt_helper.predict(test_df)\n", "\n", " print(pred_onnx)\n", @@ -708,14 +701,12 @@ "source": [ "from azureml.core.model import InferenceConfig\n", "from azureml.core.webservice import AciWebservice\n", - "from azureml.core.webservice import Webservice\n", "from azureml.core.model import Model\n", - "from azureml.core.environment import Environment\n", "\n", "inference_config = InferenceConfig(entry_script=script_file_name)\n", "\n", - "aciconfig = AciWebservice.deploy_configuration(cpu_cores = 1, \n", - " memory_gb = 1, \n", + "aciconfig = AciWebservice.deploy_configuration(cpu_cores = 2, \n", + " memory_gb = 2, \n", " tags = {'area': \"bmData\", 'type': \"automl_classification\"}, \n", " description = 'sample service for Automl Classification')\n", "\n", @@ -792,7 +783,6 @@ "metadata": {}, "outputs": [], "source": [ - "import json\n", "import requests\n", "\n", "X_test_json = X_test.to_json(orient='records')\n", @@ -832,7 +822,6 @@ "source": [ "%matplotlib notebook\n", "from sklearn.metrics import confusion_matrix\n", - "import numpy as np\n", "import itertools\n", "\n", "cf =confusion_matrix(actual,y_pred)\n", diff --git a/how-to-use-azureml/automated-machine-learning/classification-credit-card-fraud/auto-ml-classification-credit-card-fraud.ipynb b/how-to-use-azureml/automated-machine-learning/classification-credit-card-fraud/auto-ml-classification-credit-card-fraud.ipynb index 6099f645..ec2a1584 100644 --- a/how-to-use-azureml/automated-machine-learning/classification-credit-card-fraud/auto-ml-classification-credit-card-fraud.ipynb +++ b/how-to-use-azureml/automated-machine-learning/classification-credit-card-fraud/auto-ml-classification-credit-card-fraud.ipynb @@ -93,7 +93,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/classification-text-dnn/auto-ml-classification-text-dnn.ipynb b/how-to-use-azureml/automated-machine-learning/classification-text-dnn/auto-ml-classification-text-dnn.ipynb index bd3fc9db..da4e7900 100644 --- a/how-to-use-azureml/automated-machine-learning/classification-text-dnn/auto-ml-classification-text-dnn.ipynb +++ b/how-to-use-azureml/automated-machine-learning/classification-text-dnn/auto-ml-classification-text-dnn.ipynb @@ -96,7 +96,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/continuous-retraining/auto-ml-continuous-retraining.ipynb b/how-to-use-azureml/automated-machine-learning/continuous-retraining/auto-ml-continuous-retraining.ipynb index 2646497c..54a458e7 100644 --- a/how-to-use-azureml/automated-machine-learning/continuous-retraining/auto-ml-continuous-retraining.ipynb +++ b/how-to-use-azureml/automated-machine-learning/continuous-retraining/auto-ml-continuous-retraining.ipynb @@ -81,7 +81,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/experimental/classification-credit-card-fraud-local-managed/auto-ml-classification-credit-card-fraud-local-managed.ipynb b/how-to-use-azureml/automated-machine-learning/experimental/classification-credit-card-fraud-local-managed/auto-ml-classification-credit-card-fraud-local-managed.ipynb index 739fafc6..808599a8 100644 --- a/how-to-use-azureml/automated-machine-learning/experimental/classification-credit-card-fraud-local-managed/auto-ml-classification-credit-card-fraud-local-managed.ipynb +++ b/how-to-use-azureml/automated-machine-learning/experimental/classification-credit-card-fraud-local-managed/auto-ml-classification-credit-card-fraud-local-managed.ipynb @@ -92,7 +92,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/experimental/regression-model-proxy/auto-ml-regression-model-proxy.ipynb b/how-to-use-azureml/automated-machine-learning/experimental/regression-model-proxy/auto-ml-regression-model-proxy.ipynb index aabe4da4..0a7e7fe4 100644 --- a/how-to-use-azureml/automated-machine-learning/experimental/regression-model-proxy/auto-ml-regression-model-proxy.ipynb +++ b/how-to-use-azureml/automated-machine-learning/experimental/regression-model-proxy/auto-ml-regression-model-proxy.ipynb @@ -91,7 +91,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/forecasting-beer-remote/auto-ml-forecasting-beer-remote.ipynb b/how-to-use-azureml/automated-machine-learning/forecasting-beer-remote/auto-ml-forecasting-beer-remote.ipynb index dd89dc44..81385758 100644 --- a/how-to-use-azureml/automated-machine-learning/forecasting-beer-remote/auto-ml-forecasting-beer-remote.ipynb +++ b/how-to-use-azureml/automated-machine-learning/forecasting-beer-remote/auto-ml-forecasting-beer-remote.ipynb @@ -113,7 +113,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, @@ -372,7 +372,8 @@ " freq='MS' # Set the forecast frequency to be monthly (start of the month)\n", ")\n", "\n", - "automl_config = AutoMLConfig(task='forecasting', \n", + "# We will disable the enable_early_stopping flag to ensure the DNN model is recommended for demonstration purpose.\n", + "automl_config = AutoMLConfig(task='forecasting',\n", " primary_metric='normalized_root_mean_squared_error',\n", " experiment_timeout_hours = 1,\n", " training_data=train_dataset,\n", @@ -383,6 +384,7 @@ " max_concurrent_iterations=4,\n", " max_cores_per_iteration=-1,\n", " enable_dnn=True,\n", + " enable_early_stopping=False,\n", " forecasting_parameters=forecasting_parameters)" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/forecasting-bike-share/auto-ml-forecasting-bike-share.ipynb b/how-to-use-azureml/automated-machine-learning/forecasting-bike-share/auto-ml-forecasting-bike-share.ipynb index fbcee6f7..a6feb717 100644 --- a/how-to-use-azureml/automated-machine-learning/forecasting-bike-share/auto-ml-forecasting-bike-share.ipynb +++ b/how-to-use-azureml/automated-machine-learning/forecasting-bike-share/auto-ml-forecasting-bike-share.ipynb @@ -87,7 +87,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/forecasting-energy-demand/auto-ml-forecasting-energy-demand.ipynb b/how-to-use-azureml/automated-machine-learning/forecasting-energy-demand/auto-ml-forecasting-energy-demand.ipynb index 23b06788..afe7ae4c 100644 --- a/how-to-use-azureml/automated-machine-learning/forecasting-energy-demand/auto-ml-forecasting-energy-demand.ipynb +++ b/how-to-use-azureml/automated-machine-learning/forecasting-energy-demand/auto-ml-forecasting-energy-demand.ipynb @@ -99,7 +99,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/forecasting-forecast-function/auto-ml-forecasting-function.ipynb b/how-to-use-azureml/automated-machine-learning/forecasting-forecast-function/auto-ml-forecasting-function.ipynb index 2d7b38be..6710f93e 100644 --- a/how-to-use-azureml/automated-machine-learning/forecasting-forecast-function/auto-ml-forecasting-function.ipynb +++ b/how-to-use-azureml/automated-machine-learning/forecasting-forecast-function/auto-ml-forecasting-function.ipynb @@ -94,7 +94,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, diff --git a/how-to-use-azureml/automated-machine-learning/forecasting-orange-juice-sales/auto-ml-forecasting-orange-juice-sales.ipynb b/how-to-use-azureml/automated-machine-learning/forecasting-orange-juice-sales/auto-ml-forecasting-orange-juice-sales.ipynb index cd1f24be..4971c75c 100644 --- a/how-to-use-azureml/automated-machine-learning/forecasting-orange-juice-sales/auto-ml-forecasting-orange-juice-sales.ipynb +++ b/how-to-use-azureml/automated-machine-learning/forecasting-orange-juice-sales/auto-ml-forecasting-orange-juice-sales.ipynb @@ -60,7 +60,6 @@ "source": [ "import azureml.core\n", "import pandas as pd\n", - "import numpy as np\n", "import logging\n", "\n", "from azureml.core.workspace import Workspace\n", @@ -82,7 +81,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(\"This notebook was created using version 1.32.0 of the Azure ML SDK\")\n", + "print(\"This notebook was created using version 1.33.0 of the Azure ML SDK\")\n", "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" ] }, @@ -688,8 +687,8 @@ "inference_config = InferenceConfig(environment = best_run.get_environment(), \n", " entry_script = script_file_name)\n", "\n", - "aciconfig = AciWebservice.deploy_configuration(cpu_cores = 1, \n", - " memory_gb = 2, \n", + "aciconfig = AciWebservice.deploy_configuration(cpu_cores = 2, \n", + " memory_gb = 4, \n", " tags = {'type': \"automl-forecasting\"},\n", " description = \"Automl forecasting sample service\")\n", "\n", diff --git a/how-to-use-azureml/automated-machine-learning/forecasting-recipes-univariate/auto-ml-forecasting-univariate-recipe-experiment-settings.ipynb b/how-to-use-azureml/automated-machine-learning/forecasting-recipes-univariate/auto-ml-forecasting-univariate-recipe-experiment-settings.ipynb new file mode 100644 index 00000000..3d684074 --- /dev/null +++ b/how-to-use-azureml/automated-machine-learning/forecasting-recipes-univariate/auto-ml-forecasting-univariate-recipe-experiment-settings.ipynb @@ -0,0 +1,492 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Copyright (c) Microsoft Corporation. All rights reserved.\n", + "\n", + "Licensed under the MIT License." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/automated-machine-learning/forecasting-recipes-univariate/1_determine_experiment_settings.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this notebook we will explore the univaraite time-series data to determine the settings for an automated ML experiment. We will follow the thought process depicted in the following diagram:
\n", + "![Forecasting after training](figures/univariate_settings_map_20210408.jpg)\n", + "\n", + "The objective is to answer the following questions:\n", + "\n", + "
    \n", + "
  1. Is there a seasonal pattern in the data?
  2. \n", + " \n", + "
  3. Is the data stationary?
  4. \n", + " \n", + "
  5. Is there a detectable auto-regressive pattern in the stationary data?
  6. \n", + " \n", + "
\n", + "\n", + "The answers to these questions will help determine the appropriate settings for the automated ML experiment.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import warnings\n", + "import pandas as pd\n", + "\n", + "from statsmodels.graphics.tsaplots import plot_acf, plot_pacf\n", + "import matplotlib.pyplot as plt\n", + "from pandas.plotting import register_matplotlib_converters\n", + "register_matplotlib_converters() # fixes the future warning issue\n", + "\n", + "from helper_functions import unit_root_test_wrapper\n", + "from statsmodels.tools.sm_exceptions import InterpolationWarning\n", + "warnings.simplefilter('ignore', InterpolationWarning)\n", + "\n", + "\n", + "# set printing options\n", + "pd.set_option('display.max_columns', 500)\n", + "pd.set_option('display.width', 1000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load data\n", + "main_data_loc = 'data'\n", + "train_file_name = 'S4248SM144SCEN.csv'\n", + "\n", + "TARGET_COLNAME = 'S4248SM144SCEN'\n", + "TIME_COLNAME = 'observation_date'\n", + "COVID_PERIOD_START = '2020-03-01'\n", + "\n", + "df = pd.read_csv(os.path.join(main_data_loc, train_file_name))\n", + "df[TIME_COLNAME] = pd.to_datetime(df[TIME_COLNAME], format='%Y-%m-%d')\n", + "df.sort_values(by=TIME_COLNAME, inplace=True)\n", + "df.set_index(TIME_COLNAME, inplace=True)\n", + "df.head(2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# plot the entire dataset\n", + "fig, ax = plt.subplots(figsize=(6,2), dpi=180)\n", + "ax.plot(df)\n", + "ax.title.set_text('Original Data Series')\n", + "locs, labels = plt.xticks()\n", + "plt.xticks(rotation=45)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The graph plots the alcohol sales in the United States. Because the data is trending, it can be difficult to see cycles, seasonality or other interestng behaviors due to the scaling issues. For example, if there is a seasonal pattern, which we will discuss later, we cannot see them on the trending data. In such case, it is worth plotting the same data in first differences." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# plot the entire dataset in first differences\n", + "fig, ax = plt.subplots(figsize=(6,2), dpi=180)\n", + "ax.plot(df.diff().dropna())\n", + "ax.title.set_text('Data in first differences')\n", + "locs, labels = plt.xticks()\n", + "plt.xticks(rotation=45)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the previous plot we observe that the data is more volatile towards the end of the series. This period coincides with the Covid-19 period, so we will exclude it from our experiment. Since in this example there are no user-provided features it is hard to make an argument that a model trained on the less volatile pre-covid data will be able to accurately predict the covid period." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1. Seasonality\n", + "\n", + "#### Questions that need to be answered in this section:\n", + "1. Is there a seasonality?\n", + "2. If it's seasonal, does the data exhibit a trend (up or down)?\n", + "\n", + "It is hard to visually detect seasonality when the data is trending. The reason being is scale of seasonal fluctuations is dwarfed by the range of the trend in the data. One way to deal with this is to de-trend the data by taking the first differences. We will discuss this in more detail in the next section." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# plot the entire dataset in first differences\n", + "fig, ax = plt.subplots(figsize=(6,2), dpi=180)\n", + "ax.plot(df.diff().dropna())\n", + "ax.title.set_text('Data in first differences')\n", + "locs, labels = plt.xticks()\n", + "plt.xticks(rotation=45)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the next plot, we will exclude the Covid period again. We will also shorten the length of data because plotting a very long time series may prevent us from seeing seasonal patterns, if there are any, because the plot may look like a random walk." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# remove COVID period\n", + "df = df[:COVID_PERIOD_START]\n", + "\n", + "# plot the entire dataset in first differences\n", + "fig, ax = plt.subplots(figsize=(6,2), dpi=180)\n", + "ax.plot(df['2015-01-01':].diff().dropna())\n", + "ax.title.set_text('Data in first differences')\n", + "locs, labels = plt.xticks()\n", + "plt.xticks(rotation=45)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Conclusion

\n", + "\n", + "Visual examination does not suggest clear seasonal patterns. We will set the STL_TYPE = None, and we will move to the next section that examines stationarity. \n", + "\n", + "\n", + "Say, we are working with a different data set that shows clear patterns of seasonality, we have several options for setting the settings:is hard to say which option will work best in your case, hence you will need to run both options to see which one results in more accurate forecasts. \n", + "
    \n", + "
  1. If the data does not appear to be trending, set DIFFERENCE_SERIES=False, TARGET_LAGS=None and STL_TYPE = \"season\"
  2. \n", + "
  3. If the data appears to be trending, consider one of the following two settings:\n", + " \n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2. Stationarity\n", + "If the data does not exhibit seasonal patterns, we would like to see if the data is non-stationary. Particularly, we want to see if there is a clear trending behavior. If such behavior is observed, we would like to first difference the data and examine the plot of an auto-correlation function (ACF) known as correlogram. If the data is seasonal, differencing it will not get rid off the seasonality and this will be shown on the correlogram as well.\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "#### Questions that need to be answered in this section:\n", + "
    \n", + "
  1. Is the data stationary?
  2. \n", + "
  3. Does the stationarized data (either the original or the differenced series) exhibit a clear auto-regressive pattern?
  4. \n", + "
\n", + "\n", + "To answer the first question, we run a series of tests (we call them unit root tests)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# unit root tests\n", + "test = unit_root_test_wrapper(df[TARGET_COLNAME])\n", + "print('---------------', '\\n')\n", + "print('Summary table', '\\n', test['summary'], '\\n')\n", + "print('Is the {} series stationary?: {}'.format(TARGET_COLNAME, test['stationary']))\n", + "print('---------------', '\\n')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the previous cell, we ran a series of unit root tests. The summary table contains the following columns:\n", + "\n", + "\n", + "Each of the tests shows that the original time series is non-stationary. The final decision is based on the majority rule. If, there is a split decision, the algorithm will claim it is stationary. We run a series of tests because each test by itself may not be accurate. In many cases when there are conflicting test results, the user needs to make determination if the series is stationary or not.\n", + "\n", + "Since we found the series to be non-stationary, we will difference it and then test if the differenced series is stationary." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# unit root tests\n", + "test = unit_root_test_wrapper(df[TARGET_COLNAME].diff().dropna())\n", + "print('---------------', '\\n')\n", + "print('Summary table', '\\n', test['summary'], '\\n')\n", + "print('Is the {} series stationary?: {}'.format(TARGET_COLNAME, test['stationary']))\n", + "print('---------------', '\\n')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Four out of five tests show that the series in first differences is stationary. Notice that this decision is not unanimous. Next, let's plot the original series in first-differences to illustrate the difference between non-stationary (unit root) process vs the stationary one." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# plot original and stationary data\n", + "fig = plt.figure(figsize=(10,10))\n", + "ax1 = fig.add_subplot(211)\n", + "ax1.plot(df[TARGET_COLNAME], '-b')\n", + "ax2 = fig.add_subplot(212)\n", + "ax2.plot(df[TARGET_COLNAME].diff().dropna(), '-b')\n", + "ax1.title.set_text('Original data')\n", + "ax2.title.set_text('Data in first differences')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you were asked a question \"What is the mean of the series before and after 2008?\", for the series titled \"Original data\" the mean values will be significantly different. This implies that the first moment of the series (in this case, it is the mean) is time dependent, i.e., mean changes depending on the interval one is looking at. Thus, the series is deemed to be non-stationary. On the other hand, for the series titled \"Data in first differences\" the means for both periods are roughly the same. Hence, the first moment is time invariant; meaning it does not depend on the interval of time one is looking at. In this example it is easy to visually distinguish between stationary and non-stationary data. Often this distinction is not easy to make, therefore we rely on the statistical tests described above to help us make an informed decision. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Conclusion

\n", + "Since we found the original process to be non-stationary (contains unit root), we will have to model the data in first differences. As a result, we will set the DIFFERENCE_SERIES parameter to True." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 3 Check if there is a clear autoregressive pattern\n", + "We need to determine if we should include lags of the target variable as features in order to improve forecast accuracy. To do this, we will examine the ACF and partial ACF (PACF) plots of the stationary series. In our case, it is a series in first diffrences.\n", + "\n", + "