使用dlm包时遇L-BFGS-B需有限fn值错误的技术求助
解决dlmMLE运行时的"L-BFGS-B needs finite values of 'fn'"错误
这个错误本质是说,在优化过程中,对数似然函数返回了非有限值(比如NA、Inf或者-Inf),导致L-BFGS-B优化算法无法继续。结合你的TVP模型和股票价格数据,我整理了几个常见的排查方向和解决办法:
1. 先检查数据是否符合模型要求
股票价格本身是非平稳的时间序列,直接用水平值拟合时变参数模型很容易导致似然函数计算异常,甚至出现非有限值。建议先把价格转换成收益率序列:
# 计算对数收益率(缓解异方差问题) y <- diff(log(k[,1])) x.mat <- diff(log(k[,2])) # 去掉转换后产生的NA值 y <- y[!is.na(y)] x.mat <- x.mat[!is.na(x.mat)]
同时还要检查数据中是否存在缺失值或非数值:
# 检查缺失值 sum(is.na(k)) # 检查非有限值(Inf/-Inf) sum(!is.finite(k))
如果存在这类数据,需要先做清洗(比如插值、删除异常值)。
2. 调整初始参数值
你当前的初始参数start.vals = c(0,0,0),经过exp(parm)后会变成c(1,1,1),这个初始值可能和你的数据不匹配,导致似然函数计算出非有限值。可以先通过普通线性回归得到更合理的初始值:
# 用收益率拟合普通线性回归 lm_fit <- lm(y ~ x.mat) # 取残差方差的对数作为观测噪声的初始值 init_obs_var <- log(var(resid(lm_fit))) # 给状态噪声设置较小的初始值(exp后接近0,对应接近固定系数的模型) init_state_vars <- c(-5, -5) start.vals <- c(init_obs_var, init_state_vars) names(start.vals) <- c("lns2_obs", "lns2_alpha", "lns2_beta")
3. 调试似然函数,定位问题
手动计算初始参数下的似然值,确认是否是参数或模型的问题:
# 用初始参数构建模型 test_model <- buildTVP(start.vals, x.mat = x.mat) # 计算对数似然值 log_lik <- logLik(test_model, y = y) # 查看结果 print(log_lik)
如果这个结果是NA或非有限值,说明当前参数/数据组合无法产生有效的似然值,需要进一步调整数据或初始参数。
4. 尝试更换优化方法
L-BFGS-B对初始值比较敏感,可以先换用鲁棒性更强的优化方法(比如Nelder-Mead),得到合理的参数后再换回L-BFGS-B:
TVP.mle <- dlmMLE(y = y, parm = start.vals, x.mat = x.mat, build = buildTVP, hessian = TRUE, method = "Nelder-Mead")
5. 确认模型构建的正确性
检查dlmModReg的参数是否符合你的需求:
- 如果你的模型不需要常数项,需要添加
addInt = FALSE,此时状态维度会对应x.mat的列数,dW的长度也要匹配; - 确保
dW的长度和状态变量的数量一致(默认带常数项的话,状态是常数项+斜率,共2个,所以dW=c(parm[2], parm[3])是正确的)。
内容的提问来源于stack exchange,提问作者thelearner
相关产品推荐
相关产品推荐

