library(forecast)
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: timeDate
## This is forecast 7.3

Read in Data and summarize

Appliance.data <- read.csv("ApplianceShipmentsReordered.csv") 
shipments.ts <- ts(Appliance.data$Shipments, start = c(1985,1), end = c(1989, 4), freq = 4) 
head(Appliance.data)
##     Quarter Shipments
## 1 Q1 - 1985      4009
## 2 Q2 - 1985      4321
## 3 Q3 - 1985      4224
## 4 Q4 - 1985      3944
## 5 Q1 - 1986      4123
## 6 Q2 - 1986      4522
summary(Appliance.data)
##       Quarter     Shipments   
##  Q1 - 1985: 1   Min.   :3944  
##  Q1 - 1986: 1   1st Qu.:4240  
##  Q1 - 1987: 1   Median :4489  
##  Q1 - 1988: 1   Mean   :4425  
##  Q1 - 1989: 1   3rd Qu.:4588  
##  Q2 - 1985: 1   Max.   :4900  
##  (Other)  :14
tail(Appliance.data)
##      Quarter Shipments
## 15 Q3 - 1988      4417
## 16 Q4 - 1988      4258
## 17 Q1 - 1989      4245
## 18 Q2 - 1989      4900
## 19 Q3 - 1989      4585
## 20 Q4 - 1989      4533
dim(Appliance.data)
## [1] 20  2

Plot

plot(shipments.ts, xlab = "Time", ylab = "shipments", ylim = c(3900, 5000), bty = "l")

Plot with trend and plot with zoom

shipments.lm <- tslm(shipments.ts ~ trend + I(trend^2)) 
par(mfrow = c(2, 1)) 
plot(shipments.ts, xlab = "Time", ylab = "shipments", ylim = c(3900, 5000), bty = "l") 
lines(shipments.lm$fitted, lwd = 2) 
shipments.ts.zoom <- window(shipments.ts, start = c(1986, 1), end = c(1988, 4)) 
plot(shipments.ts.zoom, xlab = "Time", ylab = "shipments", ylim = c(3900, 5000), bty = "l")

Forecasts in the validation period from a quadratic trend model estimated from the training period

#quadratic model training and validation lengths
nValid <- 4 
shipments.ts
##      Qtr1 Qtr2 Qtr3 Qtr4
## 1985 4009 4321 4224 3944
## 1986 4123 4522 4657 4030
## 1987 4493 4806 4551 4485
## 1988 4595 4799 4417 4258
## 1989 4245 4900 4585 4533
nTrain <- length(shipments.ts) - nValid
#quad model training and valid in windows
train.ts <- window(shipments.ts, start = c(1985, 1), end = c(1985, nTrain))
train.ts
##      Qtr1 Qtr2 Qtr3 Qtr4
## 1985 4009 4321 4224 3944
## 1986 4123 4522 4657 4030
## 1987 4493 4806 4551 4485
## 1988 4595 4799 4417 4258
valid.ts <- window(shipments.ts, start = c(1985, nTrain + 1), end = c(1985, nTrain + nValid))
valid.ts
##      Qtr1 Qtr2 Qtr3 Qtr4
## 1989 4245 4900 4585 4533
#quadratic trend
shipments.lm <- tslm(train.ts ~ trend + I(trend^2))
#forecast based on trend
shipments.lm.pred <- forecast(shipments.lm, h = nValid, level = 0)
#quadratic trend forecast
shipments.lm.pred
##         Point Forecast     Lo 0     Hi 0
## 1989 Q1       4409.468 4409.468 4409.468
## 1989 Q2       4355.424 4355.424 4355.424
## 1989 Q3       4291.984 4291.984 4291.984
## 1989 Q4       4219.148 4219.148 4219.148
#quadratic error
valid.ts - shipments.lm.pred$mean
##           Qtr1      Qtr2      Qtr3      Qtr4
## 1989 -164.4679  544.5758  293.0159  313.8523
plot(shipments.lm.pred, ylim = c(3900, 5000), ylab = "shipments", xlab = "Time", bty = "l", xaxt = "n", xlim = c(1985,1990.25), main ="", flty = 3)
axis(1, at = seq(1985, 1990, 1), labels = format(seq(1985, 1990, 1)))
lines(shipments.lm$fitted, lwd = 1)
lines(valid.ts, lwd = 3)

Accuracy measures for validation period forecast

