#### ARIMA with Pyramid

H
```{
"cells": [
{
"cell_type": "markdown",
"source": [
"# ARIMA with pyramid\n",
"This notebook shows how to use the ARIMA-algorithm for forecasting univariate time series. To make things simple the [Pyramid Library](https://github.com/alkaline-ml/pmdarima) is used.\n",
"\n",
"In case you do not know ARIMA, have a quick look on the [wikipedia article](https://en.wikipedia.org/wiki/Autoregressive_integrated_moving_average)."
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"# First install the required packages\n",
"!pip install matplotlib numpy pandas pmdarima"
]
},
{
"cell_type": "code",
"execution_count": 1,
"outputs": [],
"source": [
"import pandas as pd\n",
"import pmdarima as pm\n",
"from pmdarima.model_selection import train_test_split\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"import warnings\n",
"warnings.filterwarnings('ignore')"
]
},
{
"cell_type": "markdown",
"source": [
"\n",
"In this example we will use the average temperature of the earth surface and make a prediction how this value will evolve.\n",
"The source of the data can be found at Kaggle: https://www.kaggle.com/berkeleyearth/climate-change-earth-surface-temperature-data"
]
},
{
"cell_type": "code",
"execution_count": 3,
"outputs": [],
"source": [
"df = pd.read_csv(\"data/GlobalTemperatures.csv\", parse_dates=[0])\n",
"df = df[[\"dt\", \"LandAverageTemperature\"]]\n",
"df[\"LandAverageTemperature\"] = df[\"LandAverageTemperature\"].interpolate()\n",
"ds_temp = df[\"LandAverageTemperature\"]"
]
},
{
"cell_type": "markdown",
"source": [
"## Create train and test data\n",
"You can either slpit by percentage or pick a start/end data. So you can decide which of the following two cells you want to run."
]
},
{
"cell_type": "code",
"execution_count": 5,
"outputs": [],
"source": [
"# split data by percentage\n",
"split_percentage = 80\n",
"train_size = int(ds_temp.shape[0]*(split_percentage/100))\n",
"train, test = train_test_split(ds_temp, train_size=train_size)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"outputs": [],
"source": [
"# split data by year\n",
"train_start_date = '1900-01-01'\n",
"train_end_date = '1999-12-01'\n",
"test_start_date = '2000-01-01'\n",
"test_end_date = '2015-12-01'\n",
"\n",
"train = df[(df[\"dt\"] >= train_start_date) & (df[\"dt\"] <= train_end_date)][\"LandAverageTemperature\"]\n",
"test = df[(df[\"dt\"] >= test_start_date) & (df[\"dt\"] <= test_end_date)][\"LandAverageTemperature\"]"
]
},
{
"cell_type": "markdown",
"source": [
"## Fit the model an create forecasts\n",
"\n",
"The `auto_arima` method of pyramid automatically fits the ARIMA model.\n",
"Within this function multiple parameters can be specified for the seasonality:\n",
"- seasonal: boolean variable that indicates that the values of the time series are repeated with a defined frequency.\n",
"- m: this value defines the frequency, so how many data points occur per year/per season. In this case 12 is needed, as the average temperatures per month are used."
]
},
{
"cell_type": "code",
"execution_count": 10,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 3min 19s\n"
]
}
],
"source": [
"%%time\n",
"# Measure the execution time of the model fitting\n",
"\n",
"# Fit model\n",
"model = pm.auto_arima(train, seasonal=True, m=12)"
]
},
{
"cell_type": "markdown",
"source": [
"With `model.summary()` you can get an insight into the fitted model and see what parameters were calculated by the `auto_arima` function."
]
},
{
"cell_type": "code",
"execution_count": 23,
"outputs": [
{
"data": {
"text/html": [
"<table class=\"simpletable\">\n",
"<caption>SARIMAX Results</caption>\n",
"<tr>\n",
"  <th>Dep. Variable:</th>                   <td>y</td>                <th>  No. Observations:  </th>   <td>1200</td>  \n",
"</tr>\n",
"<tr>\n",
"  <th>Model:</th>           <td>SARIMAX(1, 0, 0)x(1, 0, [1], 12)</td> <th>  Log Likelihood     </th> <td>-322.446</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>Date:</th>                    <td>Sun, 25 Oct 2020</td>         <th>  AIC                </th>  <td>654.892</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>Time:</th>                        <td>20:45:43</td>             <th>  BIC                </th>  <td>680.343</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>Sample:</th>                          <td>0</td>                <th>  HQIC               </th>  <td>664.479</td>\n",
"</tr>\n",
"<tr>\n",
"  <th></th>                              <td> - 1200</td>             <th>                     </th>     <td> </td>   \n",
"</tr>\n",
"<tr>\n",
"  <th>Covariance Type:</th>                <td>opg</td>               <th>                     </th>     <td> </td>   \n",
"</tr>\n",
"</table>\n",
"<table class=\"simpletable\">\n",
"<tr>\n",
"      <td></td>         <th>coef</th>     <th>std err</th>      <th>z</th>      <th>P>|z|</th>  <th>[0.025</th>    <th>0.975]</th>  \n",
"</tr>\n",
"<tr>\n",
"  <th>intercept</th> <td>    0.0009</td> <td>    0.000</td> <td>    3.227</td> <td> 0.001</td> <td>    0.000</td> <td>    0.002</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>ar.L1</th>     <td>    0.4255</td> <td>    0.024</td> <td>   17.702</td> <td> 0.000</td> <td>    0.378</td> <td>    0.473</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>ar.S.L12</th>  <td>    0.9998</td> <td> 6.48e-05</td> <td> 1.54e+04</td> <td> 0.000</td> <td>    1.000</td> <td>    1.000</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>ma.S.L12</th>  <td>   -0.8718</td> <td>    0.014</td> <td>  -60.383</td> <td> 0.000</td> <td>   -0.900</td> <td>   -0.843</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>sigma2</th>    <td>    0.0948</td> <td>    0.003</td> <td>   31.491</td> <td> 0.000</td> <td>    0.089</td> <td>    0.101</td>\n",
"</tr>\n",
"</table>\n",
"<table class=\"simpletable\">\n",
"<tr>\n",
"  <th>Ljung-Box (Q):</th>          <td>78.72</td> <th>  Jarque-Bera (JB):  </th> <td>96.69</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>Prob(Q):</th>                <td>0.00</td>  <th>  Prob(JB):          </th> <td>0.00</td> \n",
"</tr>\n",
"<tr>\n",
"  <th>Heteroskedasticity (H):</th> <td>0.99</td>  <th>  Skew:              </th> <td>-0.08</td>\n",
"</tr>\n",
"<tr>\n",
"  <th>Prob(H) (two-sided):</th>    <td>0.91</td>  <th>  Kurtosis:          </th> <td>4.38</td> \n",
"</tr>\n",
"</table><br/><br/>Warnings:<br/>[1] Covariance matrix calculated using the outer product of gradients (complex-step)."
],
"text/plain": [
"<class 'statsmodels.iolib.summary.Summary'>\n",
"\"\"\"\n",
"                                      SARIMAX Results                                       \n",
"============================================================================================\n",
"Dep. Variable:                                    y   No. Observations:                 1200\n",
"Model:             SARIMAX(1, 0, 0)x(1, 0, [1], 12)   Log Likelihood                -322.446\n",
"Date:                              Sun, 25 Oct 2020   AIC                            654.892\n",
"Time:                                      20:45:43   BIC                            680.343\n",
"Sample:                                           0   HQIC                           664.479\n",
"                                             - 1200                                         \n",
"Covariance Type:                                opg                                         \n",
"==============================================================================\n",
"                 coef    std err          z      P>|z|      [0.025      0.975]\n",
"------------------------------------------------------------------------------\n",
"intercept      0.0009      0.000      3.227      0.001       0.000       0.002\n",
"ar.L1          0.4255      0.024     17.702      0.000       0.378       0.473\n",
"ar.S.L12       0.9998   6.48e-05   1.54e+04      0.000       1.000       1.000\n",
"ma.S.L12      -0.8718      0.014    -60.383      0.000      -0.900      -0.843\n",
"sigma2         0.0948      0.003     31.491      0.000       0.089       0.101\n",
"===================================================================================\n",
"Ljung-Box (Q):                       78.72   Jarque-Bera (JB):                96.69\n",
"Prob(Q):                              0.00   Prob(JB):                         0.00\n",
"Heteroskedasticity (H):               0.99   Skew:                            -0.08\n",
"Prob(H) (two-sided):                  0.91   Kurtosis:                         4.38\n",
"===================================================================================\n",
"\n",
"Warnings:\n",
"[1] Covariance matrix calculated using the outer product of gradients (complex-step).\n",
"\"\"\""
]
},
"execution_count": 23,
"output_type": "execute_result"
}
],
"source": [
"model.summary()"
]
},
{
"cell_type": "markdown",
"source": [
"## Create Forecasts\n",
"With the fitted model, future datapoints can be predicted.\n",
"In this case, the amount of test datapoints is predicted, so that later the test data can be compared with the prediction."
]
},
{
"cell_type": "code",
"execution_count": 24,
"outputs": [],
"source": [
"# Create forecasts\n",
"forecasts = model.predict(test.shape[0])"
]
},
{
"cell_type": "markdown",
"source": [
"## Visualizations"
]
},
{
"cell_type": "code",
"execution_count": 25,
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Visualize the forecasts (green=train, blue=forecasts)\n",
"x = np.arange(train.shape[0] + test.shape[0])\n",
"plt.plot(x[:train.shape[0]], train, c='green')\n",
"plt.plot(x[train.shape[0]:], forecasts, c='blue')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 26,
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Compare forecasts and real values (green=test, blue=forecasts)\n",
"x = np.arange(test.shape[0])\n",
"plt.plot(x, test, c='green', alpha=0.5)\n",
"plt.plot(x, forecasts, c='blue', alpha=0.5)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"source": [
"## Conclusion\n",
"\n",
"The last figure demonstrates, how the forecasts and the real (test) values compare to each other.\n",
"\n",
"Overall ARIMA's prediction seems to be quite appropriate. Only the temperature peaks in summer are not predicted as well. "
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": []
}
],
"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.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
```

