Demanda de energía en Victoria, Australia

Las paqueterías necesarias para el análisis:

library(tidyverse)
library(tsibble)
library(feasts)
library(fable)
library(tsibbledata)
library(fpp3)
library(patchwork)

library(timetk) # manejo de series de tiempo modeltime

1 Pre-procesamiento de los datos

Los datos tienen una periodicidad de cada media hora. Nos interesa tenerlos por hora.

vic_elec
# A tsibble: 52,608 x 5 [30m] <Australia/Melbourne>
   Time                Demand Temperature Date       Holiday
   <dttm>               <dbl>       <dbl> <date>     <lgl>  
 1 2012-01-01 00:00:00  4383.        21.4 2012-01-01 TRUE   
 2 2012-01-01 00:30:00  4263.        21.0 2012-01-01 TRUE   
 3 2012-01-01 01:00:00  4049.        20.7 2012-01-01 TRUE   
 4 2012-01-01 01:30:00  3878.        20.6 2012-01-01 TRUE   
 5 2012-01-01 02:00:00  4036.        20.4 2012-01-01 TRUE   
 6 2012-01-01 02:30:00  3866.        20.2 2012-01-01 TRUE   
 7 2012-01-01 03:00:00  3694.        20.1 2012-01-01 TRUE   
 8 2012-01-01 03:30:00  3562.        19.6 2012-01-01 TRUE   
 9 2012-01-01 04:00:00  3433.        19.1 2012-01-01 TRUE   
10 2012-01-01 04:30:00  3359.        19.0 2012-01-01 TRUE   
# … with 52,598 more rows

Con el tidyverts, podemos utilizar index_by() y summarise():

vic_elec_hourly <- vic_elec %>% 
  index_by(hora = ~ floor_date(., "hour")) %>% 
  summarise(
    Demand = sum(Demand),
    Temperature = mean(Temperature),
    Holiday = mean(Holiday)
  )

vic_elec_hourly
# A tsibble: 26,304 x 4 [1h] <Australia/Melbourne>
   hora                Demand Temperature Holiday
   <dttm>               <dbl>       <dbl>   <dbl>
 1 2012-01-01 00:00:00  8646.        21.2       1
 2 2012-01-01 01:00:00  7927.        20.6       1
 3 2012-01-01 02:00:00  7902.        20.3       1
 4 2012-01-01 03:00:00  7256.        19.8       1
 5 2012-01-01 04:00:00  6793.        19.0       1
 6 2012-01-01 05:00:00  6636.        18.7       1
 7 2012-01-01 06:00:00  6548.        18.7       1
 8 2012-01-01 07:00:00  6865.        19.6       1
 9 2012-01-01 08:00:00  7300.        21.8       1
10 2012-01-01 09:00:00  8002.        24.6       1
# … with 26,294 more rows

Haciendo esto mismo, pero con la paquetería timetk, tendríamos primero que convertir los datos a una tibble, y posteriormente podríamos utilizar la función summarise_by_time()

vic_elec %>% 
  as_tibble() %>% 
  summarise_by_time(
    .date_var = Time,
    .by = "hour",
    Demand = sum(Demand),
    Temperature = mean(Temperature)
  ) %>% 
  as_tsibble(index = Time)
# A tsibble: 26,304 x 3 [1h] <Australia/Melbourne>
   Time                Demand Temperature
   <dttm>               <dbl>       <dbl>
 1 2012-01-01 00:00:00  8646.        21.2
 2 2012-01-01 01:00:00  7927.        20.6
 3 2012-01-01 02:00:00  7902.        20.3
 4 2012-01-01 03:00:00  7256.        19.8
 5 2012-01-01 04:00:00  6793.        19.0
 6 2012-01-01 05:00:00  6636.        18.7
 7 2012-01-01 06:00:00  6548.        18.7
 8 2012-01-01 07:00:00  6865.        19.6
 9 2012-01-01 08:00:00  7300.        21.8
10 2012-01-01 09:00:00  8002.        24.6
# … with 26,294 more rows

2 Análisis exploratorio

p <- vic_elec_hourly %>% 
  autoplot(Demand)

plotly::ggplotly(p)

Al observar la gráfica, parece exhibir tres tipos de estacionalidad:

  • Anual
  • Semanal
  • Diaria
