# Negative Forecast using Holt-Winters

I tried to use Holt-Winters for forecasting, but it gives me negative values, but since these are demand quantities they cannot be negative.

mydataforecast2 <- forecast::forecast(mydataforecast, h=20, level= c(80,95),fan= FALSE, lambda = NULL)


mydataforecast2 Point Forecast Lo 80 Hi 80 Lo 95 Hi 95 Oct 2018 -8724.044 -50231.53 32783.45 -72204.27 54756.18 Nov 2018 3826.795 -39752.39 47405.98 -62821.82 70475.41 Dec 2018 -2935.782 -48817.20 42945.64 -73105.36 67233.80 Jan 2019 -2564.481 -50969.64 45840.67 -76593.78 71464.82 Feb 2019 1132.152 -50008.02 52272.32 -77079.99 79344.29 Mar 2019 12440.978 -41634.78 66516.73 -70260.75 95142.71 Apr 2019 -3240.720 -60441.94 53960.50 -90722.44 84241.00 May 2019 -6482.359 -66988.58 54023.86 -99018.63 86053.92 Jun 2019 -11312.368 -75293.34 52668.61 -109162.82 86538.09 Jul 2019 -15894.025 -83510.41 51722.37 -119304.37 87516.32 Aug 2019 -15200.354 -86604.45 56203.74 -124403.50 94002.79 Sep 2019 -12319.313 -87655.76 63017.14 -127536.47 102897.84 Oct 2019 -25837.357 -118762.44 67087.72 -167954.00 116279.29 Nov 2019 -13286.517 -109826.49 83253.45 -160931.66 134358.63 Dec 2019 -20049.094 -120359.89 80261.70 -173461.22 133363.03 Jan 2020 -19677.793 -123909.49 84553.91 -179086.42 139730.84 Feb 2020 -15981.160 -124278.21 92315.89 -181607.21 149644.89 Mar 2020 -4672.334 -117173.78 107829.11 -176728.45 167383.78 Apr 2020 -20354.033 -137193.79 96485.73 -199045.02 158336.96 May 2020 -23595.671 -144902.81 97711.47 -209118.93 161927.59

So I tried to fit it using BoxCox()

myretailfitted <- BoxCox(myretaildatats,lambda = 0)
myretaildataforecast <- HoltWinters(myretailfitted)
> myretaildataforecast2 <- forecast::forecast(myretaildataforecast, h=20, level= c(80,95),fan= FALSE, lambda = NULL)


myretaildataforecast2 Point Forecast Lo 80 Hi 80 Lo 95 Hi 95 Oct 2018 7.604822 6.993493 8.216152 6.669875 8.539770 Nov 2018 8.549561 7.890697 9.208425 7.541916 9.557206 Dec 2018 8.133424 7.430231 8.836616 7.057984 9.208863 Jan 2019 8.061037 7.316149 8.805924 6.921830 9.200243 Feb 2019 8.152589 7.368220 8.936958 6.953000 9.352178 Mar 2019 8.444243 7.622287 9.266200 7.187169 9.701317 Apr 2019 7.218138 6.360240 8.076037 5.906095 8.530182 May 2019 7.129013 6.236618 8.021408 5.764213 8.493813 Jun 2019 6.896771 5.971165 7.822376 5.481179 8.312363 Jul 2019 6.594478 5.636812 7.552144 5.129854 8.059102 Aug 2019 7.076641 6.087954 8.065328 5.564575 8.588707 Sep 2019 7.389513 6.370750 8.408277 5.831449 8.947578 Oct 2019 6.507436 5.342285 7.672587 4.725491 8.289381 Nov 2019 7.452175 6.261395 8.642954 5.631035 9.273314 Dec 2019 7.036037 5.820170 8.251904 5.176529 8.895545 Jan 2020 6.963650 5.723202 8.204098 5.066549 8.860751 Feb 2020 7.055202 5.790652 8.319753 5.121239 8.989166 Mar 2020 7.346857 6.058654 8.635060 5.376721 9.316993 Apr 2020 6.120752 4.809324 7.432180 4.115095 8.126409 May 2020 6.031626 4.697377 7.365876 3.991068 8.072185

