I have written a code in R which adds weighting and runs additive holt-winters to forecast. However for some of my data it gives the error:
Error in etsmodel(y, errortype[i], trendtype[j], seasontype[k], damped[l], :
Parameters out of range
Can someone please tell me why it is doing this and how i can stop it happening in future.
Here is my code:
suppressMessages(library(lmtest))
suppressMessages(library(car))
suppressMessages(library(tseries))
suppressMessages(library(forecast))
suppressMessages(library(TTR))
suppressMessages(library(geoR))
suppressMessages(library(MASS))
#-------------------------------------------------------------------------------
Input.data <- matrix(c("08Q1","08Q2","08Q3","08Q4","09Q1","09Q2","09Q3","09Q4","10Q1","10Q2","10Q3","10Q4","11Q1","11Q2","11Q3","11Q4","12Q1","12Q2","12Q3","12Q4","13Q1","13Q2","13Q3","13Q4","14Q1","14Q2","14Q3",73831.11865,84750.47149,85034.80061,99137.19637,62626.50672,72144.77761,74726.1774,122203.5416,84872.02354,96054.77537,93849.93456,136380.3862,94252.32737,101044.518,112453.256,138807.2089,102091.1436,102568.8303,98839.36528,129249.4421,91207.28917,93060.79801,87776.30512,124342.2055,87128.55797,90261.46195,86371.5614),ncol=2,byrow=FALSE)
Frequency <- 1/4
Forecast.horizon <- 4
Start.date <- c(8, 1)
Data.col <- as.numeric(Input.data[, length(Input.data[1, ])])
Data.col.ts <- ts(Data.col, deltat=Frequency, start = Start.date)
trans<- abs(round(BoxCox.lambda(Data.col, method = "loglik"),5))
categ<-as.character( c(cut(trans,c(0,0.25,0.75,Inf),right=FALSE)) )
Data.new<-switch(categ,
"1"=log(Data.col.ts),
"2"=sqrt(Data.col.ts),
"3"=Data.col.ts
)
mape <- function(percent.error)
mean(abs(percent.error))
#----- Weighting ---------------------------------------------------------------
fweight <- function(x){
PatX <- 0.5+x
return(PatX)
}
integvals <- rep(0, length.out = length(Data.new))
for (i in 1:length(Data.new)){
integi <- integrate(fweight, lower = (i-1)/length(Data.new), upper= i/length(Data.new))
integvals[i] <- 2*integi$value
}
HWAW <- ets(Data.new, model = "AAA", damped = FALSE, opt.crit = "mse", ic="aic", lower = c(0.03, 0.03, 0.03, 0.04),
upper = c(0.997, 0.997, 0.997, 0.997), bounds = "usual", restrict = FALSE)
parASW <- round(HWAW$par[1:3], digits=3)
HWAOPT <- function(parASW)
{
HWAddW <- ets(Data.new, model = "AAA", alpha = parASW[1], beta = parASW[2], gamma = parASW[3], damped = FALSE, opt.crit = "mae", ic="aic",
lower = c(0.001, 0.001, 0.001, 0.0001), upper = c(0.999, 0.999, 0.999, 0.999), bounds = "admissible", restrict = FALSE)
error <- c(resid(HWAddW))
error <- t(error) %*% integvals
percent.error <- 100*(error/c(Data.new))
MAPE <- mape(percent.error)
return(MAPE)
}
OPTHWA <- optim(parASW, HWAOPT, method="L-BFGS-B", lower=c(rep(0.01, 3)), upper=c(rep(0.99, 3)), control = list(fnscale= 1, maxit = 3000))
# Alternatively, set method="Nelder-Mead" or method="L-BFGS-B"
parS4 <- OPTHWA$par
HWAW1 <- ets(Data.new, model = "AAA", alpha = parS4[1], beta = parS4[2], gamma = parS4[3], damped = FALSE, opt.crit = "mae", ic="aic",
lower = c(0, 0, 0, 0), upper = c(0.999, 0.999, 0.999, 0.999), bounds = "admissible", restrict = FALSE)
Thankyou in advance
Edit:
Even when removing the limits for the upper and lower bound the error remains
Edit
I removed the opt.crit
from the ets
which made my code run fine. If there is another way then please let me know
EDIT
Although this worked for this data set, it still gave an error for a different one. So there must be something else i can do to make this code run automatically for all data sets
Most likely the parameters estimated by HWAW which you then round to 3 decimal points in parS4 are inadmissible. Beta must be smaller than alpha and gamma must be smaller than 1 minus alpha:
https://github.com/robjhyndman/forecast/issues/179
https://robjhyndman.com/eindhoven/2-1-StateSpace.pdf
Check the parameters you are passing in: