【问题标题】:How to estimate the Kalman Filter with 'KFAS' R package, with an AR(1) transition equation?如何使用“KFAS”R 包和 AR(1) 转换方程估计卡尔曼滤波器?
【发布时间】:2017-02-08 06:57:58
【问题描述】:

我正在使用 R 中的“KFAS”包来估计带有卡尔曼滤波器的状态空间模型。我的测量和转换方程是:

y_t = Z_t * x_t + \eps_t(测量值)

x_t = T_t * x_{t-1} + R_t * \eta_t(过渡),

与 \eps_t ~ N(0,H_t) 和 \eta_t ~ N(0,Q_t)。

所以,我想估计方差 H_t 和 Q_t,还有 T_t,即 AR(1) 系数。我的代码如下:

library(KFAS)

set.seed(100)

eps <- rt(200, 4, 1)
meas <- as.matrix((arima.sim(n=200, list(ar=0.6), innov = rnorm(200)*sqrt(0.5)) + eps), 
ncol=1)

Zt <- 1
Ht <- matrix(NA)
Tt <- matrix(NA)
Rt <- 1
Qt <- matrix(NA)

ss_model <- SSModel(meas ~ -1 + SSMcustom(Z = Zt, T = Tt, R = Rt, 
                                             Q = Qt), H = Ht)
fit <- fitSSM(ss_model, inits = c(0,0.6,0), method = 'L-BFGS-B')

但它返回:"is.SSModel(do.call(updatefn, args = c(list(inits, model), update_args)) 中的错误:系统矩阵(不包括 Z)包含 NA 或无限值, 协方差矩阵包含大于 1e+07"的值

如包文件中所述,差异的 NA 定义效果很好。但是,对于 AR 系数,似乎无法做到这一点。有谁知道我该怎么做?

请注意,我知道 SSMarima 函数,它简化了将转换方程定义为 ARIMA 模型的过程。虽然我能够估计 AR(1) 系数。和 Q_t 这样,我仍然无法估计 \eps_t 方差(H_t)。此外,我正在将我的卡尔曼滤波器代码从 EViews 迁移到 R,因此我需要为其他更复杂的模型学习 SSMcustom。

谢谢!

【问题讨论】:

    标签: r kalman-filter


    【解决方案1】:

    您的示例中似乎缺少某些内容,因为您的错误消息来自函数fitSSM。如果你想使用fitSSM估计一般的状态空间模型,你需要提供自己的模型更新功能。默认行为只能处理协方差矩阵 H 和 Q 中的 NA。fitSSM 的主要目标只是从简单的东西开始。对于复杂的模型和/或大数据,我建议使用您自己编写的目标函数(借助 logLik 方法)和您最喜欢的手动数值优化例程以获得最佳性能。像这样的:

    library(KFAS)
    
    set.seed(100)
    
    eps <- rt(200, 4, 1)
    meas <- as.matrix((arima.sim(n=200, list(ar=0.6), innov = rnorm(200)*sqrt(0.5)) + eps), 
    ncol=1)
    
    Zt <- 1
    Ht <- matrix(NA)
    Tt <- matrix(NA)
    Rt <- 1
    Qt <- matrix(NA)
    
    ss_model <- SSModel(meas ~ -1 + SSMcustom(Z = Zt, T = Tt, R = Rt, 
                                                 Q = Qt), H = Ht)
    
    objf <- function(pars, model, estimate = TRUE) {
      model$H[1] <- pars[1]
      model$T[1] <- pars[2]
      model$Q[1] <- pars[3]
      if (estimate) {
      -logLik(model)
      } else {
        model
      }
    }
    
    opt <- optim(c(1, 0.5, 1), objf, method = "L-BFGS-B", 
      lower = c(0, -0.99, 0), upper = c(100, 0.99, 100), model = ss_model)
    
    ss_model_opt <- objf(opt$par, ss_model, estimate = FALSE)
    

    fitSSM相同:

    updatefn <- function(pars, model) {
      model$H[1] <- pars[1]
      model$T[1] <- pars[2]
      model$Q[1] <- pars[3]
      model
    }
    
    
    fit <- fitSSM(ss_model, c(1, 0.5, 1), updatefn, method = "L-BFGS-B", 
      lower = c(0, -0.99, 0), upper = c(100, 0.99, 100))
    
    identical(ss_model_opt, fit$model)
    

    【讨论】:

    • 你是对的。我忘记了问题中的最后一行代码(已编辑)。无论如何,你的答案很完美!非常感谢。
    猜你喜欢
    • 2012-01-17
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多