s_y <- vic_elec_hourly %>% 
  gg_season(Demand, period = "year")
s_w <- vic_elec_hourly %>% 
  gg_season(Demand, period = "week")
s_d <- vic_elec_hourly %>% 
  gg_season(Demand, period = "day")

s_y / s_w / s_d

s_y / (s_w | s_d)

3 Descomposición STL

Realizamos una descomposición STL de la serie:

comp_stl <- vic_elec_hourly %>% 
  model(
    STL(Demand, robust = TRUE)
  ) %>% 
  components() 

comp_stl %>% 
  autoplot()

comp_stl %>% 
  autoplot(season_year)

comp_stl %>% 
  autoplot(season_week)

comp_stl %>% 
  autoplot(season_day)

comp_stl %>% 
  ggplot(aes(x = hora, y = season_adjust)) +
  geom_line()

4 Flujo de pronóstico

4.1 Conjuntos de entrenamiento y prueba

vic_train <- vic_elec_hourly %>% 
  filter_index(. ~ "2014-09-30")

vic_test <- vic_elec_hourly %>% 
  filter_index("2014-10-01"~.)

4.2 Modelado

4.2.1 Suavización exponencial

Ajustamos un Holt-Winters aditivo y con tendencia amortiguada:

fit1 <- vic_train %>% 
  model(ets = ETS(Demand ~ error("A") + trend("Ad") + season("A")))

report(fit1)
Series: Demand 
Model: ETS(A,Ad,A) 
  Smoothing parameters:
    alpha = 0.8429999 
    beta  = 0.0005046006 
    gamma = 0.156982 
    phi   = 0.9795556 

  Initial states:
     l[0]     b[0]      s[0]     s[-1]   s[-2]    s[-3]    s[-4]    s[-5]
 8643.489 82.40267 -642.5048 -73.45193 680.717 1153.295 1486.505 1405.408
    s[-6]   s[-7]    s[-8]    s[-9]   s[-10]   s[-11]   s[-12]   s[-13]
 1099.634 987.357 842.7851 802.8814 767.5777 790.5029 828.9911 866.8354
   s[-14]   s[-15]    s[-16]    s[-17]    s[-18]    s[-19]    s[-20]    s[-21]
 752.8551 270.4595 -464.1822 -1644.818 -2270.221 -2366.422 -2091.133 -1542.735
    s[-22]    s[-23]
 -1132.932 -507.4028

  sigma^2:  80822.89

     AIC     AICc      BIC 
515462.4 515462.5 515705.1 
p <- vic_train %>% 
  autoplot(Demand) +
  geom_line(aes(y = .fitted), data = fit1 %>% augment(), color = "firebrick")

plotly::ggplotly(p)

Las métricas de error en el entrenamiento:

accuracy(fit1) %>% 
  select(.model, .type, RMSE, MAE, MAPE, MASE)
# A tibble: 1 × 6
  .model .type     RMSE   MAE  MAPE  MASE
  <chr>  <chr>    <dbl> <dbl> <dbl> <dbl>
1 ets    Training  284.  210.  2.32 0.282

Los pronósticos a tres meses.

fc1 <- fit1 %>% 
  forecast(h = "3 months")

fc1 %>% 
  autoplot(vic_elec_hourly %>% filter_index("2014-10-01"~.), level = NULL)

fc1 %>% 
  accuracy(vic_elec_hourly)
# A tibble: 1 × 10
  .model .type    ME  RMSE   MAE    MPE  MAPE  MASE RMSSE  ACF1
  <chr>  <chr> <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>
1 ets    Test   41.1 1137.  949. -0.847  10.8  1.27 0.985 0.943

El diagnóstico de residuos:

fit1 %>% 
  gg_tsresiduals()

Dado que los periodos estacionales de esta serie son:

  • Anual: 8760
  • Semanal: 168
  • Diaria: 24

No podemos modelar la estacionalidad a partir de ETS, ya que permite máximo periodos estacionales = 24.

4.2.2 Pronóstico con descomposición y ETS

Vamos a hacer un modelo de descomposición, modelando con SNAIVE las estacionalidades, y con ETS la serie desestacionalizada.