shipments.lm.pred
##         Point Forecast     Lo 0     Hi 0
## 1989 Q1       4409.468 4409.468 4409.468
## 1989 Q2       4355.424 4355.424 4355.424
## 1989 Q3       4291.984 4291.984 4291.984
## 1989 Q4       4219.148 4219.148 4219.148
accuracy(shipments.lm.pred$mean, valid.ts)
##               ME     RMSE     MAE      MPE     MAPE       ACF1 Theil's U
## Test set 246.744 356.3615 328.978 5.138469 7.075664 -0.3992743 0.9384219

Names

names(shipments.lm.pred) 
##  [1] "model"     "mean"      "lower"     "upper"     "level"    
##  [6] "x"         "method"    "newdata"   "residuals" "fitted"
shipments.lm.pred$residuals
##            Qtr1       Qtr2       Qtr3       Qtr4
## 1985   12.73775  228.43971   44.53803 -312.96730
## 1986 -202.07626  138.21113  223.89489 -443.02500
## 1987  -10.54853  281.32430   14.59349  -53.74097
## 1988   63.32094  283.77920  -72.36618 -196.11520

Quadratic Error

valid.ts - shipments.lm.pred$mean
##           Qtr1      Qtr2      Qtr3      Qtr4
## 1989 -164.4679  544.5758  293.0159  313.8523

Histogram of Errors

hist(shipments.lm.pred$residuals, ylab = "Frequency", xlab = "Forecast Error", bty = "l", main ="")

#Create a time series out of the data. 
shipments.ets.AAN <- ets(shipments.ts, model = "AAN")
AAN <- ets(valid.ts,  model = "AAN")
ANNfc <- forecast(AAN, h = nValid, level = 0)  


#Fit Model 1 to the time series.
shipments.ets.MMN <- ets(shipments.ts, model = "MMN", damped = FALSE)
shipments.ets.MMN
## ETS(M,M,N) 
## 
## Call:
##  ets(y = shipments.ts, model = "MMN", damped = FALSE) 
## 
##   Smoothing parameters:
##     alpha = 1e-04 
##     beta  = 1e-04 
## 
##   Initial states:
##     l = 4023.4958 
##     b = 1.0083 
## 
##   sigma:  0.0546
## 
##      AIC     AICc      BIC 
## 289.0256 293.3113 294.0043
MMN <- ets(valid.ts,  model = "MMN")
MMNfc <- forecast(MMN, h = nValid, level = 0)
#Fit Model 2. 

shipments.ets.MMdN <- ets(shipments.ts, model = "MMN", damped = TRUE)
shipments.ets.MMdN
## ETS(M,Md,N) 
## 
## Call:
##  ets(y = shipments.ts, model = "MMN", damped = TRUE) 
## 
##   Smoothing parameters:
##     alpha = 1e-04 
##     beta  = 1e-04 
##     phi   = 0.8728 
## 
##   Initial states:
##     l = 4020.7947 
##     b = 1.0208 
## 
##   sigma:  0.0488
## 
##      AIC     AICc      BIC 
## 286.9602 293.4218 292.9346
MMdN <- ets(valid.ts,  model = "MMN")
MMdNfc <- forecast(MMdN, h = nValid, level = 0)
#Fit Model 3. 
shipments.ets.AAN.pred <- forecast(shipments.ets.AAN, h = nValid, level = c(0.2, 0.4, 0.6, 0.8)) 
#Accuracy AAN
accuracy(shipments.ets.AAN.pred, nValid)
##                        ME      RMSE       MAE           MPE         MAPE
## Training set     9.291158  219.3889  183.8221 -3.318428e-02 4.168075e+00
## Test set     -4622.039089 4622.0391 4622.0391 -1.155510e+05 1.155510e+05
##                    MASE        ACF1
## Training set  0.6962957 0.002451674
## Test set     17.5077238          NA
shipments.ets.MMN.pred <- forecast(shipments.ets.MMN, h = nValid, level = c(0.2, 0.4, 0.6, 0.8)) 
#Accuracy MMN
accuracy(shipments.ets.MMN.pred, nValid)
##                       ME      RMSE       MAE           MPE         MAPE
## Training set    32.87174  240.2824  211.2008  5.292109e-01 4.746086e+00
## Test set     -4779.84338 4779.8434 4779.8434 -1.194961e+05 1.194961e+05
##                    MASE      ACF1
## Training set  0.8000029 0.1258353
## Test set     18.1054674        NA
shipments.ets.MMdN.pred <- forecast(shipments.ets.MMdN, h = nValid, level = c(0.2, 0.4, 0.6, 0.8)) 
shipments.ets.MMdN.pred
##         Point Forecast    Lo 20    Hi 20    Lo 40    Hi 40    Lo 60
## 1990 Q1       4593.628 4534.654 4646.666 4478.961 4708.926 4407.844
## 1990 Q2       4599.058 4542.643 4652.771 4480.317 4709.938 4409.610
## 1990 Q3       4603.801 4547.746 4663.214 4488.329 4724.089 4417.389
## 1990 Q4       4607.946 4551.108 4658.680 4490.349 4720.409 4416.139
##            Hi 60    Lo 80    Hi 80
## 1990 Q1 4779.928 4313.730 4884.779
## 1990 Q2 4775.458 4316.073 4876.773
## 1990 Q3 4796.393 4313.576 4896.166
## 1990 Q4 4793.088 4325.578 4889.928
#Accuracy MMdN
accuracy(shipments.ets.MMdN.pred)
##                   ME     RMSE      MAE        MPE     MAPE      MASE
## Training set -3.6349 217.0341 177.1341 -0.3320249 4.032877 0.8303971
##                     ACF1
## Training set -0.01185158
par(mfrow = c(1, 3)) 
#This command sets the plot window to show 1 row of 3 plots.
plot(shipments.ets.AAN.pred, xlab = "Quarter", ylab = "shipments (in millions)", ylim = c(3900, 5000)) 
plot(shipments.ets.MMN.pred, xlab = "Quarter", ylab="shipments (in millions)", ylim = c(3900, 5000)) 
plot(shipments.ets.MMdN.pred, xlab = "Quarter", ylab="shipments (in millions)", ylim = c(3900, 5000))

