library(fpp3)
## Warning: package 'fpp3' was built under R version 4.5.3
## ── Attaching packages ──────────────────────────────────────────── fpp3 1.0.3 ──
## ✔ tibble      3.3.1     ✔ tsibble     1.2.0
## ✔ dplyr       1.1.4     ✔ tsibbledata 0.4.1
## ✔ tidyr       1.3.2     ✔ ggtime      0.2.0
## ✔ lubridate   1.9.4     ✔ feasts      0.5.0
## ✔ ggplot2     4.0.2     ✔ fable       0.5.0
## Warning: package 'tibble' was built under R version 4.5.2
## Warning: package 'tidyr' was built under R version 4.5.2
## Warning: package 'ggplot2' was built under R version 4.5.2
## Warning: package 'tsibble' was built under R version 4.5.3
## Warning: package 'tsibbledata' was built under R version 4.5.3
## Warning: package 'ggtime' was built under R version 4.5.3
## Warning: package 'feasts' was built under R version 4.5.3
## Warning: package 'fabletools' was built under R version 4.5.3
## Warning: package 'fable' was built under R version 4.5.3
## ── 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()

Load Data

data <- vic_elec

Convert valeus to dailt

vic_monthly <- vic_elec %>%
  index_by(Month = yearmonth(Time)) %>%
  summarise(Demand = mean(Demand))

vic_monthly
## # A tsibble: 36 x 2 [1M]
##       Month Demand
##       <mth>  <dbl>
##  1 2012 Jan  4866.
##  2 2012 Feb  4939.
##  3 2012 Mar  4534.
##  4 2012 Apr  4439.
##  5 2012 May  4956.
##  6 2012 Jun  5131.
##  7 2012 Jul  5086.
##  8 2012 Aug  5035.
##  9 2012 Sep  4561.
## 10 2012 Oct  4496.
## # ℹ 26 more rows

Plot Data

vic_monthly %>%
  autoplot(Demand) +
  labs(
    title = "Monthly Average Electricity Demand in Victoria",
    x = "Month",
    y = "Average Monthly Demand"
  )

Train/Test

train <- vic_monthly %>%
  filter(Month <= yearmonth("2013 Dec"))
test <- vic_monthly %>%
  filter(Month > yearmonth("2013 Dec"))
train
## # A tsibble: 24 x 2 [1M]
##       Month Demand
##       <mth>  <dbl>
##  1 2012 Jan  4866.
##  2 2012 Feb  4939.
##  3 2012 Mar  4534.
##  4 2012 Apr  4439.
##  5 2012 May  4956.
##  6 2012 Jun  5131.
##  7 2012 Jul  5086.
##  8 2012 Aug  5035.
##  9 2012 Sep  4561.
## 10 2012 Oct  4496.
## # ℹ 14 more rows
test
## # A tsibble: 12 x 2 [1M]
##       Month Demand
##       <mth>  <dbl>
##  1 2014 Jan  4825.
##  2 2014 Feb  4816.
##  3 2014 Mar  4398.
##  4 2014 Apr  4357.
##  5 2014 May  4572.
##  6 2014 Jun  4804.
##  7 2014 Jul  5090.
##  8 2014 Aug  4891.
##  9 2014 Sep  4516.
## 10 2014 Oct  4412.
## 11 2014 Nov  4324.
## 12 2014 Dec  4320.

Fit the models

fit <- train %>%
  model(
    SES = ETS(Demand ~ error("A") + trend("N") + season("N")),
    Holt = ETS(Demand ~ error("A") + trend("A") + season("N")),
    Holt_Winters = ETS(Demand ~ error("A") + trend("A") + season("A"))
  )

fit
## # A mable: 1 x 3
##            SES         Holt Holt_Winters
##        <model>      <model>      <model>
## 1 <ETS(A,N,N)> <ETS(A,A,N)> <ETS(A,A,A)>

View Model