fit2 <- vic_train %>% 
  model(
    dcmp = decomposition_model(
      STL(Demand, robust = TRUE),
      ETS(season_adjust ~ error("A") + trend("Ad") + season("N"))
    )
  )

fit2 %>% report()
Series: Demand 
Model: STL decomposition model 
Combination: season_adjust + season_year + season_week + season_day

===================================================================

Series: season_adjust + season_year + season_week 
Model: COMBINATION 
Combination: season_adjust + season_year + season_week

======================================================

Series: season_adjust + season_year 
Model: COMBINATION 
Combination: season_adjust + season_year

========================================

Series: season_adjust 
Model: ETS(A,Ad,N) 
  Smoothing parameters:
    alpha = 0.9490909 
    beta  = 0.0001000419 
    phi   = 0.8390464 

  Initial states:
     l[0]     b[0]
 10495.53 114.8676

  sigma^2:  84379.73

     AIC     AICc      BIC 
516476.2 516476.2 516524.7 

Series: season_year 
Model: SNAIVE 

sigma^2: 150953.5072 


Series: season_week 
Model: SNAIVE 

sigma^2: 571.2532 


Series: season_day 
Model: SNAIVE 

sigma^2: 2131.6242 
accuracy(fit2)
# A tibble: 1 × 10
  .model .type       ME  RMSE   MAE     MPE  MAPE  MASE RMSSE  ACF1
  <chr>  <chr>    <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl> <dbl>
1 dcmp   Training  3.48  470.  167. -0.0777  1.73 0.224 0.407 0.623
fc2 <- fit2 %>% 
  forecast(h = "3 months")

fc2 %>% 
  autoplot(vic_elec_hourly %>% filter_index("2014-10-01"~.), level = NULL)

fc2 %>% 
  accuracy(vic_elec_hourly)
# A tibble: 1 × 10
  .model .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
  <chr>  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 dcmp   Test   192.  995.  700.  1.95  8.02 0.938 0.862 0.896
fit2 %>% 
  gg_tsresiduals()
Warning: Removed 8766 row(s) containing missing values (geom_path).
Warning: Removed 8766 rows containing missing values (geom_point).
Warning: Removed 8766 rows containing non-finite values (stat_bin).

4.2.3 Regresión armónica dinámica

tictoc::tic()
fit3 <- vic_train %>% 
  model(
    harmonic = ARIMA(Demand ~ fourier(period = "year", K = 5) +
                       fourier(period = "week", K = 3) +
                       fourier(period = "day", K = 3) + pdq(2,0,2) + PDQ(0,0,0))
  )
tictoc::toc()
34.35 sec elapsed
report(fit3)
Series: Demand 
Model: LM w/ ARIMA(2,0,2) errors 

Coefficients:
         ar1      ar2     ma1     ma2  fourier(period = "year", K = 5)C1_8766
      0.8709  -0.0137  0.4393  0.1211                               -372.1854
s.e.  0.0359   0.0319  0.0353  0.0161                                 35.1763
      fourier(period = "year", K = 5)S1_8766
                                    132.2054
s.e.                                 35.2763
      fourier(period = "year", K = 5)C2_8766
                                    375.1088
s.e.                                 35.1598
      fourier(period = "year", K = 5)S2_8766
                                    322.8801
s.e.                                 35.2795
      fourier(period = "year", K = 5)C3_8766
                                   -178.5210
s.e.                                 35.1378
      fourier(period = "year", K = 5)S3_8766
                                    122.8226
s.e.                                 35.2509
      fourier(period = "year", K = 5)C4_8766
                                   -192.5261
s.e.                                 35.0181
      fourier(period = "year", K = 5)S4_8766
                                     59.3766
s.e.                                 35.2105
      fourier(period = "year", K = 5)C5_8766
                                    -41.3890
s.e.                                 34.9357
      fourier(period = "year", K = 5)S5_8766
                                     -3.1212
s.e.                                 35.0062
      fourier(period = "week", K = 3)C1_168
                                   592.4026
s.e.                                33.7797
      fourier(period = "week", K = 3)S1_168
                                  -520.2649
s.e.                                33.7890
      fourier(period = "week", K = 3)C2_168
                                   -24.7762
