I'm trying to implement the Holt-Winters method in R. I have a time series whose data contains measurements over 24 hours of the day. I have a total of 5 years of data, that is, 43824 observations. I divided them into 43656 training and 168 tests. When I apply the method, I see that the values such as RMSE and MAPE are not bad, but when I plot them, it is seen that the real data and the predictions are not compatible. I'm sharing the codes: do you think I'm doing something wrong? Also, I can set the parameters of the Holt-Winters method with a for loop or something like a grid, but is there anything I can set in a shorter time?


date                hour                  tem
  <dttm>              <dttm>              <dbl> 
1 2018-01-01 00:00:00 1899-12-31 00:00:00  7.68 
2 2018-01-01 00:00:00 1899-12-31 01:00:00  7.30 
3 2018-01-01 00:00:00 1899-12-31 02:00:00  7.21 
4 2018-01-01 00:00:00 1899-12-31 03:00:00  7.53 
5 2018-01-01 00:00:00 1899-12-31 04:00:00  7.78 
6 2018-01-01 00:00:00 1899-12-31 05:00:00  7.93


df2<-msts(r$tem, seasonal.periods=c(24,365.25*24))

componendf2_df2 <- decompose(df2)


enter image description here


HW5 <- HoltWinters(train, alpha=0.07, beta=0.05011, gamma=0.008011,seasonal = "multiplicative")
 HW5_for <- forecast(HW5, h=168, level=0.95)
accuracy(HW5_for$mean,test )


     ME     RMSE       MAE       MPE     MAPE      ACF1 Theil's U

Test set 0.1607322 1.272415 0.8948736 0.7688493 28.02144 0.9874498  5.969364


  autoplot() +
  autolayer(test, series = "actual")+
  autolayer(HW5_for$mean, series = "fit")

enter image description here


1 Answer 1


You rather obviously have : intra-daily, intra-weekly and intra-yearly (the latter is clearly visible in your first plot panel). Straight-up Holt-Winters can't deal with that, it can only model a single seasonality. And it will not do a good job if you try to model the yearly seasonality with it, if that is even technically possible, because it would try to initialize about $365\times 24 = 8760$ initial states and then update them over just five years. You could model the intra-daily seasonality using Holt-Winters - but that would completely lose the intra-yearly seasonality, which appears to be dominant based on your first plot.

So I would definitely recommend you move away from Holt-Winters here. Our tag wiki contains pointers to alternative methods. You already defined your time series as an msts type, which makes sense, so now you could just feed it to forecast::tbats(). Note, though, that this can take a long time. It may be quite competitive in terms of accuracy and much faster to model this using multiple regression, using one set of harmonics with cycles of 24/12/8 hours (do not use dummies), another set with 168/84/56 hours, another set with cycles of 8760/4380/2920 hours, and potentially interactions. I have also had good results, in terms of both runtime and accuracy, using the MSTL function as implemented in the forecast package.

That said, even these methods will only be able to achieve a certain accuracy. There is a limit to forecastability.

Finally, your series have quite high residual coefficients of variation. You may want to reconsider the MAPE as an accuracy measure in this case.

  • $\begingroup$ Thank you for the recommendations. I also tried with Tbats, but the results are not good. I guess I'm doing something wrong somewhere. I'm adding the Tbats results below. tbats_mod <- train %>% tbats(use.box.cox = F, use.trend = T, use.damped.trend = T,use.arma.errors=T,biasadj=F) tbats_model <- forecast(tbats_mod,h=168) accuracy(tbats_model$mean,test) ` ME RMSE MAE MPE MAPE ACF1 Theil's U Test set 0.832008 1.274959 0.923159 20.68463 27.33798 0.9780328 5.53819` $\endgroup$
    – deniz
    Oct 27, 2023 at 11:38
  • $\begingroup$ I cannot attach the graph, but the actual values and predictions do not match. $\endgroup$
    – deniz
    Oct 27, 2023 at 11:45
  • $\begingroup$ "Do not match": You may want to take a look at that link in my penultimate paragraph. Some forecast error is unavoidable, there are very few perfect forecasts. $\endgroup$ Oct 27, 2023 at 11:53
  • $\begingroup$ You are right, but these seem to be quite different, the values that are closer to 5 in reality appear to be around 2. Is there a way to add the chart? $\endgroup$
    – deniz
    Oct 27, 2023 at 12:47
  • $\begingroup$ An error on the order of 3 seems to be quite within the natural variability of your time series, take a look at your first plot. All forecasting methods try to separate signal from noise, and if the signal says that a particular value is usually 5, that will be the prediction. And if the actual value is 5, and we have nothing to lead the model to suspect that (see that link again), then that is by definition noise. (Cases like these are why the MAPE may be misleading here.) You can edit your post to add more information, click on the link below it. $\endgroup$ Oct 27, 2023 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.