未观察到的组件模型预测:predict.UCM在rucm包中不起作用

时间:2016-02-07 15:20:27

标签: r time-series forecasting

我使用ucm函数构建了一个模型。但是,当我尝试预测未来时,它不会让我通过自变量。

library("rucm")
library("lubridate")

#Create Simulated Data
Date<- as.Date(seq(from=as.Date('2012-01-01'),to=as.Date('2014-03-31'),by=1),"%Y-%m-%d")
Actual <- sample(27:65,length(Date),replace = TRUE)
DOW <- wday(Date)
Month <- month(Date)
DOM <- mday(Date)
Week <- week(Date)
Ya <- year(Date)
Ya <- ifelse(Ya=="2014",2,1)
a <- data.frame(Date,Actual,DOW,Month,DOM,Week,Ya)
a$Date<-as.Date(a$Date,"%Y-%m-%d")

abc <- cbind(Weekday=model.matrix(~as.factor(a$DOW)),
             Mont=model.matrix(~as.factor(a$Month)),
             Day=model.matrix(~as.factor(a$DOM)),a[,7,drop=FALSE],
             Weekofyear=model.matrix(~as.factor(a$Week)))

abc<-data.frame(abc)

abc<-data.frame(abc[,c(-1,-8,-20,-52)])

abc2 <- subset(abc,abc$Ya==1)
abc2 <- abc2[,-48]
abc3 <- subset(abc,abc$Ya==2)
abc3 <- abc3[,-48]

#train and insample MAPE
a1<-subset(a,a$Ya==1)
a2<-subset(a,a$Ya==2)
#build model
dat <- as.data.frame(cbind(a1[,2,drop=FALSE], abc2))
fo <- as.formula(paste("Actual ~ ", paste(names(dat)[2:42], collapse= "+")))
fit_train_ucm <- ucm(fo, data = dat, cycle = TRUE, cycle.period = 365)

#predict for future
predict(fit_train_ucm,n.ahead = 90,newdata = abc3)

我收到此错误

Error in is.SSModel(newdata, na.check = TRUE, return.logical = FALSE) : 
  Object is not of class 'SSModel'

更新 基于来自GitHub的软件包作者的建议,我使用下面的代码(很抱歉,这不是很自我解释,但我尝试编辑代码)

SSModel(rep(NA,nrow(abc3)) ~ x + SSMtrend(2, Q = list(fit_train_ucm$est.var.level, fit_train_ucm$est.var.slope)) + SSMseasonal(12, Q = fit_train_ucm$est.var.season), H = fit_train_ucm$irr.var, data=abc3)

现在错误消息是

Error in eval(expr, envir, enclos) : object 'x' not found

对此有何帮助?

2 个答案:

答案 0 :(得分:1)

这个用ucm中的newdata预测的错误尚未得到纠正。

这就是你如何得到一个样本外时期的预测。

indep <- paste(names(dat)[2:42], collapse= "+")
newdata1 <- SSModel(as.formula(paste0("rep(NA,nrow(abc3)) ~ ", indep, "+ SSMtrend(1, Q =  list(fit_train_ucm$est.var.level))",
               "+ SSMcycle(365, Q = fit_train_ucm$est.var.cycle)")), H = fit_train_ucm$irr.var, data=abc3)
pred<-predict(fit_train_ucm$model, newdata=newdata1)

所以基本上我在使用KFAS包中的预测功能。要使用预测函数,我必须将数据定义为类SSModel的对象。

您将把模型中使用的所有参数作为自变量,并运行状态空间模型,并将NA作为自变量。

P.S。:我会记住这些意见,以便下次写出更好的答案。

答案 1 :(得分:1)

以便将来有人再次访问此页面-作者维护的git repo进行了一些更新,以简化方式解决此问题。请check this commit

或者,粘贴该提交可能使用的功能:

predict.ucm <- function(object, n.ahead, newdata,...){

  #### Predict in sample ####

  if (missing(newdata)) {
    return(predict(object = object$model, n.ahead = n.ahead))
  } 

  #### Predict out of sample ####

  # Regression variables.
  model_variables <- paste0(names(object$est), collapse = " + ")

  # Trend

  # Case 1 no trend
  if (is.null(object$est.var.level) & is.null(object$est.var.slope)) { 
    model_trend <- ""
  }
  # Case 2 level and trend
  if (!is.null(object$est.var.level) & !is.null(object$est.var.slope)) { 
    model_trend <- "+ SSMtrend(degree = 2, Q = list(object$est.var.level, object$est.var.slope))"
  }
  # Case 3 level only / trend only is not allowed in R
  if (!is.null(object$est.var.level) & is.null(object$est.var.slope)) { 
    model_trend <- "+ SSMtrend(degree = 1, Q = list(object$est.var.level))"
  }

  # Seasonality
  if (!is.null(object$est.var.season)) {
    model_season <- sprintf("+ SSMseasonal(period = %s, Q = object$est.var.season)", 
                            object$call['season.length'] %>% as.character())
  } else { 
    model_season <- ""
  }

  # Cycle
  if (!is.null(object$est.var.cycle)) {
    model_cycle <- sprintf("+ SSMcycle(period = %s, Q = object$est.var.cycle)", 
                           object$call['cycle.period'] %>% as.character())
  } else { 
    model_cycle <- ""
  }

  # Combine all components into a formula
  model_formula <- as.formula(sprintf("rep(NA,nrow(newdata)) ~ %s %s %s %s",
                                      model_variables,
                                      model_trend,
                                      model_season,
                                      model_cycle
  ))

  # Build a SSM object for the prediction
  oos_data <- KFAS::SSModel(formula = model_formula, H = object$irr.var, data = newdata)

  # Return the predictions
  predict(object$model, newdata = oos_data)

}

编辑
如果您有兴趣预测新数据,该数据被视为与使用原始模型构建的相同时间段 ,则可以在以上功能。理想情况下,新数据应包含用于构建第一个模型的相同因变量值。

  # Using same dependent which was used initially to fit the estimates, instead of NA
  model_formula <- as.formula(paste0(
    object$model$terms[[2]],
    sprintf(
      " ~ %s %s %s %s",
      model_variables,
      model_trend,
      model_season,
      model_cycle
    )
  ))
  # Build a SSM object for the prediction
  oos_data <- KFAS::SSModel(formula = model_formula, H = object$irr.var, data = newdata)
  
  # Return the predictions for in sample only - hence removing newdata arg
  # predict(object$model, newdata = oos_data)
  predict(oos_data)