s.e.                                31.3337
      fourier(period = "week", K = 3)S2_168
                                   455.9899
s.e.                                31.3294
      fourier(period = "week", K = 3)C3_168
                                   -43.9442
s.e.                                28.2006
      fourier(period = "week", K = 3)S3_168
                                  -103.9370
s.e.                                28.1992
      fourier(period = "day", K = 3)C1_24  fourier(period = "day", K = 3)S1_24
                                 562.4180                            1408.5068
s.e.                              17.6527                              17.6545
      fourier(period = "day", K = 3)C2_24  fourier(period = "day", K = 3)S2_24
                                 380.9742                            -543.3201
s.e.                               9.5259                               9.5264
      fourier(period = "day", K = 3)C3_24  fourier(period = "day", K = 3)S3_24
                                  69.9436                            -296.9114
s.e.                               6.1454                               6.1454
      intercept
      9341.1353
s.e.    24.9025

sigma^2 estimated as 122038:  log likelihood=-175292.9
AIC=350641.9   AICc=350641.9   BIC=350868.4
p <- vic_train %>% 
  autoplot(Demand) +
  geom_line(aes(y = .fitted), data = fit3 %>% augment(), color = "firebrick")

plotly::ggplotly(p)
fc3 <- fit3 %>% 
  forecast(h = "3 months")

fc3 %>% 
  autoplot(vic_elec_hourly %>% filter_index("2014-10-01"~.), level = NULL)

fc3 %>% 
  autoplot(vic_elec_hourly %>% filter_index("2014-10-01"~.))

fc3 %>% 
  accuracy(vic_elec_hourly)
# A tibble: 1 × 10
  .model   .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
  <chr>    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 harmonic Test  -111.  880.  673. -1.65  7.90 0.902 0.762 0.908

4.2.4 Regresión armónica + predictoras exógenas

tictoc::tic()
fit4 <- vic_train %>% 
  model(
    harmonic = ARIMA(Demand ~ Temperature + I(Temperature^2) + fourier(period = "year", K = 7) +
                       fourier(period = "week", K = 5) +
                       fourier(period = "day", K = 4) + PDQ(0,0,0) + pdq(2,0,2))
  )
tictoc::toc()
113 sec elapsed
report(fit4)
Series: Demand 
Model: LM w/ ARIMA(2,0,2) errors 

Coefficients:
         ar1      ar2      ma1      ma2  Temperature  I(Temperature^2)
      1.5044  -0.5668  -0.3417  -0.1170    -279.5698            7.5088
s.e.  0.0372   0.0321   0.0379   0.0139       7.7654            0.1837
      fourier(period = "year", K = 7)C1_8766
                                   -286.9762
s.e.                                 29.0917
      fourier(period = "year", K = 7)S1_8766
                                    161.6119
s.e.                                 26.0699
      fourier(period = "year", K = 7)C2_8766
                                    278.0314
s.e.                                 25.4613
      fourier(period = "year", K = 7)S2_8766
                                    265.3362
s.e.                                 25.5440
      fourier(period = "year", K = 7)C3_8766
                                   -147.4291
s.e.                                 25.3447
      fourier(period = "year", K = 7)S3_8766
                                    106.8796
s.e.                                 25.4146
      fourier(period = "year", K = 7)C4_8766
                                   -200.4560
s.e.                                 25.3352
      fourier(period = "year", K = 7)S4_8766
                                     29.0285
s.e.                                 25.4230
      fourier(period = "year", K = 7)C5_8766
                                    -58.3848
s.e.                                 25.3064
      fourier(period = "year", K = 7)S5_8766
                                    -12.5391
s.e.                                 25.3883
      fourier(period = "year", K = 7)C6_8766
                                    -92.0476
s.e.                                 25.2398
      fourier(period = "year", K = 7)S6_8766
                                     23.1517
s.e.                                 25.3465
      fourier(period = "year", K = 7)C7_8766
                                   -113.5976
s.e.                                 25.1573
      fourier(period = "year", K = 7)S7_8766
                                     68.9044
s.e.                                 25.2367
      fourier(period = "week", K = 5)C1_168
                                   585.2528
s.e.                                24.6627
      fourier(period = "week", K = 5)S1_168
                                  -525.6332