report(fit)
## Warning in report.mdl_df(fit): Model reporting is only supported for individual
## models, so a glance will be shown. To see the report for a specific model, use
## `select()` and `filter()` to identify a single model.
## # A tibble: 3 × 9
##   .model       sigma2 log_lik   AIC  AICc   BIC    MSE    AMSE   MAE
##   <chr>         <dbl>   <dbl> <dbl> <dbl> <dbl>  <dbl>   <dbl> <dbl>
## 1 SES          65080.   -170.  346.  347.  350. 59657. 123252. 184. 
## 2 Holt         72308.   -170.  350.  354.  356. 60257.  62780. 226. 
## 3 Holt_Winters 16317.   -141.  317.  419.  337.  5439.   5272.  50.8

Forecast into the test period

fc <- fit %>%
  forecast(h = nrow(test))

fc
## # A fable: 36 x 4 [1M]
## # Key:     .model [3]
##    .model    Month
##    <chr>     <mth>
##  1 SES    2014 Jan
##  2 SES    2014 Feb
##  3 SES    2014 Mar
##  4 SES    2014 Apr
##  5 SES    2014 May
##  6 SES    2014 Jun
##  7 SES    2014 Jul
##  8 SES    2014 Aug
##  9 SES    2014 Sep
## 10 SES    2014 Oct
## # ℹ 26 more rows
## # ℹ 2 more variables: Demand <dist>, .mean <dbl>

Plot forecasts against the full dataset

fc %>%
  autoplot(vic_monthly, level = NULL) +
  labs(
    title = "Exponential Smoothing Forecasts for Electricity Demand",
    x = "Month",
    y = "Average Monthly Demand"
  )

accuracy(fc, test)
## # A tibble: 3 × 10
##   .model       .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE   ACF1
##   <chr>        <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
## 1 Holt         Test   165.  290.  220.  3.32  4.57   NaN   NaN 0.550 
## 2 Holt_Winters Test   103.  172.  154.  2.23  3.33   NaN   NaN 0.0792
## 3 SES          Test   303.  394.  303.  6.30  6.30   NaN   NaN 0.548

View params

tidy(fit)
## # A tibble: 23 × 3
##    .model       term     estimate
##    <chr>        <chr>       <dbl>
##  1 SES          alpha    1.000   
##  2 SES          l[0]  4866.      
##  3 Holt         alpha    0.000100
##  4 Holt         beta     0.000100
##  5 Holt         l[0]  4860.      
##  6 Holt         b[0]   -13.6     
##  7 Holt_Winters alpha    0.000151
##  8 Holt_Winters beta     0.000100
##  9 Holt_Winters gamma    0.000102
## 10 Holt_Winters l[0]  4848.      
## # ℹ 13 more rows
  1. For this discussion, I used the vic_elec dataset from the fpp3 package. I changed the averaege electricity demand so it would be easier to graph and forecast. The monthly demand graph showcases that electricity demand changed throughout the year instead of staying flat. There was a repeated up and down pattern which means there was a case of seasonality. this is important because some forecast models can handle seasonality better than other models. I tested the three models, SES was the simplest model because it only looked at the level of the data. Because of this, its forecast was mostly flat. Holt’s model was better because it included trend, but it still did not fully capture the seasonal pattern. Holt-Winters worked the best because it included level, trend, and seasonality.The forecast graph showed that Holt-Winters followed the actual data more closely than the other two models. SES stayed mostly flat, Holt showed more movement, and Holt-Winters did the best job matching the seasonal changes.

2)I compared the models using RMSE, MAE, and MAPE. Lower numbers mean the model made smaller forecasting errors.The accuracy table showed that Holt-Winters had the lowest RMSE, MAE, and MAPE. This means it was the most accurate model. SES had the highest errors because it did not account for trend or seasonality. Holt was better than SES because it included trend, but it was still worse than Holt-Winters because it did not include seasonality.

  1. Lets assume a scenario such as the current climate of data centers and their mass production. Exponential smoothing models can adjust over time, but they may not react fast enough to sudden shocks. If the data became more irregular, the forecast could be improved by using a shorter training period or adding other variables, such as temperature.For datasets with irregular patterns, forecasts could be improved in a few ways. One option is to use a shorter training period so the model focuses more on recent behavior instead of older patterns that may no longer apply. Another option is to add outside variables, such as temperature, holidays, or economic conditions, because these factors may explain sudden changes in electricity demand.