Introduction

Source: https://archive.ics.uci.edu/dataset/352/online+retail he dataset I’m using in this analysis is from an online retail store. It contains information about transactions made over a certain period.

Data Prep

library(readxl)
## Warning: package 'readxl' was built under R version 4.3.3
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(tsibble)
## Warning: package 'tsibble' was built under R version 4.3.3
## 
## Attaching package: 'tsibble'
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, union
# Load dataset
retail_data <- read_excel("C:\\Users\\yinan\\Downloads\\RetailData\\OnlineRetail.xlsx")

# Preprocess dataset
retail_data_summary <- retail_data %>%
  filter(!is.na(InvoiceDate), InvoiceDate >= as.Date("2010-12-01"), InvoiceDate <= as.Date("2011-12-09")) %>%
  mutate(InvoiceDate = as.Date(InvoiceDate)) %>%
  group_by(InvoiceDate) %>%
  summarise(TotalSales = sum(Quantity * UnitPrice, na.rm = TRUE))

# Plot the time series
ggplot(retail_data_summary, aes(x = InvoiceDate, y = TotalSales)) +
  geom_line() +
  scale_x_date(date_breaks = "1 month", date_labels = "%b %Y") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Model Fitting

library(forecast)
## Warning: package 'forecast' was built under R version 4.3.3
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
#convert the preprocessed data into a time series object
retail_data_ts <- retail_data_summary %>%
  as_tsibble(index = InvoiceDate) %>%
  fill_gaps(TotalSales = 0) %>%
  as.ts()

#Fit an ARIMA model
model_arima <- auto.arima(retail_data_ts)
autoplot(model_arima) +
  ggtitle("Fitted ARIMA Model") +
  xlab("Time") + ylab("Total Sales")

# Fit an ETS model
model_ets <- ets(retail_data_ts)

# Forecast from the fitted model
fcast <- forecast(model_ets)

fitted_values <- forecast(model_ets)

# Create a sequence of dates for the fitted values
fitted_dates <- seq(from = min(retail_data_summary$InvoiceDate),
                     by = "day",
                     length.out = length(fitted_values$fitted))

# Create a data frame for plotting
plot_data <- data.frame(
  Date = fitted_dates,
  Fitted = fitted_values$fitted
 )

# Plot the fitted values
ggplot(plot_data, aes(x = Date, y = Fitted)) +
   geom_line() +
   ggtitle("Fitted ETS Model") +
   xlab("Time") + ylab("Total Sales") +
   scale_x_date(date_breaks = "1 month", date_labels = "%b %Y") +
   theme(axis.text.x = element_text(angle = 90, hjust = 1))
## Don't know how to automatically pick scale for object of type <ts>. Defaulting
## to continuous.

Forcasting

arima_forecast <- forecast(model_arima, h = 6)
ets_forecast <- forecast(model_ets, h = 6)
autoplot(arima_forecast)

autoplot(ets_forecast)

Summary

summary(ets_forecast)
## 
## Forecast method: ETS(A,N,A)
## 
## Model Information:
## ETS(A,N,A) 
## 
## Call:
##  ets(y = retail_data_ts) 
## 
##   Smoothing parameters:
##     alpha = 0.185 
##     gamma = 0.1323 
## 
##   Initial states:
##     l = 37882.3035 
##     s = 11341.6 4114.578 -10562.54 -23965.11 2852.045 12762.76
##            3456.657
## 
##   sigma:  12286.38
## 
##      AIC     AICc      BIC 
## 9244.158 9244.766 9283.374 
## 
## Error measures:
##                    ME     RMSE     MAE MPE MAPE      MASE       ACF1
## Training set 188.8708 12137.25 8713.06 NaN  Inf 0.8529662 0.04252437
## 
## Forecasts:
##          Point Forecast     Lo 80    Hi 80     Lo 95    Hi 95
## 2064.201       57049.91 41304.283 72795.54  32969.05 81130.77
## 2064.344       11340.03 -4672.701 27352.77 -13149.33 35829.40
## 2064.486       37495.27 21219.808 53770.73  12604.10 62386.43
## 2064.629       65393.51 48859.500 81927.52  40106.92 90680.09
## 2064.772       62982.89 46194.314 79771.47  37306.98 88658.81
## 2064.915       65088.27 48048.923 82127.61  39028.84 91147.69
summary(arima_forecast)
## 
## Forecast method: ARIMA(1,0,1)(2,1,1)[7] with drift
## 
## Model Information:
## Series: retail_data_ts 
## ARIMA(1,0,1)(2,1,1)[7] with drift 
## 
## Coefficients:
##          ar1      ma1    sar1     sar2     sma1    drift
##       0.8868  -0.6780  0.1289  -0.0428  -0.8555  59.3972
## s.e.  0.0537   0.0772  0.0661   0.0610   0.0416  45.1940
## 
## sigma^2 = 147706660:  log likelihood = -3962.57
## AIC=7939.14   AICc=7939.45   BIC=7966.46
## 
## Error measures:
##                     ME    RMSE      MAE MPE MAPE      MASE       ACF1
## Training set -385.4325 11939.8 8414.175 NaN  Inf 0.8237069 0.01406858
## 
## Forecasts:
##          Point Forecast     Lo 80    Hi 80      Lo 95    Hi 95
## 2064.201       58609.14 43033.851 74184.43  34788.791 82429.49
## 2064.344       10225.56 -5685.537 26136.66 -14108.365 34559.49
## 2064.486       34597.94 18427.644 50768.23   9867.608 59328.27
## 2064.629       62436.34 46065.097 78807.59  37398.683 87474.00
## 2064.772       59043.18 42515.620 75570.75  33766.456 84319.91
## 2064.915       64709.16 48059.692 81358.62  39245.999 90172.31
arima_accuracy <- accuracy(arima_forecast, lambda = NULL)
ets_accuracy <- accuracy(ets_forecast, lambda = NULL)
arima_accuracy
##                     ME    RMSE      MAE MPE MAPE      MASE       ACF1
## Training set -385.4325 11939.8 8414.175 NaN  Inf 0.8237069 0.01406858
arima_accuracy
##                     ME    RMSE      MAE MPE MAPE      MASE       ACF1
## Training set -385.4325 11939.8 8414.175 NaN  Inf 0.8237069 0.01406858

Conclusion

Based on these measures, the ARIMA model seems to have slightly better performance compared to the ETS model in terms of MAE, RMSE, and MASE. However, both models have an MPE of NaN.I don’t have separate test data and are calculating the MPE using the same data that I used to fit the model, therefore this could be the reason for the MPE being NaN.