You need to enable JavaScript to run this app. R语言中glm与bbmle包mle2拟合二项logit回归结果差异修正
优惠活动
大模型
产品
解决方案
定价
更多

R语言中glm与bbmle包mle2拟合二项logit回归结果差异修正

问题原因排查
  • 核心逻辑错误:负对数似然函数完全偏离优化目标
    你在写负对数似然时错误将log=TRUE作为参数传给了sum()函数,这里存在两个层面的问题:
    1. sum()本身没有提供log形参,该参数不是函数的正式控制项,会被...参数捕获,当成逻辑值(等价于数值1)参与求和,完全无法实现“对概率取对数再求和”的需求。
    2. 代码实际的计算逻辑是:先得到每个观测的伯努利概率值,再对这些概率值直接求和(额外加了2个来自错传参数的数值1),最后取负。这个目标函数和需要最大化的对数似然优化方向完全相反——优化器会为了最大化概率和,把预测概率p尽可能压到接近0的水平,最终收敛到参数空间的远端边界,导致你看到的极端系数估计、异常放大的标准误、所有p值接近1的结果。
  • 冗余代码问题:你定义的x1<-as.numeric(as.character(d$age))没有被任何函数引用,不影响结果但可以直接删除。
  • 模型结构逻辑是正确的:线性预测子的截距项、ses为2的系数、ses为3的系数、sector为2的系数,这个设计和glm中因子变量的参照组设定是完全一致的,不需要调整。
修正方案
  1. 重写负对数似然的计算逻辑:单独计算每个观测的对数概率,求和后取负,和二项logit模型的定义完全对齐。
  2. 将初始值从0.0001调整为0,减少优化器的无效搜索,保证收敛到全局最大值。

修正后的可运行代码

# 数据读取与GLM拟合
d <- read.delim("http://dnett.github.io/S510/Disease.txt")
d$disease <- factor(d$disease)
d$ses <- factor(d$ses)
d$sector <- factor(d$sector)
glm2 <- glm(disease ~ ses + sector, family = binomial(link = logit), data = d)
summary(glm2)

# mle2拟合部分
y <- as.numeric(as.character(d$disease))
x2 <- as.numeric(as.character(d$sector))
x3 <- as.numeric(as.character(d$ses))
library(bbmle)

# 修正后的负对数似然函数
nlldbin <- function(A, B, C, D){
  eta <- A + B*(x3 == 2) + C*(x3 == 3) + D*(x2 == 2)
  p <- 1/(1 + exp(-eta))
  # 逐观测计算对数似然,求和后取负
  log_lik <- y*log(p) + (1-y)*log(1-p)
  -sum(log_lik, na.rm = TRUE)
}

st <- list(A = 0, B = 0, C = 0, D = 0)
est_mle2 <- mle2(start = st, nlldbin, hessian = TRUE)
summary(est_mle2)
结果一致性说明

运行修正后的代码后,mle2输出的系数估计、标准误、z统计量会和glm2的结果几乎完全一致——因为两种方法本质上都是在最大化同一个二项logit模型的对数似然函数,不存在模型设定层面的差异。

内容的提问来源于stack exchange,提问作者Jasmine Helen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 23:06:02