# ARIMA with pyramid

This notebook shows how to use the ARIMA-algorithm for forecasting univariate time series. To make things simple the Pyramid Library is used.

In case you do not know ARIMA, have a quick look on the wikipedia article.

``````# First install the required packages
!pip install matplotlib numpy pandas pmdarima``````
``````import pandas as pd
import pmdarima as pm
from pmdarima.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt

import warnings
warnings.filterwarnings('ignore')``````

In this example we will use the average temperature of the earth surface and make a prediction how this value will evolve. The source of the data can be found at Kaggle: https://www.kaggle.com/berkeleyearth/climate-change-earth-surface-temperature-data

``````# Load data
df = pd.read_csv("data/GlobalTemperatures.csv", parse_dates=[0])
df = df[["dt", "LandAverageTemperature"]]
df["LandAverageTemperature"] = df["LandAverageTemperature"].interpolate()
ds_temp = df["LandAverageTemperature"]``````

## Create train and test data

You can either slpit by percentage or pick a start/end data. So you can decide which of the following two cells you want to run.

``````# split data by percentage
split_percentage = 80
train_size = int(ds_temp.shape[0]*(split_percentage/100))
train, test = train_test_split(ds_temp, train_size=train_size)``````
``````# split data by year
train_start_date = '1900-01-01'
train_end_date = '1999-12-01'
test_start_date = '2000-01-01'
test_end_date = '2015-12-01'