Now it gives me above results. How do I scale it back to my original data?

• I would be more interested in why the original forecast was negative. Can you share your data? Oct 19, 2018 at 14:24
• Here is the data --> Week, Quantity 1,7500 2,1041426 3,261636 4,104861 5,93899 6,49511 7,20978 8,28646 9,21179 10,20995 11,24693 12,17301 13,23370 14,84233 15,30068 16,29403 17,26642 18,21107 19,11900 20,7337 21,7231 22,6922 23,27829 24,22216 25,9614 26,19302 27,13418 28,11924 29,16830 30,19214 31,5503 32,10069 33,9153 34,11844 35,14262 36,23057 37,8971 38,21451 39,13944 40,12575 41,12584 42,23048 43,8308 44,7107 45,5456 46,2811 47,3610 48,4794 Oct 19, 2018 at 15:34
• Thanks. Holt Winters has a seasonal and trend component. Unless you have more data that you didn't show, you shouldn't be using seasonality with less than one year's worth of weekly data. In fact I would think that if you specified the frequency of the ts object as 52 you would get an error from the forecast function. Additionally, the data definitely is trending down. It makes sense that it would forecast a negative trend forward that would lead to negative values. If this is the result of some kind of level shift in demand, not a trend, then you need to control for it. Oct 19, 2018 at 17:00
• Do you suggest using another forecasting method - I have only order quantity for max 2-3 years /monthly data depending upon the product. At one point retailers would push the existing inventory, so no new order will be placed. What's the best way to control is negative trend - I prefer the forecast to be zero than negative. My bad it's monthly data - so I kept the frequency to 12, so that I will have atleast 2 seasons Oct 19, 2018 at 17:15
• ok so seasonality should be okay. For trend you have a few options. First, if there are exogenous factors that are causing shifts down in demand then you could utilize a forecasting method that allows for regressors (the forecast package has things you could use). Alternately, you can use a damped trend which will lead the trend to die out-- choose a parameter close to zero and it will die out quickly. That way a short term decrease that would take you to zero won't get all the way there. Oct 19, 2018 at 17:46

The formula for converting a Box-Cox transformed time series back to the original time-series is:

x = $$e^{\frac{\log{(\alpha * transform +1})}{\alpha}}$$

where "transform" is the transformed time-series.

• Hello - I used the formula but it gives me an error :myretransformedata <- exp(log(0.4019424*myretaildataforecast2+1)/0.4019424) Error in 0.4019424 * myretaildataforecast2 : non-numeric argument to binary operator Could you please advise Oct 19, 2018 at 15:37
• I corrected the formula. Does it work now? Oct 19, 2018 at 15:45
• The issue is 0.4019424*myretaildataforecast2 ? Do I need to convert my timeseries object into something else so that the multiplication works Oct 19, 2018 at 16:01
• Try converting it to a vector Oct 19, 2018 at 16:11
• num <- as.numeric(myretaildataforecast2) Error: (list) object cannot be coerced to type 'double' . Gives an error. Oct 19, 2018 at 17:35

Your problem is primarily you are trying to force an inadequate model onto the WEEKLY data . Latent in the data are pulses and two level shifts . Following is a useful model and here

The Actual,Fit and Forecast graph is here with residual plot here . The ACF of the residuals suggest sufficiency

The forecast plot is here with prediction limits.

The Actual and forecast plot is here showing the 4 pulses and two level shifts while the model is a two parameter autoregression ( lag1 and lag3 ) sometimes called (3,0,0) with an omitted coefficent at lag 2.

