DATA_624_Homework_6

Author

Long Lin

library(fpp3)
── Attaching packages ──────────────────────────────────────────── fpp3 1.0.3 ──
✔ tibble      3.3.1     ✔ tsibble     1.2.0
✔ dplyr       1.2.0     ✔ tsibbledata 0.4.1
✔ tidyr       1.3.2     ✔ ggtime      1.0.0
✔ lubridate   1.9.5     ✔ feasts      0.5.0
✔ ggplot2     4.0.2     ✔ fable       0.5.0
── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
✖ lubridate::date()    masks base::date()
✖ dplyr::filter()      masks stats::filter()
✖ tsibble::intersect() masks base::intersect()
✖ tsibble::interval()  masks lubridate::interval()
✖ dplyr::lag()         masks stats::lag()
✖ tsibble::setdiff()   masks base::setdiff()
✖ tsibble::union()     masks base::union()

Exercise 9.1

Figure 9.32 shows the ACFs for 36 random numbers, 360 random numbers and 1,000 random numbers.

a. Explain the differences among these figures. Do they all indicate that the data are white noise?

All of the figures indicate white noise because all of the autocorrelations stay within the blue dashed lines. The differences between the figures are that as the sample gets bigger from 36 to 360 random numbers, the blue dashed lines get closer together and the autocorrelation spikes get smaller. The blue dashed lines get even closer together and the autocorrelation spikes get even smaller once there are 1000 random numbers.

b. Why are the critical values at different distances from the mean of zero? Why are the autocorrelations different in each figure when they each refer to white noise?

The critical values are at different distances from the mean of zero because as the sample size of random numbers increases, the bounds get tighter. This is due to the fact that the bounds are set at ±1.96/√T where T is the sample size. This means that as the sample increases, the denominator gets bigger as well resulting in a smaller interval.

The autocorrelations are different in each figure when they each refer to white noise because the sample size is different. Since the sample with only 36 numbers is smaller than the sample with 360 or 1000 samples, the autocorrelations will have bigger fluctuations. The same is true in reverse for the bigger samples.

Exercise 9.2

A classic example of a non-stationary series are stock prices. Plot the daily closing prices for Amazon stock (contained in gafa_stock), along with the ACF and PACF. Explain how each plot shows that the series is non-stationary and should be differenced.

gafa_stock |>
  filter(Symbol == "AMZN") |>
  autoplot(Close)

This plot shows that the data is non-stationary because there clearly is a trend present in the data. It trends positively for the most part and then has a negative trend at the end.

gafa_stock |>
  filter(Symbol == "AMZN") |>
  ACF(Close) |>
  autoplot()
Warning: Provided data has an irregular interval, results should be treated
with caution. Computing ACF by observation.

This ACF shows that the data is non-stationary because the ACF does not drop to 0 relatively quickly. Instead, it starts at 1 and then only slowly declines, so slow that at 30 lag, it still looks to be around 0.9.

gafa_stock |>
  filter(Symbol == "AMZN") |>
  PACF(Close) |>
  autoplot()
Warning: Provided data has an irregular interval, results should be treated
with caution. Computing ACF by observation.

This PACF plot shows that the data is non-stationary because there is one big spike at lag 1 that drops drastically for all the lags afterwards.

The three plots for the Amazon stock data shows that this is a random walk model and should be differenced so that it becomes stationary.

Exercise 9.3

For the following series, find an appropriate Box-Cox transformation and order of differencing in order to obtain stationary data.

a. Turkish GDP from global_economy.

turkey <- global_economy |> 
  filter(Country == "Turkey")

turkey |> 
  gg_tsdisplay(GDP, plot_type='partial')

The original plot shows a positive trend and the acf shows multiple lags where it goes past the blue dashed lines. The pacf also shows a close to 1 value on lag 1. This means that this dataset is non-stationary.

turkey_lambda <- turkey |>
  features(GDP, features = guerrero) |>
  pull(lambda_guerrero)
turkey_lambda
[1] 0.1572187

I used the Guerrero feature to find the lambda value of 0.1572187.

turkey |>
  mutate(bc_GDP = box_cox(GDP, turkey_lambda)) |>
  features(bc_GDP, list(unitroot_nsdiffs, unitroot_ndiffs))
