{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "block_hidden": true
   },
   "outputs": [],
   "source": [
    "%load_ext rpy2.ipython\n",
    "%matplotlib inline\n",
    "from prophet import Prophet\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "import logging\n",
    "logging.getLogger('prophet').setLevel(logging.ERROR)\n",
    "logging.getLogger('numexpr').setLevel(logging.ERROR)\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "block_hidden": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "R[write to console]: Loading required package: Rcpp\n",
      "\n",
      "R[write to console]: Loading required package: rlang\n",
      "\n"
     ]
    }
   ],
   "source": [
    "%%R\n",
    "library(prophet)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By default Prophet fits additive seasonalities, meaning the effect of the seasonality is added to the trend to get the forecast. This time series of the number of air passengers is an example of when additive seasonality does not work:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "output_hidden": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "R[write to console]: Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.\n",
      "\n",
      "R[write to console]: Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 52084 characters]\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%R -w 10 -h 6 -u in\n",
    "df <- read.csv('../examples/example_air_passengers.csv')\n",
    "m <- prophet(df)\n",
    "future <- make_future_dataframe(m, 50, freq = 'm')\n",
    "forecast <- predict(m, future)\n",
    "plot(m, forecast)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 88284 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df = pd.read_csv('../examples/example_air_passengers.csv')\n",
    "m = Prophet()\n",
    "m.fit(df)\n",
    "future = m.make_future_dataframe(50, freq='MS')\n",
    "forecast = m.predict(future)\n",
    "fig = m.plot(forecast)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This time series has a clear yearly cycle, but the seasonality in the forecast is too large at the start of the time series and too small at the end. In this time series, the seasonality is not a constant additive factor as assumed by Prophet, rather it grows with the trend. This is multiplicative seasonality.\n",
    "\n",
    "Prophet can model multiplicative seasonality by setting `seasonality_mode='multiplicative'` in the input arguments:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "output_hidden": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "R[write to console]: Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.\n",
      "\n",
      "R[write to console]: Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 52480 characters]\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%R -w 10 -h 6 -u in\n",
    "m <- prophet(df, seasonality.mode = 'multiplicative')\n",
    "forecast <- predict(m, future)\n",
    "plot(m, forecast)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 74516 characters]\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "m = Prophet(seasonality_mode='multiplicative')\n",
    "m.fit(df)\n",
    "forecast = m.predict(future)\n",
    "fig = m.plot(forecast)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The components figure will now show the seasonality as a percent of the trend:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "output_hidden": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 37512 characters]\n"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%R -w 9 -h 6 -u in\n",
    "prophet_plot_components(m, forecast)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 50500 characters]\n",
      "text/plain": [
       "<Figure size 648x432 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = m.plot_components(forecast)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With `seasonality_mode='multiplicative'`, holiday effects will also be modeled as multiplicative. Any added seasonalities or extra regressors will by default use whatever `seasonality_mode` is set to, but can be overriden by specifying `mode='additive'` or `mode='multiplicative'` as an argument when adding the seasonality or regressor.\n",
    "\n",
    "For example, this block sets the built-in seasonalities to multiplicative, but includes an additive quarterly seasonality and an additive regressor:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%R\n",
    "m <- prophet(seasonality.mode = 'multiplicative')\n",
    "m <- add_seasonality(m, 'quarterly', period = 91.25, fourier.order = 8, mode = 'additive')\n",
    "m <- add_regressor(m, 'regressor', mode = 'additive')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "output_hidden": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<prophet.forecaster.Prophet at 0x7fd258219d30>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = Prophet(seasonality_mode='multiplicative')\n",
    "m.add_seasonality('quarterly', period=91.25, fourier_order=8, mode='additive')\n",
    "m.add_regressor('regressor', mode='additive')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Additive and multiplicative extra regressors will show up in separate panels on the components plot. Note, however, that it is pretty unlikely to have a mix of additive and multiplicative seasonalities, so this will generally only be used if there is a reason to expect that to be the case."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
