You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

glmmTMB模型收敛状态程序化判定与状态码含义咨询

glmmTMB模型收敛状态判定与相关疑问

发现的4种收敛场景

  • 正常收敛:无警告,model$fit$convergence == 0,model$fit$message == "relative convergence (4)"
  • 收敛至奇异拟合:触发警告model convergence problem; singular convergence (7),model$fit$convergence = 1,model$fit$message = "singular convergence (7)"
  • 疑似奇异拟合:触发警告Model convergence problem; non-positive-definite Hessian matrix,但model$fit$convergence = 0,model$fit$message = "relative convergence (4)"
  • 伪收敛(不收敛):触发两条警告,分别为Model convergence problem; non-positive-definite Hessian matrix.和Model convergence problem; false convergence (8),model$fit$convergence = 1,model$fit$message = "false convergence (8)"

核心问题

目前需要程序化检查收敛状态,但无法从拟合对象中直接提取警告信息,只能依赖model$fit$convergence和model$fit$message,但正常收敛(场景1)和疑似奇异拟合(场景3)的这两个输出完全一致,因此存在以下疑问:

  1. 如何从拟合对象中程序化明确判定所有收敛状态?
  2. 收敛消息/警告中括号内的数字(如4、7、8)代表什么?是否存在其他未发现的收敛状态?

解答

1. 程序化判定收敛状态的方法

glmmTMB的拟合对象中,除了model$fit里的基础信息,还可以通过两种方式明确区分所有收敛场景:

方法一:检查Hessian矩阵正定性

提取模型的Hessian矩阵并计算其特征值,若存在非正特征值,即可判定为场景3的疑似奇异拟合,结合model$fit$convergence == 0和model$fit$message == "relative convergence (4)",就能和场景1的正常收敛区分开:

library(glmmTMB)
# 提取Hessian矩阵
hess <- getME(model, "hessian")
# 计算特征值
eig_vals <- eigen(hess, only.values = TRUE)$values
# 判断是否存在非正特征值
is_singular_hessian <- any(eig_vals <= 1e-8) # 用极小值替代0避免浮点误差

方法二:捕获拟合时的警告信息

在拟合模型时,通过withCallingHandlers()捕获所有警告内容,直接通过警告文本判定场景:

fit_warnings <- character(0)
model <- withCallingHandlers(
  glmmTMB(y ~ x + (1 + x^2 | group), data = data),
  warning = function(w) {
    fit_warnings <<- c(fit_warnings, conditionMessage(w))
    invokeRestart("muffleWarning") # 避免控制台输出警告
  }
)

# 根据警告内容判定场景
if (length(fit_warnings) == 0) {
  cat("场景1:正常收敛")
} else if (any(grepl("singular convergence", fit_warnings))) {
  cat("场景2:收敛至奇异拟合")
} else if (any(grepl("non-positive-definite Hessian matrix", fit_warnings)) && model$fit$convergence == 0) {
  cat("场景3:疑似奇异拟合")
} else if (any(grepl("false convergence", fit_warnings))) {
  cat("场景4:伪收敛")
}

2. 收敛状态数字的含义及其他状态

这些括号内的数字是nlopt优化库的收敛状态码,glmmTMB底层使用nlopt进行参数优化,常见状态码对应含义:

  • 4:NLOPT_SUCCESS_RELATIVE——相对收敛,目标函数的变化量小于设定的容差阈值
  • 7:NLOPT_FAILURE——优化失败,对应奇异收敛(通常是随机效应协方差矩阵接近奇异)
  • 8:NLOPT_FAILURE的子类型,伪收敛,迭代过程未达到收敛标准就提前停止

除已发现的4种场景,实际使用中还可能遇到其他收敛状态,比如:

  • 状态码1:NLOPT_SUCCESS——绝对收敛,目标函数值达到预设的绝对容差
  • 状态码5:NLOPT_STOPVAL_REACHED——目标函数值达到预先设定的停止值
  • 状态码6:NLOPT_MAXEVAL_REACHED——达到最大迭代次数仍未收敛
  • 状态码9:NLOPT_INVALID_ARGS——输入参数无效(如模型公式错误、数据格式异常)

这些状态可通过nlopt的底层定义或glmmTMB的源码确认,遇到未知状态码时,可结合model$fit$message和优化过程的上下文判断具体原因。


各场景复现代码

library(glmmTMB)

# 1. 正常收敛
set.seed(1)
data <- data.frame(y = rnorm(100), x = rnorm(100), group = rep(1:10, each = 10))
model <- glmmTMB(y ~ x + (1  | group), data = data)
model$fit$convergence # == 0
model$fit$message  # "relative convergence (4)"

# 2. 收敛至奇异拟合
set.seed(3)
data <- data.frame(y = rnorm(100), x = rnorm(100), group = rep(1:10, each = 10))
model <- glmmTMB(y ~ x + (1 + x | group), data = data)
model$fit$convergence # == 1
model$fit$message  # "singular convergence (7)"

# 3. 疑似奇异拟合
set.seed(5)
data <- data.frame(y = rnorm(100), x = rnorm(100), group = rep(1:10, each = 10))
model <- glmmTMB(y ~ x + (1 + x^2 | group), data = data)
model$fit$convergence # == 0
model$fit$message # "relative convergence (4)"

# 4. 伪收敛(不收敛)
set.seed(1)
data <- data.frame(y = rnorm(100), x = rnorm(100), group = rep(1:10, each = 10))
data$y1 = data$y < -2
model <- glmmTMB(y1 ~ x + (1 + x | group), family = binomial, data = data)
model$fit$convergence   # == 1
model$fit$message  # "false convergence (8)"

内容的提问来源于stack exchange,提问作者Robert Long

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:11:20