# A tibble: 1 × 3
  Country nsdiffs ndiffs
  <fct>     <int>  <int>
1 Turkey        0      1

I used unitroot_ndiffs to estimate that it will require 1 difference to make the series stationary.

turkey |>
  mutate(d_bc_GDP = difference(box_cox(GDP, turkey_lambda))) |>
  gg_tsdisplay(d_bc_GDP, plot_type = "partial")
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).

Comparing the plot of the dataset differenced to the original is a night and day difference. Differencing once made the dataset stationary and the acf and pacf plots support that.

b. Accommodation takings in the state of Tasmania from aus_accommodation.

tasmania <- aus_accommodation |>
  filter(State == "Tasmania")

tasmania |>
  gg_tsdisplay(Takings, plot_type='partial')

The plot shows a dataset that is seasonal with a slightly positive trend. The acf plot shows multiple lags that go past the blue dashed lines. The pacf plot also shows multiple lags that go past the blue dashed lines.

tasmania_lambda <- tasmania |>
  features(Takings, features = guerrero) |>
  pull(lambda_guerrero)
tasmania_lambda
[1] 0.001819643

Using the Guerrero method, I got a lambda value of 0.001819643 for the box-cox.

tasmania |>
  mutate(bc_Takings = box_cox(Takings, tasmania_lambda)) |>
  features(bc_Takings, list(unitroot_nsdiffs, unitroot_ndiffs))
# A tibble: 1 × 3
  State    nsdiffs ndiffs
  <chr>      <int>  <int>
1 Tasmania       1      1

Using the unitroot_nsdiffs and unitroot_ndiffs features, I got an estimated 1 for the number of differences needed to make the data stationary as well as a 1 for the number of seasonal differences. Since this is quarterly data, seasonal difference would mean a lag of 4.

tasmania |>
  mutate(d_bc_Takings = difference(box_cox(Takings, tasmania_lambda), lag = 4)) |>
  features(d_bc_Takings, unitroot_ndiffs)
# A tibble: 1 × 2
  State    ndiffs
  <chr>     <int>
1 Tasmania      0

After taking the seasonal difference and recalculating with unitroot_ndiffs, it looks like a normal difference is not needed anymore.

