I de neste to labbene skal vi ta i bruk noen av tidsrekke-verktøyene vi har lært, og anvende dem til å skape en prognose, eller forecast. Labbene er basert på boken Forecasting: Principles and Practice og bruker den som referanse. Det kan være særlig nyttig å lese gjennom k.8 og k.9.

library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.3     ✓ purrr   0.3.4
## ✓ tibble  3.0.6     ✓ dplyr   1.0.4
## ✓ tidyr   1.1.2     ✓ stringr 1.4.0
## ✓ readr   1.3.1     ✓ forcats 0.5.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(fpp2)
## Loading required package: forecast
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Loading required package: fma
## Loading required package: expsmooth

Prognoser basert på ARIMA

AR modellene som vi har brukt er en del av en større klasse modeller som heter ARIMA (AR: Autoregressive, MA: Moving Average. Vi kommer tilbake til hva ‘I’ betyr.)

An autoregressive model har vi allerede sett.

En Moving Average model er også dynamisk, men her er det feilene i modellen (eller sjokkene, hvis vi tenker økonomisk) som skaper dynamikken, og ikke y verdien.

Vi kan skrive en MA med orden 1 (MA(1)) modell som:

\(y_t = c + \epsilon_t + \epsilon_{t-1}\)

En MA med orden 2 (MA(2)) modell som:

\(y_t = c + \epsilon_t + \epsilon_{t-1} + \epsilon_{t-2}\)

Økonomiske intuisjonøen for en sånn modell er at en sjokk i en periode kan påvirke ikke bare nåværende periode, men også senere perioder.

En liten interessant fakta: alle AR modeller kan også skrives som MA modeller. Og alle MA modeller kan også skrives som AR modeller. Men som en praktisk sak, velger de fleste å bruke en blanding av AR og MA komponenter til å best modellere en tidsrekke.

Vi bruker en eksempel fra Forecasting boka. Her bruker de en datasett over bestillinger av utstry for kraftindustrien. Datasettet er inkludert i fpp2 pakken, og finnes med navnet elecequip.

str(elecequip)
##  Time-Series [1:195] from 1996 to 2012: 79.3 75.8 86.3 72.6 74.9 ...

Vi bruker autoplot funksjonen til fpp2 pakken til å plotte vår dataserie.

autoplot(elecequip)

Hva ser vi i denne dataserien?

  1. Det første vi kanskje ser er at det virker som det er noen sesonger, eller faste opp- og ned-mønsteret.

Så først ønsker vi å sesongjustere datasettet, så at vi kun har den mer langsiktige elementet.

stl deler opp tidsrekken i flere komponenter: en sesong komponent, en trend komponent og en feil-komponent (seasonal, trend and irregular)

decomp = elecequip %>% stl(s.window="periodic")
head(decomp$time.series)
##           seasonal    trend  remainder
## Jan 1996 -5.444213 80.35590  4.4383098
## Feb 1996 -5.967189 80.27515  1.4720416
## Mar 1996  8.039247 80.19439 -1.9136391
## Apr 1996 -6.385339 80.16226 -1.1769171
## May 1996 -4.839102 80.13012 -0.4310188
## Jun 1996  7.732144 80.13135 -4.0534979

Vi sender deretter vår objekt med alle komponentene til funksjonen seasadj, som justerer den opprinnelige datasettet for sesongvariasjon (trekker fra sesongene).

eeadj = decomp %>% seasadj()
autoplot(eeadj)

library(tseries)
adf.test(eeadj)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  eeadj
## Dickey-Fuller = -2.4033, Lag order = 5, p-value = 0.4073
## alternative hypothesis: stationary

Vi kan isteden ta en first-difference å se om det løser vårt problem

d_eeadj = eeadj %>% diff()
adf.test(d_eeadj)
## Warning in adf.test(d_eeadj): p-value smaller than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  d_eeadj
## Dickey-Fuller = -4.2461, Lag order = 5, p-value = 0.01
## alternative hypothesis: stationary

Nå ser det bedre ut!

Vi kan deretter se på ACF og pACF for å få litt innsikt i dynamikken

