Exercise 9.1

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.


Exercise 9.2

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.


Exercise 9.3

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.


Exercise 9.5

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.


Exercise 9.6

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.


Exercise 9.7

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.


Exercise 9.8

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.