R语言KFAS包中初始化何时会改变滤波和平滑结果?
KFAS包初始化对滤波和平滑结果的影响疑问
我想了解KFAS包中初始化对滤波和平滑结果的重要性。以下代码先采用精确 diffuse 初始化复现KFAS文献里的带漂移随机游走示例,之后改用更简单的显式初始化P1 <- matrix(c(1e7, 0, 0, 1e7), 2, 2),两种方法的结果几乎完全一致,符合预期。
但更换数据集(tdx为待分析的税率序列,约100个数据点,可提供给尝试解答的人)后,情况出现差异:
- 使用
P1 <- matrix(0, 2, 2); P1inf <- diag(2)的版本得到了合理的滤波和平滑结果; - 使用
P1 <- matrix(c(1e7, 0, 0, 1e7), 2, 2)的版本结果完全不合理,和参考版本毫无重合,呈现发散趋势。
我原本预期两个模型结果接近,差异仅集中在序列开头的初始化阶段,但实际两者差异巨大,第二个模型的滤波结果完全不可信。请问这是怎么回事?
复现代码
rm(list = ls()) library(KFAS) data("alcohol", package = "KFAS") deaths <- window(alcohol[, 2], end = 2007) population <- window(alcohol[, 6], end = 2007) data <- deaths / population # load("data_tdx.RData") # data <- tdx # 这是KFAS文献中的模型(带漂移的随机游走) Zt <- matrix(c(1, 0), 1, 2) Ht <- matrix(NA) Tt <- matrix(c(1, 0, 1, 1), 2, 2) Rt <- matrix(c(1, 0), 2, 1) Qt <- matrix(NA) a1 <- matrix(c(1, 0), 2, 1) P1 <- matrix(0, 2, 2) P1inf <- diag(2) model_gaussian <- SSModel(data ~ -1 + SSMcustom(Z = Zt, T = Tt, R = Rt, Q = Qt, a1 = a1, P1 = P1, P1inf = P1inf), H = Ht) fit_gaussian <- fitSSM(model_gaussian, inits = c(0, 0), method = "BFGS") out_gaussian <- KFS(fit_gaussian$model) # 复现文献中的图1 temp <- cbind(data, out_gaussian$a[,1], out_gaussian$alphahat[,1]) cols <- c("black","red","blue") lwd <- 2 lty <- c(1,1,1) plot.ts(temp, plot.type="single", col = cols,lwd = lwd,lty=lty,xlab="",ylab="",main="") legend("bottomright", legend = c("观测数据","滤波趋势","平滑趋势"), col = c("black","red","blue"), lty = c(1,1,1), lwd = c(2,2,2), bty="n", cex=0.9 ) # 采用显式初始化的相同模型 P1 <- matrix(c(1e7, 0, 0, 1e7), 2, 2) model_gaussian1 <- SSModel(data ~ -1 + SSMcustom(Z = Zt, T = Tt, R = Rt, Q = Qt, a1 = a1, P1 = P1), H = Ht) fit_gaussian1 <- fitSSM(model_gaussian1, inits = c(0, 0), method = "BFGS") out_gaussian1 <- KFS(fit_gaussian1$model) temp <- cbind(data, out_gaussian1$a[,1], out_gaussian1$alphahat[,1]) cols <- c("black","red","blue") lwd <- 2 lty <- c(1,1,1) plot.ts(temp, plot.type="single", col = cols,lwd = lwd,lty=lty,xlab="",ylab="",main="") legend("bottomright", legend = c("观测数据","滤波趋势","平滑趋势"), col = c("black","red","blue"), lty = c(1,1,1), lwd = c(2,2,2), bty="n", cex=0.9 ) (check <- cbind(out_gaussian$a[,1], out_gaussian1$a[,1], out_gaussian$alphahat[,1], out_gaussian1$alphahat[,1]))
问题原因分析
Diffuse初始化的本质差异
带漂移的随机游走模型中,趋势项(随机游走)、漂移项(常数)都是非平稳状态。精确diffuse初始化(P1inf)专门处理这种“初始状态完全未知”的非平稳情况,它本质是将对应状态的初始协方差设为无穷大,告诉卡尔曼滤波:完全由数据驱动估计初始状态,不引入任何先验假设。大数值协方差初始化的局限性
用1e7这类超大值代替无穷大,看似等价,实则存在致命问题:- 当数据集信号噪声比低(比如税率序列波动平缓、观测噪声大),大初始协方差会让滤波初期过度依赖初始猜测值(
a1),忽略观测数据的修正作用; - 卡尔曼滤波的递推公式对数值敏感,大协方差会导致增益计算出现不稳定,后续递推逐渐发散;
- 对于漂移项这种无随机波动的状态,大初始协方差会让模型错误认为其不确定性极大,而diffuse初始化能正确识别这类状态的“确定性未知”属性。
- 当数据集信号噪声比低(比如税率序列波动平缓、观测噪声大),大初始协方差会让滤波初期过度依赖初始猜测值(
数据集特性的影响
酒精死亡率序列信号噪声比高、趋势明显,大初始协方差带来的偏差会被数据快速修正,因此结果和diffuse初始化接近;但税率序列可能趋势平缓、噪声相对较大,数据无法快速修正偏差,最终导致结果发散。
解决建议
- 优先使用精确diffuse初始化:对于非平稳状态(如随机游走、常数漂移),直接用
P1inf指定扩散状态,这是KFAS针对这类模型设计的标准初始化方式; - 谨慎设置显式初始化:若必须用显式协方差,不要随意设超大值,可通过序列前几个观测的方差估计初始状态的不确定性,或结合领域先验信息设置合理值;
- 检查模型适配性:确认税率序列是否真的适合带漂移的随机游走模型,若序列趋势不明显,可考虑去掉漂移项或调整模型结构。
内容的提问来源于stack exchange,提问作者Stefan Boeters
相关产品推荐
相关产品推荐