acf(d_eeadj)

pacf(d_eeadj)

Det ser ut som det er dynamikk i serien, og på pacf så ser det ut som det er kanskje 3 signifikante lag.

Så en første modell vi kan prøve er AR(3) med en differansse (I(1)). Det vil si en ARIMA(3,1,0).

diff y_t = diff y_t-1 + diff y_t-2 + diff y_t-3

fit1 = Arima(eeadj, order=c(3,1,0))

Vi kan sjekke residualene for å se om det er noe autokorrelasjon igjen?

acf(residuals(fit1))

pacf(residuals(fit1))

Det ser bra ut!

Nå kan vi snu modellen rundt og skape en forecast:

forecast1 = forecast(fit1, h=20)
autoplot(forecast1)

Oppgaver:

  1. Hva er noen av problemene ved denne prognosen, fra et praktisk standspunkt?

  2. Kjør en ARIMA modell uten differanse I(0). Hvordan ser prognosen ut da?

  3. I boken bruker de en ARIMA(3,1,1) isteden. Hvorfor har de valgt denne modellen? Blir resultatene annerledes?

Du kan lese mer om nøyaktig hvordan prognosen er laget her

Prognoser med sesong.

I eksemepelen over, lagde vi en prognose ut i fra en serie uten sesonger. Nå skal vi se på en prognose med sesonger.

Vi skal se på data om detaljhandel fra europa. Dette kommer også med pakken fpp2 og heter euretail.

str(euretail)
##  Time-Series [1:64] from 1996 to 2012: 89.1 89.5 89.9 90.1 89.2 ...

Jeg bruker en funksjon i fpp2 som automatisk viser både datasettet pluss ACF og PACF

euretail %>%  ggtsdisplay()

euretail %>% diff(lag=4) %>% ggtsdisplay()

Datasettet ser fortsatt ikke-stasjonær ut, så vi gjør en ekstra differanse:

euretail %>% diff(lag=4) %>% diff() %>% ggtsdisplay()

Nå begynner det å se bra ut.

Vi kjører vår ARIMA model. Hvis vi ser på vår PACF, så ser det ut som vi har autokorrelasjon i den første laggen. Vi har også sesong-korrelasjon på den 4. laggen.

Vi kan modellere det på følgende måte: 1 AR ledd, 1 sesong (4 kvartaler) ledd og både en sesong differanse og en vanlig differanse.

fit2 = euretail %>%
  Arima(order=c(1,1,0), seasonal=c(1,1,0))
residuals(fit2) %>% ggtsdisplay()

Nå ser vi ikke mange signifikante autokorrelasjoner

Nå er vi klar til å skape en prognose 3 år (12 kvartaler) i framtiden:

forecast2 = fit2 %>% forecast(h=12)
autoplot(forecast2)

Oppgave

Fra labb 12 lastet vi inn kronekurs data fra Norges Bank:

kronekurs = read_csv("https://jmaurit.github.io/anvendt_macro/lab/data/kroneKurs.csv")
## Parsed with column specification:
## cols(
##   date = col_date(format = ""),
##   NOK_USD = col_double()
## )
tail(kronekurs)
## # A tibble: 6 x 2
##   date       NOK_USD
##   <date>       <dbl>
## 1 2020-04-01   10.4 
## 2 2020-05-01   10.1 
## 3 2020-06-01    9.53
## 4 2020-07-01    9.30
## 5 2020-08-01    8.94
## 6 2020-09-01    9.14
kk_ts = ts(kronekurs$NOK_USD, start=c(1960,1), frequency=12)
autoplot(kk_ts)

Du skal lage en prognosemodell for kronen basert på en ARIMA modell.

  1. Ved å se på tidsrekken, ville det vært fornuftig å avgrense perioden som du bruker til å lage din prognose? Hvorfor?

  2. Skap en passende ARIMA modell og bruk den til å skape en prognose 12 måneder fram for valutakurset.

  3. Tror du at du kunne skape en bedre prognose ved å bruke mer informasjon. Hva slaks informasjon ville du ønsket å bruke?