fixed.nValid <- 4 
fixed.nTrain <- length(shipments.ts) - fixed.nValid 
stepsAhead <- 1 
error <- rep(0, fixed.nValid - stepsAhead + 1) 
percent.error <- rep(0, fixed.nValid - stepsAhead + 1) 

for(j in fixed.nTrain:(fixed.nTrain + fixed.nValid - stepsAhead)) { 
  train.ts <- window(shipments.ts, start = c(1985, 1), end = c(1985, j)) 
  valid.ts <- window(shipments.ts, start = c(1985, j + stepsAhead), end = c(1985, j + stepsAhead)) 
  naive.pred <- naive(train.ts, h = stepsAhead) 
  error[j - fixed.nTrain + 1] <- valid.ts - naive.pred$mean[stepsAhead] 
  percent.error[j - fixed.nTrain + 1] <- error[j - fixed.nTrain + 1]/ valid.ts 
  } 
mean(abs(error)) 
## [1] 258.75
sqrt(mean(error^2))
## [1] 364.3909
mean(abs(percent.error))
## [1] 0.0542274
fixed.nValid <- 4 
fixed.nTrain <- length(shipments.ts) - fixed.nValid 
train.ts <- window(shipments.ts, start = c(1985, 1), end = c(1985, fixed.nTrain)) 
valid.ts <- window(shipments.ts, start = c(1985, fixed.nTrain + 1), end = c(1985, fixed.nTrain + fixed.nValid)) 
naive.pred <- naive(train.ts, h = fixed.nValid)
snaive.pred <- snaive(train.ts, h = fixed.nValid) 
accuracy(naive.pred, valid.ts)
##                  ME     RMSE    MAE       MPE     MAPE     MASE       ACF1
## Training set  16.60 304.8922 265.40 0.1556967 6.077216 1.264311 -0.1617179
## Test set     307.75 385.6446 314.25 6.4985932 6.651715 1.497023 -0.4693744
##              Theil's U
## Training set        NA
## Test set      1.049607
accuracy(snaive.pred, valid.ts)
##                    ME     RMSE      MAE       MPE     MAPE     MASE
## Training set 130.9167 252.3287 209.9167 2.8592405 4.665890 1.000000
## Test set      48.5000 243.1820 223.5000 0.8867438 5.009241 1.064708
##                    ACF1 Theil's U
## Training set 0.08095064        NA
## Test set     0.05467639  0.436126

Quad Error

Quad <- hist(shipments.lm.pred$residuals, ylab = "Frequency", xlab = "Forecast Error", bty = "l", main ="", ylim = c(0,8))

