将巨大的模型对象保存到文件

时间:2012-12-23 12:38:18

标签: r

假设您有一个VAR()回归操作返回的类'varrest'的模型对象。 我想将模型保存到文件中,但不是所有用于估计系数的数据。

如何在没有训练数据的情况下保存模型规范? 因为当我保存模型时,它的文件大小超过1GB,因此加载确实需要时间。 可以保存没有某些属性的对象吗?

2 个答案:

答案 0 :(得分:5)

predict.varest函数从这段代码开始:

K <- object$K
p <- object$p
obs <- object$obs
type <- object$type
data.all <- object$datamat
ynames <- colnames(object$y)

然后,您可以调查可能会实现多少修剪:

data(Canada)
tcan <- 
VAR(Canada, p = 2, type = "trend")
names(tcan)
# [1] "varresult"    "datamat"      "y"            "type"         "p"           
# [6] "K"            "obs"          "totobs"       "restrictions" "call"        
 object.size(tcan[c("K","p", "obs", "type", "datamat", "y")] )
#15080 bytes
 object.size(tcan)
#252032 bytes

所以区别很大,但只保存这些项目是不够的,因为predict.varest中的下一行是:

B <- Bcoef(object)

您需要将该对象添加到上面的列表中,然后构造一个新的预测函数,该函数接受的内容少于模型对象的大“varresult”节点。还发现有一个下游调用需要存储的内部函数。 (您需要提前决定预测所需的时间间隔。)

tsmall <- c( tcan[c("K","p", "obs", "type", "datamat", "y", "call")] )
tsmall[["Bco"]] <- Bcoef(tcan)
tsmall$sig.y <- vars:::.fecov(x = tcan, n.ahead = 10)

修改后的predict函数将是:

sm.predict <- function (object, ..., n.ahead = 10, ci = 0.95, dumvar = NULL) 
{
    K <- object$K
    p <- object$p
    obs <- object$obs
    type <- object$type
    data.all <- object$datamat
    ynames <- colnames(object$y)
    n.ahead <- as.integer(n.ahead)
    Z <- object$datamat[, -c(1:K)]
  # This used to be a call to Bcoef(object)
    B <- object$Bco
    if (type == "const") {
        Zdet <- matrix(rep(1, n.ahead), nrow = n.ahead, ncol = 1)
        colnames(Zdet) <- "const"
    }
    else if (type == "trend") {
        trdstart <- nrow(Z) + 1 + p
        Zdet <- matrix(seq(trdstart, length = n.ahead), nrow = n.ahead, 
            ncol = 1)
        colnames(Zdet) <- "trend"
    }
    else if (type == "both") {
        trdstart <- nrow(Z) + 1 + p
        Zdet <- matrix(c(rep(1, n.ahead), seq(trdstart, length = n.ahead)), 
            nrow = n.ahead, ncol = 2)
        colnames(Zdet) <- c("const", "trend")
    }
    else if (type == "none") {
        Zdet <- NULL
    }
    if (!is.null(eval(object$call$season))) {
        season <- eval(object$call$season)
        seas.names <- paste("sd", 1:(season - 1), sep = "")
        cycle <- tail(data.all[, seas.names], season)
        seasonal <- as.matrix(cycle, nrow = season, ncol = season - 
            1)
        if (nrow(seasonal) >= n.ahead) {
            seasonal <- as.matrix(cycle[1:n.ahead, ], nrow = n.ahead, 
                ncol = season - 1)
        }
        else {
            while (nrow(seasonal) < n.ahead) {
                seasonal <- rbind(seasonal, cycle)
            }
            seasonal <- seasonal[1:n.ahead, ]
        }
        rownames(seasonal) <- seq(nrow(data.all) + 1, length = n.ahead)
        if (!is.null(Zdet)) {
            Zdet <- as.matrix(cbind(Zdet, seasonal))
        }
        else {
            Zdet <- as.matrix(seasonal)
        }
    }
    if (!is.null(eval(object$call$exogen))) {
        if (is.null(dumvar)) {
            stop("\nNo matrix for dumvar supplied, but object varest contains exogenous variables.\n")
        }
        if (!all(colnames(dumvar) %in% colnames(data.all))) {
            stop("\nColumn names of dumvar do not coincide with exogen.\n")
        }
        if (!identical(nrow(dumvar), n.ahead)) {
            stop("\nRow number of dumvar is unequal to n.ahead.\n")
        }
        if (!is.null(Zdet)) {
            Zdet <- as.matrix(cbind(Zdet, dumvar))
        }
        else {
            Zdet <- as.matrix(dumvar)
        }
    }
    Zy <- as.matrix(object$datamat[, 1:(K * (p + 1))])
    yse <- matrix(NA, nrow = n.ahead, ncol = K)
  # This used to be a call to vars:::.fecov
    sig.y <- object$sig.y
    for (i in 1:n.ahead) {
        yse[i, ] <- sqrt(diag(sig.y[, , i]))
    }
    yse <- -1 * qnorm((1 - ci)/2) * yse
    colnames(yse) <- paste(ci, "of", ynames)
    forecast <- matrix(NA, ncol = K, nrow = n.ahead)
    lasty <- c(Zy[nrow(Zy), ])
    for (i in 1:n.ahead) {
        lasty <- lasty[1:(K * p)]; print(lasty); print(B)
        Z <- c(lasty, Zdet[i, ]) ;print(Z)
        forecast[i, ] <- B %*% Z
        temp <- forecast[i, ]
        lasty <- c(temp, lasty)
    }
    colnames(forecast) <- paste(ynames, ".fcst", sep = "")
    lower <- forecast - yse
    colnames(lower) <- paste(ynames, ".lower", sep = "")
    upper <- forecast + yse
    colnames(upper) <- paste(ynames, ".upper", sep = "")
    forecasts <- list()
    for (i in 1:K) {
        forecasts[[i]] <- cbind(forecast[, i], lower[, i], upper[, 
            i], yse[, i])
        colnames(forecasts[[i]]) <- c("fcst", "lower", "upper", 
            "CI")
    }
    names(forecasts) <- ynames
    result <- list(fcst = forecasts, endog = object$y, model = object, 
        exo.fcst = dumvar)
    class(result) <- "varprd"
    return(result)
}

答案 1 :(得分:4)

要么

  • 将您不想要的属性设置为NULL,或
  • 将您想要的部分复制到新对象或
  • 使用正确的索引调用save()函数。