R中加权数据下AIC手动计算与内置函数结果差异的技术咨询
首先,咱们得先搞清楚核心问题:你的手动AIC公式只适用于未加权的高斯线性模型,一旦涉及加权(不管线性还是非线性),这个公式就完全不适用了,这也是为什么R内置函数和手动计算结果差异巨大的原因。
为什么会有差异?
R的AIC()函数是基于模型的对数似然值来计算的,核心公式是:
AIC = -2 * logLik(model) + 2 * 参数数量
这里的关键是,加权模型的对数似然计算会考虑权重带来的方差结构变化:
- 对于未加权模型,我们默认所有观测的误差方差是恒定的(σ²);
- 但加权模型中,每个观测的误差方差是
σ² / w_i(w_i是你指定的权重),这时候对数似然的计算必须包含权重的对数项,来反映不同观测的方差差异。
你的手动公式完全忽略了这一点:
n + n log(2π) + n log(RSS/n) + 2(k + 1)
这个公式是从未加权高斯模型的对数似然推导而来,只适用于所有观测方差相同的场景。当你把它套用到加权模型时,你用的deviance(m4)是加权残差平方和而非普通RSS,同时也没加入权重对数的调整项,结果自然会完全偏离正确值。
线性加权模型的小差异
线性模型中差异相对小,是因为lm()的加权拟合下,AIC()已经考虑了权重,但你的手动公式没做对应调整——不过即使这样,线性模型里你的手动计算其实也是不准确的,只是因为线性模型结构简单,差异没那么扎眼。
非线性加权模型的显著差异
到了nls()的加权模型,这个问题被放大了:logLik(m4)的计算会包含sum(log(w))这一项(权重的对数和),而你的手动公式完全没考虑这个,导致结果天差地别。你看到的AIC(m4)=320.71是正确的基于加权似然的结果,而手动计算的0.15完全是错误的。
该用哪个结果?
毫无疑问,必须用R内置的AIC()函数结果。原因很简单:
- 它会根据模型类型(加权/未加权、线性/非线性)自动调用对应的对数似然计算逻辑,正确处理权重带来的方差变化;
- 你的手动公式只适用于非常特定的场景(未加权线性高斯模型),不能推广到其他情况。
关于GraphPad Prism的结果
你提到Prism显示加权模型AIC更低,这和R内置AIC()的结果看似矛盾,但其实是你的手动计算错误导致的误解。Prism的加权AIC计算逻辑和R内置函数是一致的,都是基于加权对数似然,你可以仔细核对Prism的结果和AIC(m4)是否匹配——大概率是你在手动计算时的错误,让你误以为Prism和手动结果一致。
正确的手动计算方式(可选)
如果一定要手动验证,应该基于模型的对数似然来计算:
# 以加权非线性模型m4为例 ll <- logLik(m4) # AIC公式:-2*对数似然 + 2*参数数量 aic_manual <- -2 * ll + 2 * attr(ll, "df") # 这个结果会和AIC(m4)完全一致 aic_manual AIC(m4)
内容的提问来源于stack exchange,提问作者Ron

