AIC在biglm和lm之间有所不同

use*_*687 5 r lm model-comparison

我一直在尝试使用biglm在大型数据集上运行线性回归(大约60,000,000行).我想使用AIC进行模型选择.但是我发现在较小的数据集上使用biglm时,biglm返回的AIC变量与lm返回的变量不同.这甚至适用于biglm帮助中的示例.

data(trees)
ff<-log(Volume)~log(Girth)+log(Height)

chunk1<-trees[1:10,]
chunk2<-trees[11:20,]
chunk3<-trees[21:31,]

library(biglm)
a <- biglm(ff,chunk1)
a <- update(a,chunk2)
a <- update(a,chunk3)

AIC(a)#48.18546

a_lm <- lm(ff, trees)
AIC(a_lm)#-62.71125
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下这里发生了什么吗?使用biglm生成的AIC是否可以安全地用于比较同一数据集上的biglm模型?

Ben*_*ker 5

tl;博士看起来像AIC方法中的biglm-class对象(更具体地说,在更新方法中),在当前(0.9-1)版本中有一个非常明显的错误,但是biglm包的作者是聪明,经验丰富的家伙,并被biglm广泛使用,所以也许我错过了一些东西.谷歌搜索"biglm AIC df.resid",似乎这已经在2009年讨论过?更新:包作者/维护者通过电子邮件报告这确实是一个错误.

有趣的东西似乎在这里发生.模型之间AIC之间的差异在建模框架中应该是相同的,无论使用哪些常数,然而计算参数(因为这些常量和参数计数建模框架中应该是一致的......)

原始示例:

data(trees)
ff <- log(Volume)~log(Girth)+log(Height)
chunk1<-trees[1:10,]
chunk2<-trees[11:20,]
chunk3<-trees[21:31,]
library(biglm)
a <- biglm(ff,chunk1)
a <- update(a,chunk2)
a <- update(a,chunk3)
a_lm <- lm(ff, trees)
Run Code Online (Sandbox Code Playgroud)

现在适合简化模型:

ff2 <- log(Volume)~log(Girth)    
a2 <- biglm(ff2, chunk1)
a2 <- update(a2, chunk2)
a2 <- update(a2 ,chunk3)
a2_lm <- lm(ff2,trees)
Run Code Online (Sandbox Code Playgroud)

现在比较AIC值:

AIC(a)-AIC(a2)
## [1] 1.80222

AIC(a_lm)-AIC(a2_lm)
## [1] -20.50022
Run Code Online (Sandbox Code Playgroud)

检查我们没有搞砸了:

all.equal(coef(a),coef(a_lm))  ## TRUE
all.equal(coef(a2),coef(a2_lm))  ## TRUE
Run Code Online (Sandbox Code Playgroud)

在引擎盖下看:

biglm:::AIC.biglm
## function (object, ..., k = 2) 
##    deviance(object) + k * (object$n - object$df.resid)
Run Code Online (Sandbox Code Playgroud)

原则上这是正确的公式(观察数量减去残差df应该是拟合的参数数量),但是挖掘,看起来$df.resid对象的组件没有正确更新:

a$n  ## 31, correct
a$df.resid  ## 7, only valid before updating!
Run Code Online (Sandbox Code Playgroud)

biglm:::update.biglm,我想补充一下

object$df.resid <- object$df.resid + NROW(mm)
Run Code Online (Sandbox Code Playgroud)

就在阅读之前或之后

object$n <- object$n + NROW(mm)
Run Code Online (Sandbox Code Playgroud)

...

这对我来说似乎是一个相当明显的错误,所以也许我错过了一些明显的东西,或者它可能已被修复.

一个简单的解决方法是将您自己的AIC功能定义为

AIC.biglm <- function (object, ..., k = 2) {
    deviance(object) + k * length(coef(object))
}

AIC(a)-AIC(a2)  ## matches results from lm()
Run Code Online (Sandbox Code Playgroud)

(虽然注意AIC(a_lm)仍然不等于AIC(a),因为stats:::AIC.default()使用2*对数似然而不是偏差(这两个度量的加法系数不同)...)