Question. Figure 9.32 shows the ACFs for white noise series with n=36, 360, and 1000. Explain the differences. Do they all indicate white noise? Why do the critical values differ?
wn36 <- tsibble(idx = 1:36, y = rnorm(36), index = idx)
wn360 <- tsibble(idx = 1:360, y = rnorm(360), index = idx)
wn1000<- tsibble(idx = 1:1000,y = rnorm(1000),index = idx)
acf_data <- bind_rows(
wn36 %>% ACF(y) %>% mutate(n="n=36") %>% as_tibble(),
wn360 %>% ACF(y) %>% mutate(n="n=360") %>% as_tibble(),
wn1000%>% ACF(y) %>% mutate(n="n=1000") %>% as_tibble()
)
ggplot(acf_data, aes(lag, acf)) +
geom_hline(yintercept = 0) +
geom_segment(aes(xend = lag, y = 0, yend = acf)) +
facet_wrap(~ n, scales = "free_x")
Answer: All three series are white noise since their autocorrelations fluctuate around zero with no clear patterns. Smaller sample sizes (n=36) have wider confidence bands, while larger samples produce tighter bounds.
Question. Plot Amazon closing stock prices from
gafa_stock along with ACF and PACF. Explain why the series
is non-stationary and should be differenced.
amzn <- gafa_stock %>%
filter(Symbol == "AMZN") %>%
select(Date, Close) %>%
as_tsibble(index = Date)
autoplot(amzn, Close) + labs(title='Amazon Closing Prices', y='Price', x='Year')
ACF(amzn, Close) %>% autoplot()
PACF(amzn, Close) %>% autoplot()
amzn_log <- amzn %>% mutate(lclose = log(Close))
amzn_d1 <- amzn_log %>% mutate(d1 = difference(lclose))
ACF(amzn_d1, d1) %>% autoplot()
PACF(amzn_d1, d1) %>% autoplot()
Answer: The Amazon series is non-stationary because it trends upward and the ACF decays slowly. After log and first differencing, the ACF/PACF show near-zero correlations, indicating stationarity.
Question. For each series, find a Box-Cox
transformation and order of differencing to achieve stationarity.
(a) Turkish GDP, (b) Tasmania accommodation takings, (c) souvenir
sales.
tr_gdp <- global_economy %>% filter(Code=="TUR") %>% select(Year, GDP) %>% as_tsibble(index=Year)
tas_acc <- aus_accommodation %>% filter(State=="Tasmania") %>% select(Date, Takings) %>% as_tsibble(index=Date)
souvs <- souvenirs %>% select(Month, Sales) %>% as_tsibble(index=Month)
lam_tr <- tr_gdp %>% features(GDP, guerrero) %>% pull(lambda_guerrero)
lam_tas <- tas_acc %>% features(Takings, guerrero) %>% pull(lambda_guerrero)
lam_souv <- souvs %>% features(Sales, guerrero) %>% pull(lambda_guerrero)
lam_tr; lam_tas; lam_souv
## [1] 0.1572187
## [1] 0.001819643
## [1] 0.002118221
tr_d1 <- tr_gdp %>% mutate(y=box_cox(GDP,lam_tr), yd1=difference(box_cox(GDP,lam_tr)))
tas_D1d1 <- tas_acc %>% mutate(y=box_cox(Takings,lam_tas), yD1d1=difference(difference(y,lag=4)))
souv_D1d1 <- souvs %>% mutate(y=box_cox(Sales,lam_souv), yD1d1=difference(difference(y,lag=12)))
features(tr_d1, yd1, unitroot_kpss)
## # A tibble: 1 × 2
## kpss_stat kpss_pvalue
## <dbl> <dbl>
## 1 0.0889 0.1
features(tas_D1d1, yD1d1, unitroot_kpss)
## # A tibble: 1 × 2
## kpss_stat kpss_pvalue
## <dbl> <dbl>
## 1 0.0474 0.1
features(souv_D1d1, yD1d1, unitroot_kpss)
## # A tibble: 1 × 2
## kpss_stat kpss_pvalue
## <dbl> <dbl>
## 1 0.0381 0.1
Answer: Box-Cox transformations stabilize variance, and differencing removes trend/seasonality. For all three series, the KPSS test confirms stationarity after appropriate transformation and differencing.
Question. Simulate AR(1), MA(1), ARMA(1,1), and AR(2) processes.
n <- 200
# AR(1)
e <- rnorm(n)
y_ar1 <- numeric(n); y_ar1[1] <- 0
for(i in 2:n) y_ar1[i] <- 0.6*y_ar1[i-1] + e[i]
autoplot(tsibble(t=1:n,y=y_ar1,index=t), y)
# MA(1)
e2 <- rnorm(n)
y_ma1 <- e2 + 0.6*dplyr::lag(e2,default=0)
autoplot(tsibble(t=1:n,y=y_ma1,index=t), y)
# ARMA(1,1)
e3 <- rnorm(n)
y_arma <- numeric(n); y_arma[1] <- 0
for(i in 2:n) y_arma[i] <- 0.6*y_arma[i-1] + e3[i] + 0.6*e3[i-1]
autoplot(tsibble(t=1:n,y=y_arma,index=t), y)
# AR(2) nonstationary
e4 <- rnorm(n)
y_ar2 <- numeric(n); y_ar2[1:2]<-0
for(i in 3:n) y_ar2[i] <- -0.8*y_ar2[i-1] + 0.3*y_ar2[i-2] + e4[i]
autoplot(tsibble(t=1:n,y=y_ar2,index=t), y)
Answer: Each simulated process behaves as expected: AR(1) is persistent, MA(1) has short memory, ARMA(1,1) mixes both, and the nonstationary AR(2) explodes over time.
Question. Fit ARIMA to
aus_airpassengers, compare with benchmarks, forecast 10
years.
aus_airpassengers <- aus_airpassengers %>% select(Year, Passengers) %>% as_tsibble(index=Year)
lam_ap <- aus_airpassengers %>% features(Passengers, guerrero) %>% pull(lambda_guerrero)
ap_trans <- aus_airpassengers %>% mutate(y=box_cox(Passengers,lam_ap))
fit_auto <- ap_trans %>% model(ARIMA(y))
report(fit_auto)
## Series: y
## Model: ARIMA(0,1,0) w/ drift
##
## Coefficients:
## constant
## 0.0289
## s.e. 0.0063
##
## sigma^2 estimated as 0.001837: log likelihood=80.12
## AIC=-156.25 AICc=-155.97 BIC=-152.59
fit_auto %>% forecast(h="10 years") %>% autoplot(ap_trans)
Answer: The best model is ARIMA(0,1,0) with drift, meaning the series needs only differencing plus a mean trend. The 10-year forecast follows the long-term upward movement.
Question. Fit ARIMA and ETS to US GDP and compare forecasts.
us_gdp <- global_economy %>% filter(Code=="USA") %>% select(Year,GDP) %>% as_tsibble(index=Year)
lam_us <- us_gdp %>% features(GDP, guerrero) %>% pull(lambda_guerrero)
us_trans <- us_gdp %>% mutate(y=box_cox(GDP,lam_us))
fit_us_auto <- us_trans %>% model(ARIMA(y))
report(fit_us_auto)
## Series: y
## Model: ARIMA(1,1,0) w/ drift
##
## Coefficients:
## ar1 constant
## 0.4586 118.1822
## s.e. 0.1198 9.5047
##
## sigma^2 estimated as 5479: log likelihood=-325.32
## AIC=656.65 AICc=657.1 BIC=662.78
fit_us_auto %>% forecast(h="10 years") %>% autoplot(us_trans)
fit_ets <- us_gdp %>% model(ETS(GDP))
fit_ets %>% forecast(h="10 years") %>% autoplot(us_gdp)
Answer: ARIMA produces a linear trend after differencing, while ETS gives a smoother exponential-style forecast. Both predict continued GDP growth over the next decade.
Question. For one country in
aus_arrivals, difference, check ACF/PACF, fit ARIMA.
# Convert to tsibble directly (Quarter already in correct format)
aus_arrivals_fixed <- aus_arrivals %>%
as_tsibble(index = Quarter, key = Origin)
# Focus on Japan
x <- aus_arrivals_fixed %>% filter(Origin == "Japan")
autoplot(x, Arrivals) + labs(title='Japan Arrivals', y='Arrivals', x='Quarter')
lam_x <- x %>% features(Arrivals, guerrero) %>% pull(lambda_guerrero)
xt <- x %>% mutate(y = box_cox(Arrivals, lam_x))
xD1d1 <- xt %>% mutate(yD1d1 = difference(difference(y, lag = 4)))
ACF(xD1d1,yD1d1) %>% autoplot()
PACF(xD1d1,yD1d1) %>% autoplot()
fit_auto <- xt %>% model(ARIMA(y))
report(fit_auto)
## Series: y
## Model: ARIMA(0,1,2)(0,1,2)[4]
##
## Coefficients:
## ma1 ma2 sma1 sma2
## -0.2651 -0.1479 -0.7208 0.2206
## s.e. 0.0886 0.0891 0.0918 0.0905
##
## sigma^2 estimated as 4.164: log likelihood=-259.29
## AIC=528.57 AICc=529.09 BIC=542.59
fit_auto %>% forecast(h = "3 years") %>% autoplot(xt)
Answer: Trend and seasonality are removed with Box-Cox and lag-4 differencing. The selected ARIMA(0,1,2)(0,1,2)[4] fits well and the forecast preserves quarterly seasonality.