使用R最大化对数似然函数估计参数时优化失效问题求助
优化失效原因
- 优化函数参数格式不符合
optim要求:optim默认将待估参数作为单个向量传入目标函数,你定义的Logg为4个独立参数a,b,c,s,无法接收optim传递的参数向量,直接导致函数调用失败。 - 初始值选取完全落在无效域:你选取的初始值
c(0,0,0,0)存在两个致命问题:一是参数b出现在lambda公式的分母位置,b=0会直接触发除零错误;二是a、b、sigma²(即代码中的s)、c均为非负参数,0值会导致log计算输入为0,返回非数值NaN,优化无法迭代。 - 非必要计算引入错误:你的观测死亡数d30/d60/d90为浮点型数值,而
factorial()仅支持整数输入,会直接报错;且对数似然中的log(factorial(d))项为与待估参数无关的常数,不影响优化结果,完全可以删除。 - 未考虑计算过程中的数值稳定性:迭代过程中如果出现
lambda + c <= 0的情况,会触发log输入为非正数的错误,导致优化中断。
调整后的解决方案
调整核心逻辑:改写目标函数适配optim的参数传递规则,选用支持参数约束的优化方法,替换合理初始值,删掉冗余计算、添加数值稳定逻辑。调整后可正常运行的代码如下:
d30 <- 2975.1 d60 <- 11456.38 d90 <- 2977.08 r30 <- 1531956.05 r60 <- 650404.58 r90 <- 9728.47 # 改写后的对数似然函数,接收单个参数向量 Logg <- function(par) { a <- par[1] b <- par[2] c <- par[3] s <- par[4] # 计算三个年龄组的mu值 mu0 <- (a*exp(b*0))/(1 + (s*a/b)*(exp(b*0)-1)) mu30 <- (a*exp(b*30))/(1 + (s*a/b)*(exp(b*30)-1)) mu60 <- (a*exp(b*60))/(1 + (s*a/b)*(exp(b*60)-1)) # 计算三组的泊松率项,加极小值避免log(0) lambda0 <- mu0 + c lambda30 <- mu30 + c lambda60 <- mu60 + c if (any(c(lambda0, lambda30, lambda60) <= 1e-10)) return(-Inf) # 对数似然计算,删除了不影响优化的常数阶乘项 ll <- d30*log(lambda0 * r30) - lambda0 * r30 + d60*log(lambda30 * r60) - lambda30 * r60 + d90*log(lambda60 * r90) - lambda60 * r90 return(ll) } # 选合理初始值,用带参数下界约束的L-BFGS-B方法优化 init_par <- c(a=0.001, b=0.01, c=0.0001, s=0.05) optim_res <- optim(init_par, Logg, method = "L-BFGS-B", lower = c(1e-8, 1e-8, 1e-8, 1e-8), control = list(fnscale=-1)) # 输出优化结果 print(optim_res)
如果后续收敛效果不佳,可以进一步调整初始值,或换用nloptr等更稳定的非线性优化包。
内容的提问来源于stack exchange,提问作者Natasha
相关产品推荐
相关产品推荐

