Aikasarjaennustaminen 3

Tämä artikkeli on jatkoa artikkeleille Aikasarjaennustaminen 1 ja Aikasarjaennustaminen 2.

Edellisen artikkelin Aikasarjaennustaminen 2 lopussa totesin, että esimerkkinä käyttämässäni aikasarjassa on neljän vuosineljänneksen välein toistuvaa kausivaihtelua, joka on syytä huomioida ennustamisessa. Tässä artikkelissa tarkastelen kausivaihtelun huomioivaa Holt-Winterin menetelmää.

Holt-Winterin tulomallissa aikasarjan tason L (level) hetkellä t määrittää lauseke

Lt = alfa * Yt/St-s + (1 – alfa)(Lt-1 + Tt-1)

Yllä Yt on viimeisin havainto, St-s on edellisen vastaavan periodin kausivaihtelu ja  Tt-1 on edellinen trendi.

Trendille T hetkellä t saadaan arvio lausekkeesta

Tt = beta * (Lt – Lt-1) + (1 – beta) * Tt-1

Kausivaihtelulle S hetkellä t saadaan arvio lausekkeesta

St = gamma * Yt/Lt + (1 – gamma) * St-s

Ennuste hetkelle t + p saadaan

(Lt + pTt)St-s

Yllä on kyse Holt-Winterin tulomallista, jossa kausivaihtelu huomioidaan kausivaihtelukertoimena. Holt-Winterin mallia voidaan soveltaa myös summamallina, jolloin kausivaihtelu huomioidaan lisättävänä kausivaihteluterminä. Tulomalli soveltuu paremmin tilanteisiin, joissa kausivaihtelukomponentin suuruus vaihtelee aikasarjan tason L mukaan. Summamalli soveltuu tilanteisiin, joissa kausivaihtelukomponentin suuruus ei riipu aikasarjan tasosta L.

Mallin parametrit alfa, beta ja gamma pyritään määrittämään siten että virheiden keskihajonta RMSE saa pienimmän mahdollisen arvonsa.

Python toteutus

Tämän artikkelin ohjelmakoodin ja tulosteet löydät GitHubista:

https://github.com/taanila/tilastoapu/blob/master/forecast3.ipynb

Jos kopioit koodia itsellesi, niin kannattaa käyttää GitHubia. Tästä artikkelista kopioidut koodit eivät välttämättä toimi oikein (esimerkiksi sisennykset voivat kopioitua virheellisesti).

Oletan, että lukijalla on asennettuna Anaconda ja sen mukana tuleva Jupyter notebook.

Kirjastot

Tarvitsen monia ohjelmakirjastoja: pandas dataframen käsittelyyn, matplotlib kuvioiden tekemiseen, statsmodels eksponentiaaliseen tasoitukseen, sklearn ennustevirhettä kuvaavien tunnuslukujen laskemiseen ja math neliöjuuren laskemiseen.

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from statsmodels.tsa.api import Holt
from sklearn.metrics import mean_squared_error, mean_absolute_error
from math import sqrt

Aikasarja

Tallennan vuosineljänneksittäisiä myyntilukuja sisältävän aikasarjan data-nimiseen dataframeen:

series=[500,350,250,400,450,350,200,300,350,200,150,
   400,550,350,250,550,550, 400,350,600,750,500,400,650,850]
index=pd.date_range('2000-03-31', periods=25, freq='Q')
data=pd.DataFrame(series, index=index)
data.columns=['Demand']

Ennustemalli

Tämän jälkeen sovitan eksponentiaalisen mallin aikasarjaan ja tallennan mallin mukaiset sovitetut arvot datan Predict-sarakkeeseen. Jos haluan käyttää summamallia, niin korvaan parametrin seasonal=’mul’ parametrilla seasonal=’add’.

fit1 = ExponentialSmoothing(data['Demand'], seasonal_periods=4, 
   trend='add', seasonal='mul').fit()
data['Predict']=fit1.fittedvalues 
data.plot()

holtwinter1

Silmämäärin katsottuna Holt-Winterin malli istuu hyvin aikasarjaan. Tarkistan asian virheiden suuruutta kuvaavista tunnusluvuista. Ensiksi RMSE:

sqrt(mean_squared_error(data['Demand'], data['Predict']))

Tulokseksi saan RMSE = 53 ( yksinkertaisessa eksponentiaalisessa tasoituksessa 150)

MAD:

mean_absolute_error(data['Demand'], data['Predict'])

Tulokseksi saan MAD = 42 (yksinkertaisessa eksponentiaalisessa tasoituksessa 128)

Virheitä kannattaa tarkastella myös sellaisenaan:

data['Resid']=fit1.resid
data['Resid'].plot()

holtwinter2

Virheiden vaihtelu näyttää satunnaiselta niin kuin hyvässä mallissa pitää ollakin.

Ennuste

Lasken vielä ennusteet neljälle seuraavalle neljännekselle omaan dataframeen ja piirrän samaan kuvioon alkuperäisen aikasarjan ja neljän  neljänneksen ennusteet.

index=pd.date_range('2006-06-30', periods=4, freq='Q')
datap=pd.DataFrame(fit1.forecast(4), index=index)
datap.columns=['Predict']
data['Demand'].plot()
datap['Predict'].plot()

holtwinter3

Ennusteestakin (oranssi) näkee, että kausivaihtelu on mallissa huomioitu.

Mallin parametreista selviävät alfan (smoothing_level), betan (smoothing_slope), ja gamman (smoothing_seasonal) arvot sekä tason, trendin ja kausivaihtelun alkuarvot :

fit1.params

{’damping_slope’: nan,
’initial_level’: 571.4286398129714,
’initial_seasons’: array([0.84785489, 0.56435295, 0.41577146, 0.71556852]),
’initial_slope’: 18.700003064693195,
’lamda’: None,
’remove_bias’: False,
’smoothing_level’: 0.8700136796734163,
’smoothing_seasonal’: 0.0,
’smoothing_slope’: 1.818780385451967e-19,
’use_boxcox’: False}

Mainokset