The automatic analysis delivered the "controls" that were to be found ... primarily the two downwards level shifts at period 19 and 39 and the 4 pulses at periods 14,23,7 and 42. The are the kind of features that https://stats.stackexchange.com/users/204319/chris-umphlett is suggesting to include in a useful model.

Note that there is a very slight upwards expectation in the forecasts.

In summary "listen to the data" while selecting an appropriate model . Notice there is no need or justification for any power transformations Notice that there is no need for any unwarranted power transformations like logs as is detailed here When (and why) should you take the log of a distribution (of numbers)?.

Using Box-Cox strategies (without isolating/incorporating a few pulse effects) falsely renders the conclusion that it is proven that there is more variability at the higher level . The conclusion is that increased variability is linked to higher levels of the expected value is false because the effect is not pervasive i.e. true everywhere or nearly everywhere.

1. My model is a hybrid model that includes predictor variables that were identified via Intervention Detection procedures https://pdfs.semanticscholar.org/09c4/ba8dd3cc88289caf18d71e8985bdd11ad21c.pdf . For you to duplicate my results simply create a data matrix (6 predictors) and and use an ar(3) model for the error process (preferably omit the lag2 coefficient) . You could then forecast using specified future values of the predictors and obtain .

2) Apparently you have run into a potential flaw in the software that you used as I was able to estimate a pure ar(3) model . and here . The residuals from this insufficient model suggest the presence of pulses and level shifts (not trends as there is a visual shift in the mean of the residuals rather than a continuous downwards slope) that need to be treated in order to correctly separate gignal and noise. . You should report your potential error to the author of the software so it can be remedied.

3) You didn't answer my question . Is this monthly data ? If so I can re-analyze as their maybe deterministic seasonal pulses in the data that are waiting to be discovered as they may be temporarily obfuscated by the autoregressive structure.

• I get error when I try to run the forecast function. arima(x = myretaildatats, order = c(3, 0, 0)) Coefficients: ar1 ar2 ar3 intercept 0.0717 0.3031 0.3798 89520.08 s.e. 0.1882 0.5210 0.4178 90935.45 sigma^2 estimated as 2.04e+10: log likelihood = -638.3, aic = 1286.6 >forecastarimaoutput <- forecast::Arima(forecastarima, h=20) Error in stats::arima(x = x, order = order, seasonal = seasonal, include.mean = include.mean, : unused argument (h = 20) Oct 20, 2018 at 8:14
• Yes it is monthly data Oct 20, 2018 at 12:31
• I will open up another answer ..... Oct 20, 2018 at 12:55
• There is no "flaw in the software used" with regards to fitting the AR(3) model, @paty26s is just passing the wrong arguments to the wrong functions. Oct 20, 2018 at 19:27
• that is good to know ....user error ! . I might have said or a "flaw in the software usage" . Oct 20, 2018 at 20:07

After being advised that the 48 values were MONTHLY.. A useful model was automatically constructed blending arima structure and any waiting-to-be-identified deterministic structure. The model is here and here with statistical summary here .

The plot of the residuals is here and forecast plot here

The arima portion is very similar to my first response as it has both a lag 1 and a lag 3 component. . (1,0,0)(1,0,0)3 .

One level shift down at or around period 20. Three pulses .. 14,23 and 4. Two seasonal dummy factors are also found representing a systematic downwards effect at period 1 and period 7 thus there is seasonality ( i.e. two seasonal dummies ) and not auto-projective seasonality i.e. arima seasonality.

Following is a table of forecasts

The Actual/Fit and Forecast is here

In order to more more fully understand this model ...closely examine the 7,19,31,and 43 values and you will better appreciate the seasonal pulse at period 7 of 12 that occurred each and every year as the values are all on the "low side" reflecting a singular effect given recent values.

time value

7 20978 19 11900 31 5503 43 8308

After being advised that the data starts at 2015/10 period 7 is April.

• There are 48 observations in the file, start date is good Oct 21, 2018 at 17:02