线性模型加权拟合与GLM过原点拟合技术问询
问题1:为什么观测数更少的B点更靠近拟合直线?
你的加权代码完全没问题,这是加权最小二乘(WLS)的正常表现。
加权最小二乘的核心目标是最小化加权残差平方和:
$$\sum w_i (y_i - \hat{y}_i)^2$$
其中$w_i$是每个数据点的权重(这里就是你设置的tot_obsv)。
我们拆解下你的模型细节:
- 点A的权重是28(13+15),点B的权重是14(3+11)
- 拟合得到的系数$\beta \approx 4.32 \times 10^{-5}$,因此:
- 点A的拟合值:$300 \times 4.32e-5 \approx 0.013$,残差绝对值≈0.451
- 点B的拟合值:$6000 \times 4.32e-5 \approx 0.259$,残差绝对值≈0.045
虽然点B的残差绝对值更小(看起来更靠近直线),但它的权重只有点A的一半,所以它在加权平方和中的贡献远远小于点A:
- 点A的加权残差平方:$28 \times (0.451)^2 \approx 5.70$
- 点B的加权残差平方:$14 \times (0.045)^2 \approx 0.028$
模型会优先让权重大的点(A)的加权拟合误差尽可能小,权重小的点(B)即使绝对残差小,对整体目标的影响也微乎其微,这完全符合加权模型的设计逻辑。
问题2:如何让logit链接的GLM强制过原点?
首先要明确一个关键限制:logit链接的GLM无法直接让曲线过(0,0)(即浓度为0时死亡概率为0)。因为logit(p) = $\log(\frac{p}{1-p})$,当p=0时,logit(p)是负无穷,无法通过线性预测项$\beta \times conc$在conc=0时得到负无穷。
下面分两种场景解决你的问题:
场景1:仅需GLM无截距项(线性预测项无常数项)
如果你只是想去掉模型的截距项(即logit(p) = $\beta \times conc$),那你的初始代码是正确的:
M_glm <- glm(cbind(nr_dead, nr_surv) ~ 0 + conc, data = M, family = "binomial")
此时当conc=0时,logit(p)=0 → p=0.5,这是logit链接下无截距模型的必然结果,并非代码错误。
场景2:正确绘制无截距GLM的预测曲线
你的绘图代码存在冗余(提前predict后再用geom_smooth拟合),可以简化为以下两种更清晰的方式:
方式1:提前预测后用geom_line绘制
# 生成预测用的浓度序列 x_pred <- seq(0, 7000, length.out = 100) # 预测死亡概率 y_pred <- predict(M_glm, newdata = list(conc = x_pred), type = "response") # 绘图 library(ggplot2) ggplot(M, aes(x = conc, y = rate)) + geom_point(aes(size = tot_obsv), pch = 16) + # 添加预测曲线 geom_line(data = data.frame(conc = x_pred, rate = y_pred), aes(x = conc, y = rate), color = "blue", linewidth = 2) + xlab("concentration") + ylab("death rate") + ylim(0, 0.5) + theme_bw()
方式2:直接用geom_smooth拟合无截距GLM
不需要提前拟合模型,让geom_smooth直接拟合无截距的二项GLM:
library(ggplot2) ggplot(M, aes(x = conc, y = rate)) + geom_point(aes(size = tot_obsv), pch = 16) + geom_smooth(method = "glm", method.args = list(family = "binomial", formula = y ~ 0 + x), color = "blue", linewidth = 2) + xlab("concentration") + ylab("death rate") + ylim(0, 0.5) + theme_bw()
这里要注意method.args中的formula = y ~ 0 + x,其中x和y对应ggplot aes里的变量(即conc和rate),确保拟合的是无截距模型。
补充:如果一定要让曲线过(0,0)
如前所述,logit链接无法实现这个需求,你可以考虑以下替代方案:
- 使用其他链接函数(比如
log链接),但此时conc=0时p=1,仍不符合需求; - 自定义链接函数或使用非GLM模型(比如$p = \frac{\beta \times conc}{1 + \beta \times conc}$),但这类模型需要手动拟合,且对二项数据的适配性不如GLM;
- 重新审视需求:通常浓度为0时死亡概率不会严格为0,logit链接无截距模型的p=0.5可能不符合实际,但这是模型的数学特性决定的。
内容的提问来源于stack exchange,提问作者Lumi