s.e.                                24.6747
      fourier(period = "week", K = 5)C2_168
                                   -35.4893
s.e.                                23.6637
      fourier(period = "week", K = 5)S2_168
                                   451.2795
s.e.                                23.6651
      fourier(period = "week", K = 5)C3_168
                                   -48.3112
s.e.                                22.1794
      fourier(period = "week", K = 5)S3_168
                                  -111.9848
s.e.                                22.1797
      fourier(period = "week", K = 5)C4_168
                                   -82.5628
s.e.                                20.4075
      fourier(period = "week", K = 5)S4_168
                                    88.5390
s.e.                                20.4108
      fourier(period = "week", K = 5)C5_168
                                    97.4267
s.e.                                18.5450
      fourier(period = "week", K = 5)S5_168
                                  -214.5934
s.e.                                18.5468
      fourier(period = "day", K = 4)C1_24  fourier(period = "day", K = 4)S1_24
                                 553.8125                            1465.3068
s.e.                              15.2370                              17.5365
      fourier(period = "day", K = 4)C2_24  fourier(period = "day", K = 4)S2_24
                                 419.3109                            -534.7655
s.e.                               7.7587                               7.9637
      fourier(period = "day", K = 4)C3_24  fourier(period = "day", K = 4)S3_24
                                  81.8289                            -291.6448
s.e.                               4.8385                               4.8306
      fourier(period = "day", K = 4)C4_24  fourier(period = "day", K = 4)S4_24
                                -188.4723                             100.2865
s.e.                               3.4588                               3.4473
       intercept
      11659.4246
s.e.     80.2433

sigma^2 estimated as 100188:  log likelihood=-172909.7
AIC=345899.4   AICc=345899.5   BIC=346223
fc4 <- fit4 %>% 
  forecast(new_data = vic_elec_hourly %>% filter_index("2014-10-01"~.))

fc4 %>% 
  autoplot(vic_elec_hourly %>% filter_index("2014-10-01"~.), level = NULL)

fc4 %>% 
  autoplot(vic_elec_hourly %>% filter_index("2014-10-01"~.))

fc4 %>% 
  accuracy(vic_elec_hourly)
# A tibble: 1 × 10
  .model   .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
  <chr>    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 harmonic Test  -88.7  772.  597. -1.18  7.09 0.800 0.668 0.903

4.3 Combinación de modelos

Unimos los modelos estimados anteriormente en una sola mable (tabla de modelos) y creamos un modelo combinado a partir de los modelos anteriores:

fit <- fit1 %>% 
  mutate(
    dcmp = fit2$dcmp,
    harmonic = fit3$harmonic,
    harmonic_temp = fit4$harmonic,
    combinado1 = (ets + dcmp + harmonic + harmonic_temp)/4
  )

fit
# A mable: 1 x 5
            ets                      dcmp                    harmonic
        <model>                   <model>                     <model>
1 <ETS(A,Ad,A)> <STL decomposition model> <LM w/ ARIMA(2,0,2) errors>
# … with 2 more variables: harmonic_temp <model>, combinado1 <model>
accuracy(fit) %>% arrange(MAPE)
# A tibble: 5 × 10
  .model        .type          ME  RMSE   MAE     MPE  MAPE  MASE RMSSE     ACF1
  <chr>         <chr>       <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl>    <dbl>
1 dcmp          Training  3.48     470.  167. -0.0777  1.73 0.224 0.407  6.23e-1
2 combinado1    Training -3.12     244.  172. -0.144   1.85 0.231 0.211  3.87e-1
3 ets           Training -0.186    284.  210. -0.0556  2.32 0.282 0.246  7.68e-1
4 harmonic_temp Training -0.00195  316.  238. -0.120   2.61 0.319 0.274 -2.04e-3
5 harmonic      Training  0.00939  349.  262. -0.135   2.83 0.352 0.302  9.99e-5
fc <- fit %>% 
  forecast(new_data = vic_test)

p <-  
  ggplot()+
  geom_line(data = vic_test, aes(x = hora, y = Demand)) + 
  geom_line(data = fc, aes(x = hora, y = .mean, color = .model))

plotly::ggplotly(p)
fc %>% 
  accuracy(vic_elec_hourly) %>% arrange(MAPE)
