The time plot in Figure 18.9 shows the series of quarterly shipments (in million dollars) of US household appliances between 1985–1989 (data are available in ApplianceShipments.csv, data courtesy of Ken Black).
Which of the following methods would be suitable for forecasting this series if applied to the raw data? 1. Moving average 2. Simple exponential smoothing 3. Double exponential smoothing 4. Holt–Winter’s exponential smoothing
# Load libraries
library(tidyverse) # for data manipulation
library(forecast) # for time series analysis
library(lubridate) # for date manipulation
library(mlba) # for load data
library(zoo) # for moving average
library(knitr) # for tables
# Load the data
data("ApplianceShipments") # Load the data to ApplianceShipments
# Create a time series object
appliance.ts <- ts(ApplianceShipments$Shipments,
start = c(1985, 1),
# end = c(1989, 4),
frequency = 4)
# Decompose the time series
appliance.decomp <- decompose(appliance.ts)
# Plot the decomposed time series
autoplot(appliance.decomp) +
xlab("Year") +
ylab("Shipments (in million dollars)") +
ggtitle("Decomposition of Appliance Shipments") +
theme_minimal()
Apply a moving average with window span w = 4 to the data. Use all but the last year as the training set. Create a time plot of the moving average series.
# Split the data into training and test set
nValid <- 4
nTrain <- length(appliance.ts) - nValid
train.ts <- window(appliance.ts, start = c(1985, 1), end = c(1985, nTrain + 1))
valid.ts <- window(appliance.ts, start = c(1985, nTrain + 1),
end = c(1985, nTrain + nValid))
# Plot train and test set
autoplot(train.ts, series = "Training") +
autolayer(valid.ts, series = "Validation") +
xlab("Year") +
ylab("Shipments (in million dollars)") +
ggtitle("Training and Validation Set of Appliance Shipments") +
theme_minimal()
# Create a moving average model
appliance.ma <- rollmean(train.ts, k=4, align = "right")
# Create a time plot of the moving average series
autoplot(appliance.ma, series = "Moving Average") +
autolayer(train.ts, series = "Actual") +
xlab("Year") +
ylab("Shipments (in million dollars)") +
ggtitle("Moving Average (w = 4) of Appliance Shipments") +
theme_minimal()
# Full moving average model
appliance.fullma <- rollmean(appliance.ts, k=4, align = "right")
# Forecast appliance sales in Q1-1990 and Q1-1991
forecast(appliance.ma, h = 9) |> kable()
Point Forecast | Lo 80 | Hi 80 | Lo 95 | Hi 95 | |
---|---|---|---|---|---|
1989 Q2 | 4429.759 | 4342.672 | 4516.845 | 4296.571 | 4562.946 |
1989 Q3 | 4429.759 | 4306.606 | 4552.912 | 4241.413 | 4618.105 |
1989 Q4 | 4429.759 | 4278.930 | 4580.587 | 4199.086 | 4660.431 |
1990 Q1 | 4429.759 | 4255.598 | 4603.919 | 4163.404 | 4696.114 |
1990 Q2 | 4429.759 | 4235.043 | 4624.475 | 4131.966 | 4727.551 |
1990 Q3 | 4429.759 | 4216.459 | 4643.059 | 4103.544 | 4755.973 |
1990 Q4 | 4429.759 | 4199.369 | 4660.149 | 4077.408 | 4782.110 |
1991 Q1 | 4429.759 | 4183.462 | 4676.056 | 4053.080 | 4806.437 |
1991 Q2 | 4429.759 | 4168.522 | 4690.996 | 4030.232 | 4829.286 |
forecast(appliance.fullma) |> kable()
Point Forecast | Lo 80 | Hi 80 | Lo 95 | Hi 95 | |
---|---|---|---|---|---|
1990 Q1 | 4565.743 | 4482.992 | 4648.494 | 4439.186 | 4692.300 |
1990 Q2 | 4565.743 | 4448.721 | 4682.765 | 4386.773 | 4744.713 |
1990 Q3 | 4565.743 | 4422.423 | 4709.063 | 4346.554 | 4784.932 |
1990 Q4 | 4565.743 | 4400.253 | 4731.233 | 4312.648 | 4818.838 |
1991 Q1 | 4565.743 | 4380.720 | 4750.766 | 4282.775 | 4848.711 |
1991 Q2 | 4565.743 | 4363.062 | 4768.425 | 4255.768 | 4875.718 |
1991 Q3 | 4565.743 | 4346.823 | 4784.664 | 4230.933 | 4900.553 |
1991 Q4 | 4565.743 | 4331.708 | 4799.779 | 4207.817 | 4923.669 |
# Plot the forecasts
autoplot(forecast(appliance.ma, h = 9)) +
autolayer(appliance.ts, series = "Actual") +
xlab("Year") +
ylab("Shipments (in million dollars)") +
ggtitle("Forecast of Appliance Shipments using MA(4)") +
theme_minimal()
autoplot(forecast(appliance.fullma)) +
autolayer(appliance.ts, series = "Actual") +
xlab("Year") +
ylab("Shipments (in million dollars)") +
ggtitle("Forecast of Appliance Shipments using MA(4)") +
theme_minimal()
We now focus on forecasting beyond 1989. In the following, continue to use all but the last year as the training set, and the last four quarters as the validation set. First, fit a regression model to sales with a linear trend and quarterly seasonality to the training data. Next, apply Holt–Winter’s exponential smoothing (with the default smoothing values) to the training data. Choose an adequate “season length.”
# Time series regression model
appliance.lm <- tslm(train.ts ~ trend + season, lambda = 1)
# Forecast appliance sales using the regression model
forecast.lm <- forecast(appliance.lm, h = nValid)
# Compute the MAPE for the validation data using the regression model
accuracy(forecast.lm, valid.ts) |> kable()
ME | RMSE | MAE | MPE | MAPE | MASE | ACF1 | Theil’s U | |
---|---|---|---|---|---|---|---|---|
Training set | 0.00000 | 151.56085 | 128.10941 | -0.1191684 | 2.908784 | 0.5804888 | 0.2760747 | NA |
Test set | -18.96667 | 99.01135 | 81.73333 | -0.4136366 | 1.782656 | 0.3703497 | -0.6158021 | 0.5425461 |
# Holt-Winter's exponential smoothing
appliance.ets <- ets(train.ts, model = "MAA")
# Forecast appliance sales using Holt-Winter's exponential smoothing
forecast.ets <- forecast(appliance.ets, h = nValid)
# Compute the MAPE for the validation data using Holt-Winter's exponential smoothing
accuracy(forecast.ets, valid.ts) |> kable()
ME | RMSE | MAE | MPE | MAPE | MASE | ACF1 | Theil’s U | |
---|---|---|---|---|---|---|---|---|
Training set | -37.94926 | 145.2715 | 108.5604 | -0.8678832 | 2.444005 | 0.4919082 | -0.1638919 | NA |
Test set | 473.25984 | 509.2908 | 473.2598 | 10.2195003 | 10.219500 | 2.1444329 | -0.1940605 | 2.675792 |
# Plot the forecasts
autoplot(forecast.lm, series = "Regression") +
# training data
autolayer(train.ts, series = "Training") +
# validation data
autolayer(valid.ts, series = "Validation") +
xlab("Year") +
ylab("Shipments (in million dollars)") +
ggtitle("Forecast of Appliance Shipments using Regression Model") +
theme_minimal()
autoplot(forecast.ets, series = "Holt-Winter's") +
# training data
autolayer(train.ts, series = "Training") +
# validation data
autolayer(valid.ts, series = "Validation") +
xlab("Year") +
ylab("Shipments (in million dollars)") +
ggtitle("Forecast of Appliance Shipments using Holt-Winter's Exponential Smoothing") +
theme_minimal()