# Use stored hist object to help set up density curve
multiplier <- Quad$counts / Quad$density
# Need to ignore NA from 1985
Quadmydensity <- density(shipments.lm.pred$residuals, na.rm=TRUE)
Quadmydensity$y <- Quadmydensity$y * multiplier[1]

# Add the density curve
lines(Quadmydensity)

AAN Error

AANhist <- hist(shipments.ets.AAN.pred$residuals, ylab = "Frequency", xlab = "Forecast Error", bty = "l", main ="")
# Use stored hist object to help set up density curve
multiplier <- AANhist$counts / AANhist$density
# Need to ignore NA from 1985
AANmydensity <- density(shipments.ets.AAN.pred$residuals, na.rm=TRUE)
AANmydensity$y <- AANmydensity$y * multiplier[1]

# Add the density curve
lines(AANmydensity)

MMN Error

MMNhist <- hist(shipments.ets.MMN.pred$residuals, ylab = "Frequency", xlab = "Forecast Error", bty = "l", main ="")

# Use stored hist object to help set up density curve
multiplier <- MMNhist$counts / MMNhist$density
# Need to ignore NA from 1985
MMNmydensity <- density(shipments.ets.MMN.pred$residuals, na.rm=TRUE)
MMNmydensity$y <- MMNmydensity$y * multiplier[1]

# Add the density curve
lines(MMNmydensity)

MMdN Error

MMdNhist <- hist(shipments.ets.MMdN.pred$residuals, ylab = "Frequency", xlab = "Forecast Error", bty = "l", main ="")
# Use stored hist object to help set up density curve
multiplier <- MMdNhist$counts / MMdNhist$density
# Need to ignore NA from 1985
MMdNmydensity <- density(shipments.ets.MMdN.pred$residuals, na.rm=TRUE)
MMdNmydensity$y <- AANmydensity$y * multiplier[1]

# Add the density curve
lines(MMdNmydensity)

Naive Error

Naivehist <-  hist(naive.pred$residuals, ylab = "Frequency", xlab = "Forecast Error", bty = "l", main ="")
multiplier <- Naivehist$counts / Naivehist$density
# Need to ignore NA from 1985
Naivemydensity <- density(naive.pred$residuals, na.rm=TRUE)
Naivemydensity$y <- Naivemydensity$y * multiplier[1]

# Add the density curve
lines(Naivemydensity)

SNaive Error

SNaivehist <- hist(snaive.pred$residuals, ylab = "Frequency", xlab = "Forecast Error", bty = "l", main ="")
multiplier <- SNaivehist$counts / SNaivehist$density
SNaivemydensity <- density(snaive.pred$residuals, na.rm=TRUE)
SNaivemydensity$y <- SNaivemydensity$y * multiplier[1]
lines(SNaivemydensity)

Qu1 <- mean(4245, 4258, 4595, 4409.468)
Qu2 <- mean(4900, 4258, 4799, 4355.434)
Qu3 <- mean(4585, 4258, 4417, 4291.984)
Qu4 <- mean(4533,4258,4258,4219.148)
Qu1
## [1] 4245
Qu2
## [1] 4900
Qu3
## [1] 4585
Qu4
## [1] 4533
Combined <- c(4245,4990, 4585, 4533)
Combined.ts <- ts(Combined, start = c(1989,1), end = c(1989, 4), freq = 4)
plot(valid.ts, bty="l", xaxt="n", xlab="The Year 1989", yaxt="n", ylab="Shipments", ylim = c(4000, 8000))
axis(1, at=seq(1989,1989.75,0.25), labels=c("Quarter 1", "Quarter 2", "Quarter 3", "Quarter 4"))
axis(2, las=2)
# Now add the forecasts and make the line red and dashed
lines(naive.pred$mean, col=2, lty=1)
# Add a legend
lines(snaive.pred$mean, col=3, lty=1)
lines(shipments.lm.pred$mean, col = 4, lty = 1)
lines(Combined.ts, col = 6, lty = 2)

# Add a legend
legend(1989,8000, c("Actual","Naive", "SNaive", "Quad Trend", "Combined"), col=1:6, lty=1:5)

Four Forecasts

head(valid.ts)
## [1] 4245 4900 4585 4533
head(naive.pred$mean)
## [1] 4258 4258 4258 4258
head(snaive.pred$mean)
## [1] 4595 4799 4417 4258
head(shipments.lm.pred$mean)
##        1        2        3        4 
## 4409.468 4355.424 4291.984 4219.148