# A tibble: 5 × 10
  .model        .type      ME  RMSE   MAE    MPE  MAPE  MASE RMSSE  ACF1
  <chr>         <chr>   <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>
1 combinado1    Test     2.12  768.  578. -0.507  6.58 0.775 0.665 0.911
2 harmonic_temp Test   -88.7   772.  597. -1.18   7.09 0.800 0.668 0.903
3 dcmp          Test   188.    993.  698.  1.90   8.00 0.936 0.859 0.897
4 harmonic      Test  -124.    894.  682. -1.82   8.03 0.915 0.774 0.910
5 ets           Test    33.3  1138.  950. -0.936 10.8  1.27  0.986 0.943
fc %>% 
  filter(.model == "combinado1") %>% 
  autoplot(vic_test)

4.3.1 Regresión armónica + predictoras exógenas y dummy festivos

tictoc::tic()
fit5 <- vic_train %>% 
  model(
    harmonic_temp_h = ARIMA(Demand ~ Temperature + I(Temperature^2) + fourier(period = "year", K = 7) + Holiday +
                       fourier(period = "week", K = 5) +
                       fourier(period = "day", K = 4) + PDQ(0,0,0) + pdq(2,0,2))
  )
tictoc::toc()
129.29 sec elapsed
report(fit5)
Series: Demand 
Model: LM w/ ARIMA(2,0,2) errors 

Coefficients:
         ar1      ar2      ma1      ma2  Temperature  I(Temperature^2)
      1.5057  -0.5698  -0.3458  -0.1166    -277.0607            7.4895
s.e.  0.0358   0.0307   0.0366   0.0135       7.7482            0.1841
      fourier(period = "year", K = 7)C1_8766
                                   -290.7067
s.e.                                 28.2610
      fourier(period = "year", K = 7)S1_8766
                                    163.3459
s.e.                                 25.1826
      fourier(period = "year", K = 7)C2_8766
                                    279.8746
s.e.                                 24.5480
      fourier(period = "year", K = 7)S2_8766
                                    261.2902
s.e.                                 24.6468
      fourier(period = "year", K = 7)C3_8766
                                   -144.0639
s.e.                                 24.4367
      fourier(period = "year", K = 7)S3_8766
                                    104.1295
s.e.                                 24.5107
      fourier(period = "year", K = 7)C4_8766
                                   -195.0305
s.e.                                 24.4444
      fourier(period = "year", K = 7)S4_8766
                                     30.4333
s.e.                                 24.5118
      fourier(period = "year", K = 7)C5_8766
                                    -55.6505
s.e.                                 24.4109
      fourier(period = "year", K = 7)S5_8766
                                     -9.2727
s.e.                                 24.4798
      fourier(period = "year", K = 7)C6_8766
                                    -88.7195
s.e.                                 24.3423
      fourier(period = "year", K = 7)S6_8766
                                     19.7732
s.e.                                 24.4441
      fourier(period = "year", K = 7)C7_8766
                                   -108.1952
s.e.                                 24.2762
      fourier(period = "year", K = 7)S7_8766    Holiday
                                     68.7754  -272.8512
s.e.                                 24.3355    44.1670
      fourier(period = "week", K = 5)C1_168
                                   583.1329
s.e.                                23.8272
      fourier(period = "week", K = 5)S1_168
                                  -529.9252
s.e.                                23.8458
      fourier(period = "week", K = 5)C2_168
                                   -33.1550
s.e.                                22.9762
      fourier(period = "week", K = 5)S2_168
                                   456.8081
s.e.                                22.9880
      fourier(period = "week", K = 5)C3_168
                                   -49.9360
s.e.                                21.6779
      fourier(period = "week", K = 5)S3_168
                                  -115.5447
s.e.                                21.6874
      fourier(period = "week", K = 5)C4_168
                                   -83.9451
s.e.                                20.0969
      fourier(period = "week", K = 5)S4_168
                                    90.5980
s.e.                                20.0961
      fourier(period = "week", K = 5)C5_168
                                    98.6771
s.e.                                18.3810
      fourier(period = "week", K = 5)S5_168
                                  -216.1351
s.e.                                18.3816
      fourier(period = "day", K = 4)C1_24  fourier(period = "day", K = 4)S1_24
                                 552.4248                            1460.0218
