在R语言中如何对数据框内的分层回归系数自动化执行mle2()优化
报错核心原因
你遇到的initial value in 'vmmin' is not finite报错本质是负对数似然函数在初始值处返回了无穷大/非有限值,由以下几个代码逻辑错误共同导致:
- 窗口索引越界:内层
k循环的上限是nrow(CFbasin2),取k:(k+9)时,当k > nrow(CFbasin2)-9,生成的x会包含大量NA甚至空行,计算误差时直接产生NaN/Inf - R惰性求值坑:内层循环重复定义
regress.ll函数,等循环结束调用mle2时,函数绑定的k是循环最终值(已经越界),根本没有匹配对应窗口的有效数据 - 似然函数写法错误:线性回归MLE的误差默认服从均值为0的正态分布,你在函数内动态计算误差均值
mu_error、动态计算误差标准差sd_errors的写法完全不符合MLE逻辑,不仅会导致参数冗余,一旦误差标准差为0/NA就会直接返回无穷大似然值 - 初始值存在NA:滚动回归生成的
CFbasin_coef可能存在NA值,直接传入start参数会被识别为非有限初始值
修复方案
步骤1:先清理无效系数
# 去掉滚动回归生成的含NA的系数行 CFbasin_coef <- na.omit(CFbasin_coef) # 确定有效窗口的最大索引 max_window_idx <- nrow(CFbasin2) - 9
步骤2:修正似然函数与循环逻辑
# 负对数似然函数单独定义,sigma作为待估参数,数据显式传入 regress.ll <- function(b0, b1, b2, r0, r1, r2, sigma, x) { x1 <- x$Qhaw x2 <- x$Qdp x3 <- x$Qlit y <- x$Qkl y.hat <- b0 + b1*(r0 + r1*x1 + r2*x2) + b2*x3 errors <- y - y.hat # 正态分布假设均值为0,sigma为待估参数 neg.loklik <- -sum(dnorm(errors, mean = 0, sd = sigma, log = TRUE), na.rm = TRUE) return(neg.loklik) } results <- list() # 不需要嵌套循环,每个系数对应匹配的10天窗口 for(i in 1:nrow(CFbasin_coef)){ # 你这里的窗口索引要和之前滚动回归的窗口对应,我这里先按10天步长取,你可以根据自己的窗口规则修改k的取值 k <- i if(k > max_window_idx) break current_x <- CFbasin2[k:(k+9), ] # 计算初始sigma:用初始系数算误差的标准差,加个小值避免为0 init_err <- current_x$Qkl - (CFbasin_coef$b0[i] + CFbasin_coef$b1[i]*(CFbasin_coef$r0[i] + CFbasin_coef$r1[i]*current_x$Qhaw + CFbasin_coef$r2[i]*current_x$Qdp) + CFbasin_coef$b2[i]*current_x$Qlit) init_sigma <- sd(init_err, na.rm = TRUE) + 1e-6 # 调用mle2,显式传入当前窗口数据,添加sigma初始值 results[[i]] <- mle2( minuslogl = regress.ll, start = list( b0 = CFbasin_coef$b0[i], b1 = CFbasin_coef$b1[i], b2 = CFbasin_coef$b2[i], r0 = CFbasin_coef$r0[i], r1 = CFbasin_coef$r1[i], r2 = CFbasin_coef$r2[i], sigma = init_sigma ), fixed = list(x = current_x), # 限制sigma为正,避免优化时出现非法值 lower = c(sigma = 1e-6), method = "L-BFGS-B" ) }
额外注意事项
- 如果你的滚动窗口是按年的同日提取而非时间序列连续10天,需要修改
current_x的提取逻辑,不要用连续行索引,而是按日历年的日期范围筛选 - 如果仍然有收敛报错,可以适当放宽参数上下限,或者对流量数据做对数变换降低异方差影响
内容的提问来源于stack exchange,提问作者Rua Jing
相关产品推荐
相关产品推荐

