未观察到的组件模型预测:predict.UCM 在 rucm 包中不起作用
Unobserved Components Model Predictions: predict.UCM not working in rucm package
我使用 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
对此有任何帮助吗?
ucm 中使用新数据进行预测的错误尚未更正。
这是您获得样本外时间段预测的方法。
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 包中的预测功能。要使用预测功能,我必须将数据定义为 class SSModel
.
的对象
您将模型中使用的所有参数作为自变量,运行 一个以 NA 作为自变量的州 space 模型。
P.S.: 我会记住评论,下次写出更好的答案。
只是为了将来有人再次登陆此页面 - 作者维护的 git 存储库已进行了一些更新,以简单的方式解决此问题。请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)
我使用 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
对此有任何帮助吗?
ucm 中使用新数据进行预测的错误尚未更正。
这是您获得样本外时间段预测的方法。
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 包中的预测功能。要使用预测功能,我必须将数据定义为 class SSModel
.
您将模型中使用的所有参数作为自变量,运行 一个以 NA 作为自变量的州 space 模型。
P.S.: 我会记住评论,下次写出更好的答案。
只是为了将来有人再次登陆此页面 - 作者维护的 git 存储库已进行了一些更新,以简单的方式解决此问题。请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)