s.e.                              15.2307                              17.5121
      fourier(period = "day", K = 4)C2_24  fourier(period = "day", K = 4)S2_24
                                 419.0302                            -536.4984
s.e.                               7.7888                               7.9916
      fourier(period = "day", K = 4)C3_24  fourier(period = "day", K = 4)S3_24
                                  81.9913                            -291.5046
s.e.                               4.8462                               4.8384
      fourier(period = "day", K = 4)C4_24  fourier(period = "day", K = 4)S4_24
                                -188.6192                             100.2777
s.e.                               3.4600                               3.4486
       intercept
      11631.9996
s.e.     79.7767

sigma^2 estimated as 100053:  log likelihood=-172893
AIC=345868   AICc=345868.2   BIC=346199.7
fc5 <- fit5 %>% 
  forecast(new_data = vic_test)

fc5 %>% 
  accuracy(vic_test)
# A tibble: 1 × 10
  .model          .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
  <chr>           <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 harmonic_temp_h Test  -89.4  755.  589. -1.16  6.99   NaN   NaN 0.899

4.3.2 Más modelos combinados

Agregamos el nuevo modelo a nuestra tabla, y probamos haciendo otras dos combinaciones distintas:

fit_comb2 <- fit %>% 
  mutate(harmonic_temp_h = fit5$harmonic_temp_h,
         combinado2 = (ets + dcmp + harmonic_temp_h)/3,
         combinado3 = (ets + dcmp + harmonic + harmonic_temp + harmonic_temp_h)/5)
fit_comb2 %>% 
  accuracy() %>% arrange(MAPE)
# A tibble: 8 × 10
  .model          .type        ME  RMSE   MAE     MPE  MAPE  MASE RMSSE     ACF1
  <chr>           <chr>     <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl>    <dbl>
1 combinado2      Train… -1.89     241.  157. -0.117   1.69 0.211 0.209  5.55e-1
2 dcmp            Train…  3.48     470.  167. -0.0777  1.73 0.224 0.407  6.23e-1
3 combinado1      Train… -3.12     244.  172. -0.144   1.85 0.231 0.211  3.87e-1
4 combinado3      Train… -4.33     249.  181. -0.161   1.95 0.242 0.215  2.80e-1
5 ets             Train… -0.186    284.  210. -0.0556  2.32 0.282 0.246  7.68e-1
6 harmonic_temp_h Train…  0.0117   316.  238. -0.120   2.61 0.319 0.274 -2.32e-3
7 harmonic_temp   Train… -0.00195  316.  238. -0.120   2.61 0.319 0.274 -2.04e-3
8 harmonic        Train…  0.00939  349.  262. -0.135   2.83 0.352 0.302  9.99e-5
fc_comb2 <- fit_comb2 %>% 
  forecast(new_data = vic_test)

fc_comb2 %>% 
  accuracy(vic_test) %>% arrange(MAPE)
# A tibble: 8 × 10
  .model          .type      ME  RMSE   MAE     MPE  MAPE  MASE RMSSE  ACF1
  <chr>           <chr>   <dbl> <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl> <dbl>
1 combinado3      Test   -16.2   744.  565. -0.638   6.48   NaN   NaN 0.908
2 combinado1      Test     2.12  768.  578. -0.507   6.58   NaN   NaN 0.911
3 combinado2      Test    44.0   773.  586. -0.0669  6.61   NaN   NaN 0.909
4 harmonic_temp_h Test   -89.4   755.  589. -1.16    6.99   NaN   NaN 0.899
5 harmonic_temp   Test   -88.7   772.  597. -1.18    7.09   NaN   NaN 0.903
6 dcmp            Test   188.    993.  698.  1.90    8.00   NaN   NaN 0.897
7 harmonic        Test  -124.    894.  682. -1.82    8.03   NaN   NaN 0.910
8 ets             Test    33.3  1138.  950. -0.936  10.8    NaN   NaN 0.943
p <-  
  ggplot()+
  geom_line(data = vic_test, aes(x = hora, y = Demand)) + 
  geom_line(data = fc_comb2, aes(x = hora, y = .mean, color = .model))

plotly::ggplotly(p)