Wprowadzenie

Cel: wyznaczenie prognoz kursu wymiany USD-PLN za pomocą wygładzania wykładniczego oraz modelu ARIMA. Porównanie jakości otrzymanych prognoz.

Dane

Dane z okresu 2019-01-01–2022-12-31 podzielono na dwa zbiory: uczący (2019-01-01–2022-11-30) i testowy (2022-12-01–2022-12-31). Model jest szacowny na podstawie danych ze zbioru uczącego a jego zdolność predykcyjna (jakość prognoz) jest szacowana przez porównanie z wartościami ze zbioru testowego.

dat_xts <- as.xts(read.zoo('USD-PLN_r.csv', header=T,
                           index.column = 1, 
                           sep = ",", format = "%Y/%m/%d"))
dat_train <- dat_xts["2019-01-01/2022-11-30"]
dat_test <- dat_xts["2022-12-01/2022-12-31"]

hmax <- length(dat_test)
n_train <-length(dat_train)
n_test <-length(dat_test)

Zbiór uczący ma 991 obserwacji.

Zbiór testowy ma 21 obserwacji.

Metoda wygładzania wykładniczego

m_es <- holt(dat_train, h=hmax, alpha=.33)

#summary(m_es)

accuracy(m_es)
##                          ME       RMSE        MAE          MPE      MAPE
## Training set -0.00002659838 0.04205193 0.02947938 0.0008153522 0.7154978
##                  MASE      ACF1
## Training set 1.498975 0.5602824
##checkresiduals(m_es)
res_es <- m_es$residuals

m_es.fitted <- m_es$fitted
autoplot(m_es.fitted, series="teoret") +  autolayer(m_es$x, series="empir")

Box.test(res_es, type='Ljung-Box')
## 
##  Box-Ljung test
## 
## data:  res_es
## X-squared = 312.03, df = 1, p-value < 0.00000000000000022
## wyznaczenie prognoz


m_esf <- forecast(m_es, h=hmax)
autoplot(m_esf)

m_esa <- accuracy(m_esf, dat_test)

Dokładność prognoz

m_esa
##                          ME       RMSE        MAE          MPE      MAPE
## Training set -0.00002659838 0.04205193 0.02947938 0.0008153522 0.7154978
## Test set      0.08394175497 0.09554815 0.08394175 1.9011518474 1.9011518
##                  MASE      ACF1
## Training set 1.498975 0.5602824
## Test set     4.268291        NA

ARIMA

Stosowany jest wariant ARIMA(0,1,0) z dryfem.

m_aa  <- auto.arima(dat_train)
##summary(m_aa)
accuracy(m_aa)
##                       ME       RMSE        MAE        MPE      MAPE      MASE
## Training set 0.000670252 0.02849204 0.01958371 0.01426302 0.4779061 0.9957972
##                      ACF1
## Training set -0.003748486
##checkresiduals(m_aa)
res_aa <- m_aa$residuals

m_aa.fitted <- m_aa$fitted
autoplot(m_aa.fitted, series="teoret") +  autolayer(m_aa$x, series="empir")

Box.test(res_aa, type='Ljung-Box')
## 
##  Box-Ljung test
## 
## data:  res_aa
## X-squared = 0.013967, df = 1, p-value = 0.9059
##Wyznacznie prognoz na 4 miesiace i porównanie z wartościami ze zbioru testowgo

m_aaf <- forecast(m_aa, h=hmax)
autoplot(m_aaf)

m_aaa <- accuracy(m_aaf, dat_test)
m_aaa
##                        ME       RMSE        MAE         MPE      MAPE      MASE
## Training set  0.000670252 0.02849204 0.01958371  0.01426302 0.4779061 0.9957972
## Test set     -0.080511095 0.08840818 0.08051110 -1.82644162 1.8264416 4.0938476
##                      ACF1
## Training set -0.003748486
## Test set               NA

Metoda Naiwna

W metodzie naiwnej prognozą jest ostatnia zaobserowana wartość. Zwykle służy jako twz. benchmark (jeżeli bardziej skomplikowana metoda daje jakościowo te same prognozy to tejże skomplikowanej metody nie warto stosować)

m_sn  <- naive(dat_train, h=hmax)
f.naive.forecast <- forecast(m_sn, h=hmax)

e.residuals1 <- m_sn$residuals
e.fitted1 <- m_sn$fitted

plot(m_sn)

autoplot(m_sn)

##e.acc.naive <- accuracy(f.naive.forecast, ets.t)
e.acc.naive <- accuracy(f.naive.forecast, dat_test)

Porównanie prognoz

A.table <- rbind( m_esa, m_aaa, e.acc.naive)
row.names(A.table) <- c('es', 'es/t', 'arima', 'arima/t', 'naive', 'naive/t')
A.table <- as.data.frame(A.table)
A.table <- A.table[order(A.table$RMSE),]
A.table
##                     ME       RMSE        MAE           MPE      MAPE      MASE
## arima    0.00067025198 0.02849204 0.01958371  0.0142630184 0.4779061 0.9957972
## naive    0.00075222222 0.02868522 0.01966636  0.0159275369 0.4798795 1.0000000
## es      -0.00002659838 0.04205193 0.02947938  0.0008153522 0.7154978 1.4989745
## arima/t -0.08051109505 0.08840818 0.08051110 -1.8264416180 1.8264416 4.0938476
## naive/t -0.08173333333 0.08952771 0.08173333 -1.8540678208 1.8540678 4.1559962
## es/t     0.08394175497 0.09554815 0.08394175  1.9011518474 1.9011518 4.2682906
##                 ACF1
## arima   -0.003748486
## naive    0.110918081
## es       0.560282433
## arima/t           NA
## naive/t           NA
## es/t              NA

Jakość prognoz jest bardzo dobra a wielkość błędu podobna przy zastosowaniu wszystkich trzech metod. Czyli można naiwną :-)

Porównanie na wykresie (dane empiryczne + prognozy dla trzech metod):

autoplot(as.ts(dat_xts), series="empir") +  
  autolayer(m_esf$mean, series="es") +
  autolayer(m_aaf$mean, series="aa") +
  autolayer(f.naive.forecast$mean, series="naive") 

Porównanie na wykresie (dane empiryczne tylko dla zbioru testowego + prognozy dla trzech metod):

autoplot(as.ts(dat_test, start= n_train +1), series="empir") +  
  autolayer(m_esf$mean, series="es") +
  autolayer(m_aaf$mean, series="aa") +
  autolayer(f.naive.forecast$mean, series="naive")

Widać co zaszło: wartości szeregu empiryczny nieznacznie spadłay w przedziale 4.4–4.5. ARIMA oraz metoda naiwna przewidywały w zasadzie stałą wartość na poziomie 4.5 a wygładzanie wykładnicze spadek do poziomu około 4.25. Popełniane błędy są podobne a różnice między metodami niewielkie; tylko kierunek jest różny: ARIMA/MN przeszacowuje; WW niedoszacowuje.