train = df[(df["dt"] &gt;= train_start_date) & (df["dt"] &lt;= train_end_date)]["LandAverageTemperature"]
test = df[(df["dt"] &gt;= test_start_date) & (df["dt"] &lt;= test_end_date)]["LandAverageTemperature"]``````

## Fit the model an create forecasts

The `auto_arima` method of pyramid automatically fits the ARIMA model. Within this function multiple parameters can be specified for the seasonality:

• seasonal: boolean variable that indicates that the values of the time series are repeated with a defined frequency.
• m: this value defines the frequency, so how many data points occur per year/per season. In this case 12 is needed, as the average temperatures per month are used.
``````%%time
# Measure the execution time of the model fitting

# Fit model
model = pm.auto_arima(train, seasonal=True, m=12)``````
```Wall time: 3min 19s
```

With `model.summary()` you can get an insight into the fitted model and see what parameters were calculated by the `auto_arima` function.

``model.summary()``
Dep. Variable: No. Observations: y 1200 SARIMAX(1, 0, 0)x(1, 0, [1], 12) -322.446 Sun, 25 Oct 2020 654.892 20:45:43 680.343 0 664.479 - 1200 opg
coef std err z P>|z| [0.025 0.975] 0.0009 0.000 3.227 0.001 0.000 0.002 0.4255 0.024 17.702 0.000 0.378 0.473 0.9998 6.48e-05 1.54e+04 0.000 1.000 1.000 -0.8718 0.014 -60.383 0.000 -0.900 -0.843 0.0948 0.003 31.491 0.000 0.089 0.101
 Ljung-Box (Q): Jarque-Bera (JB): 78.72 96.69 0 0 0.99 -0.08 0.91 4.38

Warnings:
[1] Covariance matrix calculated using the outer product of gradients (complex-step).

## Create Forecasts

With the fitted model, future datapoints can be predicted. In this case, the amount of test datapoints is predicted, so that later the test data can be compared with the prediction.

``````# Create forecasts
forecasts = model.predict(test.shape[0])``````

## Visualizations

``````# Visualize the forecasts (green=train, blue=forecasts)
x = np.arange(train.shape[0] + test.shape[0])
plt.plot(x[:train.shape[0]], train, c='green')
plt.plot(x[train.shape[0]:], forecasts, c='blue')
plt.show()``````
``````# Compare forecasts and real values (green=test, blue=forecasts)
x = np.arange(test.shape[0])
plt.plot(x, test, c='green', alpha=0.5)
plt.plot(x, forecasts, c='blue', alpha=0.5)
plt.show()``````

## Conclusion

The last figure demonstrates, how the forecasts and the real (test) values compare to each other.

Overall ARIMA's prediction seems to be quite appropriate. Only the temperature peaks in summer are not predicted as well.

© The Algorithms 2024