tasmania |>
  mutate(d_bc_Takings = difference(box_cox(Takings, tasmania_lambda), lag = 4)) |>
  gg_tsdisplay(d_bc_Takings, plot_type = "partial")
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_point()`).

The plot looks to be stationary with the acf dropping rapidly to near zero.

c. Monthly sales from souvenirs.

souvenirs |>
  gg_tsdisplay(Sales, plot_type='partial')

The plot for souvenirs show seasonality with a clear spike in December, also the acf plot shows a spike on the lag 12.

souvenirs_lambda <- souvenirs |>
  features(Sales, features = guerrero) |>
  pull(lambda_guerrero)
souvenirs_lambda
[1] 0.002118221

Using the Guerrero feature, I got a lambda value of 0.002118221.

souvenirs |>
  mutate(bc_Sales = box_cox(Sales, souvenirs_lambda)) |>
  features(bc_Sales, list(unitroot_nsdiffs, unitroot_ndiffs))
# A tibble: 1 × 2
  nsdiffs ndiffs
    <int>  <int>
1       1      1

Since this is monthly data and unitroot_nsdiffs returned 1, I will try a seasonal difference of 12.

souvenirs |>
  mutate(d_bc_Sales = difference(box_cox(Sales, souvenirs_lambda), lag = 12)) |>
  features(d_bc_Sales, list(unitroot_nsdiffs, unitroot_ndiffs))
# A tibble: 1 × 2
  nsdiffs ndiffs
    <int>  <int>
1       0      0

Recalculating for unitroot_nsdiffs and unitroot_ndiffs after taking the seasonal difference shows that no more difference is needed.

souvenirs |>
  mutate(d_bc_Sales = difference(box_cox(Sales, souvenirs_lambda), lag = 12)) |>
  gg_tsdisplay(d_bc_Sales, plot_type = "partial")
Warning: Removed 12 rows containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 12 rows containing missing values or values outside the scale range
(`geom_point()`).

Doing a visual test, it shows that the data is no longer trending or seasonal. Also, the acf drops rapidly to 0 and no longer has the spike at lag 12. This shows that the data is now stationary.

Exercise 9.5

For your retail data (from Exercise 7 in Section 2.10), find the appropriate order of differencing (after transformation if necessary) to obtain stationary data.

set.seed(8585)
myseries <- aus_retail |>
  filter(`Series ID` == sample(aus_retail$`Series ID`,1))

myseries |> 
  gg_tsdisplay(Turnover, plot_type='partial')

This retail data has clearly seasonality and a positive trend. It is non-stationary based off of the plots above.

retail_lambda <- myseries |>
  features(Turnover, features = guerrero) |>
  pull(lambda_guerrero)
retail_lambda
[1] 0.1704623

Using the Guerrero feature, I got a lambda value of 0.1704623.

myseries |>
  mutate(bc_Turnover = box_cox(Turnover, retail_lambda)) |>
  features(bc_Turnover, list(unitroot_nsdiffs, unitroot_ndiffs))
# A tibble: 1 × 4
  State           Industry               nsdiffs ndiffs
  <chr>           <chr>                    <int>  <int>
1 New South Wales Other retailing n.e.c.       1      1

Based on the unitroot_nsdiffs and unitroot_ndiffs features, I will use a seasonal difference with lag 12 since its monthly data.

myseries |>
  mutate(d_bc_Turnover = difference(box_cox(Turnover, retail_lambda), lag = 12)) |>
  features(d_bc_Turnover, list(unitroot_nsdiffs, unitroot_ndiffs))
# A tibble: 1 × 4
  State           Industry               nsdiffs ndiffs
  <chr>           <chr>                    <int>  <int>
1 New South Wales Other retailing n.e.c.       0      0

After using the seasonal difference of lag 12 and recalculating, it looks like no more difference is required.

myseries |>
  mutate(d_bc_Turnover = difference(box_cox(Turnover, souvenirs_lambda), lag = 12)) |>
  gg_tsdisplay(d_bc_Turnover, plot_type = "partial")
Warning: Removed 12 rows containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 12 rows containing missing values or values outside the scale range
(`geom_point()`).

The plot shows that the acf goes to near 0 although it does take until lag 11 to get below the blue dashed line. For my retail data it required just taking the seasonal difference with a lag of 12 to become stationary.

Exercise 9.6

Simulate and plot some data from simple ARIMA models.

a. Use the following R code to generate data from an AR(1) model with ϕ1=0.6 and σ2=1. The process starts with y1=0.

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- 0.6 * y[i - 1] + e[i]
}
sim <- tsibble(idx = seq_len(100), y = y, index = idx)

b. Produce a time plot for the series. How does the plot change as you change ϕ1?

sim |> 
  autoplot(y)

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- 0 * y[i - 1] + e[i]
}
sim <- tsibble(idx = seq_len(100), y = y, index = idx)
sim |> 
  autoplot(y)

The plot with a phi value of 0 looks like its white noise.

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- 0.95 * y[i - 1] + e[i]
}
sim <- tsibble(idx = seq_len(100), y = y, index = idx)
sim |> 
  autoplot(y)

The plot with a phi value of 0.95 looks like it has a positive trend and a much smoother plot.

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- -0.5 * y[i - 1] + e[i]
}
sim <- tsibble(idx = seq_len(100), y = y, index = idx)
sim |> 
  autoplot(y)

The plot with a phi value of -0.5 looks like white noise with a lot of variance from point to point.

c. Write your own code to generate data from an MA(1) model with θ1=0.6 and σ2=1.

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- e[i] + 0.6 * e[i - 1]
}
sim_ma <- tsibble(idx = seq_len(100), y = y, index = idx)

d. Produce a time plot for the series. How does the plot change as you change θ1?

sim_ma |>
  autoplot(y)

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- e[i] + 0.95 * e[i - 1]
}
sim_ma <- tsibble(idx = seq_len(100), y = y, index = idx)
sim_ma |>
  autoplot(y)

Increasing the theta value to 0.95 seems to make it smoother with a larger interval between the biggest and smallest y values.

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- e[i] + -0.5 * e[i - 1]
}
sim_ma <- tsibble(idx = seq_len(100), y = y, index = idx)
sim_ma |>
  autoplot(y)

Using a theta value of -.05 looks to do the opposite by adding even more variance to the plot.

e. Generate data from an ARMA(1,1) model with ϕ1=0.6, θ1=0.6 and σ2=1.

y <- numeric(100)
e <- rnorm(100)
for (i in 2:100) {
  y[i] <- 0.6 * y[i - 1] + e[i] + 0.6 * e[i - 1]
}
sim_arma <- tsibble(idx = seq_len(100), y = y, index = idx)

f. Generate data from an AR(2) model with ϕ1=−0.8, ϕ2=0.3 and σ2=1. (Note that these parameters will give a non-stationary series.)

y <- numeric(100)
e <- rnorm(100)
for (i in 3:100) {
  y[i] <- -0.8 * y[i - 1] + 0.3 * y[i - 2] + e[i]
}
sim_ar2 <- tsibble(idx = seq_len(100), y = y, index = idx)

g. Graph the latter two series and compare them.

sim_arma |>
  gg_tsdisplay(y, plot_type = "partial")

sim_ar2 |>
  gg_tsdisplay(y, plot_type = "partial")

The plots for the latter 2 series are completely different. The plot for the ARMA(1, 1) looks stationary since there doesn’t appear to be any trend or seasonality, the acf and pacf supports this. The plot for the AR(2) looks like there’s a clear symmetrical pattern and non-stationary since the variance is not constant. The acf plot for AR(2) shows almost every point going past the blue dashed lines.

Exercise 9.7

Consider aus_airpassengers, the total number of passengers (in millions) from Australian air carriers for the period 1970-2011.

a. Use ARIMA() to find an appropriate ARIMA model. What model was selected? Check that the residuals look like white noise. Plot forecasts for the next 10 periods.

ap <- aus_airpassengers |> filter(Year <= 2011)
fit_airpassengers <- ap |>
  model(ARIMA(Passengers))
report(fit_airpassengers)
Series: Passengers 
Model: ARIMA(0,2,1) 

Coefficients:
          ma1
      -0.8756
s.e.   0.0722

sigma^2 estimated as 4.671:  log likelihood=-87.8
AIC=179.61   AICc=179.93   BIC=182.99

ARIMA() selected a (0,2,1) model.

fit_airpassengers |>
  gg_tsresiduals()

The residuals do look like white noise according to the plots above.

fit_airpassengers |>
  forecast(h = 10) |>
  autoplot(aus_airpassengers) +
  labs(title = "Forecasts from ARIMA(0,2,1)")

b. Write the model in terms of the backshift operator.

\[(1 - B)^2 y_t = (1 - 0.8756 B) \varepsilon_t\]

c. Plot forecasts from an ARIMA(0,1,0) model with drift and compare these to part a.

fit_c <- ap |> 
  model(ARIMA(Passengers ~ 1 + pdq(0,1,0)))
fit_c |> 
  forecast(h = 10) |> 
  autoplot(ap)

fit_c |>
  gg_tsresiduals()

report(fit_c)
Series: Passengers 
Model: ARIMA(0,1,0) w/ drift 

Coefficients:
      constant
        1.3669
s.e.    0.3319

sigma^2 estimated as 4.629:  log likelihood=-89.08
AIC=182.17   AICc=182.48   BIC=185.59

The plot from part a had a much higher projection compared to the plot from part c. This is due to the drift in plot c that takes into account the average change for the whole 1970-2011 period.

d. Plot forecasts from an ARIMA(2,1,2) model with drift and compare these to parts a and c. Remove the constant and see what happens.

fit_d_drift <- ap |> 
  model(ARIMA(Passengers ~ 1 + pdq(2,1,2)))
report(fit_d_drift)
Series: Passengers 
Model: ARIMA(2,1,2) w/ drift 

Coefficients:
         ar1      ar2      ma1     ma2  constant
      1.4694  -0.5103  -1.5736  0.6780    0.0650
s.e.  0.3780   0.3558   0.3081  0.2688    0.0294

sigma^2 estimated as 4.748:  log likelihood=-87.74
AIC=187.47   AICc=189.94   BIC=197.75
fit_d_drift |>
  gg_tsresiduals()

fit_d_drift |> forecast(h = 10) |> autoplot(ap) +
  labs(title = "ARIMA(2,1,2) with drift")

The ARIMA(2,1,2) gives a similar forecast to part a and a higher forecast than part c.

fit_d_noconst <- ap |>
  model(ARIMA(Passengers ~ 0 + pdq(2,1,2)))
Warning: 1 error encountered for ARIMA(Passengers ~ 0 + pdq(2, 1, 2))
[1] non-stationary AR part from CSS
report(fit_d_noconst)
Series: Passengers 
Model: NULL model 
NULL model
fit_d_noconst |> 
  forecast(h = 10) |> autoplot(ap) +
  labs(title = "ARIMA(2,1,2) without constant")
Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
-Inf
Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
-Inf
Warning: Removed 10 rows containing missing values or values outside the scale range
(`geom_line()`).

Removing the constant seems to have resulted in a null model.

e. Plot forecasts from an ARIMA(0,2,1) model with a constant. What happens?

fit_e <- ap |> 
  model(ARIMA(Passengers ~ 1 + pdq(0,2,1)))
Warning: Model specification induces a quadratic or higher order polynomial trend.  This
is generally discouraged, consider removing the constant or reducing the number
of differences.
fit_e |> 
  forecast(h = 10) |> autoplot(ap)

fit_e |>
  gg_tsresiduals()

report(fit_e)
Series: Passengers 
Model: ARIMA(0,2,1) w/ poly 

Coefficients:
          ma1  constant
      -1.0000    0.0721
s.e.   0.0709    0.0260

sigma^2 estimated as 4.086:  log likelihood=-85.74
AIC=177.48   AICc=178.15   BIC=182.55

The plot for the ARIMA(0,2,1) model with a constant looks to appear steeper and gives a warning that suggests removing the constant because the model specification induces a quadratic or higher order polynomial trend.

Exercise 9.8

For the United States GDP series (from global_economy):

a. if necessary, find a suitable Box-Cox transformation for the data;

us <- global_economy |>
  filter(Country == "United States")

us |> autoplot(GDP)

us_lambda <- us |>
  features(GDP, features = guerrero) |>
  pull(lambda_guerrero)
us_lambda
[1] 0.2819443

Using the Guerrero feature, I got a lambda value of 0.2819443.

us |> autoplot(box_cox(GDP, us_lambda))

Using the lambda value, I got the box-cox transformation above.

b. fit a suitable ARIMA model to the transformed data using ARIMA();

fit_us <- us |>
  model(ARIMA(box_cox(GDP, us_lambda)))
report(fit_us)
Series: GDP 
Model: ARIMA(1,1,0) w/ drift 
Transformation: box_cox(GDP, us_lambda) 

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 |>
  forecast(h = 10) |>
  autoplot(us) +
  labs(title = "US GDP forecasts: ARIMA(1,1,0) with drift (Box-Cox)")

I used the ARIMA() function and got an ARIMA(1,1,0) model that I used to model the transformed data.

c. try some other plausible models by experimenting with the orders chosen;

fit_us_011 <- us |>
  model(ARIMA(box_cox(GDP, us_lambda) ~ pdq(0,1,1)))
report(fit_us_011)
Series: GDP 
Model: ARIMA(0,1,1) w/ drift 
Transformation: box_cox(GDP, us_lambda) 

Coefficients:
         ma1  constant
      0.4026  219.6195
s.e.  0.1098   13.6953

sigma^2 estimated as 5689:  log likelihood=-326.37
AIC=658.73   AICc=659.18   BIC=664.86
fit_us_111 <- us |>
  model(ARIMA(box_cox(GDP, us_lambda) ~ pdq(1,1,1)))
report(fit_us_111)
Series: GDP 
Model: ARIMA(1,1,1) w/ drift 
Transformation: box_cox(GDP, us_lambda) 

Coefficients:
         ar1      ma1  constant
      0.4736  -0.0190  114.8547
s.e.  0.2851   0.3286    9.3486

sigma^2 estimated as 5580:  log likelihood=-325.32
AIC=658.64   AICc=659.41   BIC=666.82
fit_us_012 <- us |>
  model(ARIMA(box_cox(GDP, us_lambda) ~ pdq(0,1,2)))
report(fit_us_012)
Series: GDP 
Model: ARIMA(0,1,2) w/ drift 
Transformation: box_cox(GDP, us_lambda) 

Coefficients:
         ma1     ma2  constant
      0.4479  0.1637  219.1786
s.e.  0.1308  0.1295   15.4672

sigma^2 estimated as 5634:  log likelihood=-325.58
AIC=659.17   AICc=659.94   BIC=667.34
fit_us_210 <- us |>
  model(ARIMA(box_cox(GDP, us_lambda) ~ pdq(2,1,0)))
report(fit_us_210)
Series: GDP 
Model: ARIMA(2,1,0) w/ drift 
Transformation: box_cox(GDP, us_lambda) 

Coefficients:
         ar1     ar2  constant
      0.4554  0.0071  117.2907
s.e.  0.1341  0.1352    9.5225

sigma^2 estimated as 5580:  log likelihood=-325.32
AIC=658.64   AICc=659.41   BIC=666.82
fit_us_221 <- us |>
  model(ARIMA(box_cox(GDP, us_lambda) ~ pdq(2,1,1)))
report(fit_us_221)
Series: GDP 
Model: ARIMA(2,1,1) w/ drift 
Transformation: box_cox(GDP, us_lambda) 

Coefficients:
         ar1      ar2      ma1  constant
      1.1661  -0.2792  -0.7356   24.3346
s.e.  0.3418   0.2108   0.3077    2.5572

sigma^2 estimated as 5647:  log likelihood=-325.14
AIC=660.29   AICc=661.46   BIC=670.5

d. choose what you think is the best model and check the residual diagnostics;

I think the ARIMA(0,1,1) is the best model of the ones I tested since it has the lowest AICc value of 659.18. The plot from the auto ARIMA still has a lower AICc value though at 657.1.

e. produce forecasts of your fitted model. Do the forecasts look reasonable?

fit_us_011 |>
  forecast(h = 10) |>
  autoplot(us)

The forecasts look reasonable, it follows the upward trend of the previous data at a similar pace.

f. compare the results with what you would obtain using ETS() (with no transformation).

fit_ets <- us |> 
  model(ETS(GDP))
report(fit_ets)
Series: GDP 
Model: ETS(M,A,N) 
  Smoothing parameters:
    alpha = 0.9990876 
    beta  = 0.5011949 

  Initial states:
         l[0]        b[0]
 448093333334 64917355687

  sigma^2:  7e-04

     AIC     AICc      BIC 
3190.787 3191.941 3201.089 
fit_ets |>
  forecast(h = 10) |>
  autoplot(us)

The ETS model produces a much wider interval for the forecast with a smaller positive slope.

us |>
  filter(Year <= 2012) |>
  model(
    arima_auto = ARIMA(box_cox(GDP, us_lambda)),
    arima_011  = ARIMA(box_cox(GDP, us_lambda) ~ pdq(0,1,1)),
    ets        = ETS(GDP)
  ) |>
  forecast(h = 5) |>
  accuracy(us)
# A tibble: 3 × 11
  .model    Country .type       ME    RMSE     MAE   MPE  MAPE  MASE RMSSE  ACF1
  <chr>     <fct>   <chr>    <dbl>   <dbl>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 arima_011 United… Test  -2.78e11 3.08e11 2.78e11 -1.51  1.51 0.892 0.821 0.419
2 arima_au… United… Test  -2.18e11 2.50e11 2.18e11 -1.18  1.18 0.699 0.666 0.400
3 ets       United… Test   2.91e11 3.45e11 2.91e11  1.57  1.57 0.935 0.920 0.191

Testing the accuracy of the ETS(), ARIMA(0,1,1), and auto ARIMA() models, it appears that the auto ARIMA() model was the best since it’s RMSSE value was the lowest. The ARIMA(0,1,1) came in second as a middleground with a RMSSE value between that of the auto ARIMA() and ETS() models.