我一直在尝试使用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
有人可以解释一下这里发生了什么吗?用biglm生成的AIC是否可以安全地用于比较同一数据集上的biglm模型?
最佳答案
tl; dr 在我看来,在当前(0.9-1)版本中,对于biglm
类对象(更具体地说,在update方法中),AIC方法中存在一个非常明显的错误,但该作者biglm
软件包是一个聪明,有经验的人,并且biglm
被广泛使用,所以也许我缺少了一些东西。搜寻"biglm AIC df.resid"
,似乎已经是discussed way back in 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)
现在拟合简化模型:
ff2 <- log(Volume)~log(Girth)
a2 <- biglm(ff2, chunk1)
a2 <- update(a2, chunk2)
a2 <- update(a2 ,chunk3)
a2_lm <- lm(ff2,trees)
现在比较AIC值:
AIC(a)-AIC(a2)
## [1] 1.80222
AIC(a_lm)-AIC(a2_lm)
## [1] -20.50022
检查我们是否没有搞砸:
all.equal(coef(a),coef(a_lm)) ## TRUE
all.equal(coef(a2),coef(a2_lm)) ## TRUE
看一下引擎盖:
biglm:::AIC.biglm
## function (object, ..., k = 2)
## deviance(object) + k * (object$n - object$df.resid)
原则上,这是正确的公式(观测值减去残差df应该是所拟合的参数的数量),但深入研究,似乎对象的
$df.resid
组件未正确更新:a$n ## 31, correct
a$df.resid ## 7, only valid before updating!
看
biglm:::update.biglm
,我会添加object$df.resid <- object$df.resid + NROW(mm)
在读取的行之前或之后
object$n <- object$n + NROW(mm)
...
对我来说,这似乎是一个相当明显的错误,所以也许我缺少明显的东西,或者它已得到修复。
一个简单的解决方法是将您自己的AIC函数定义为
AIC.biglm <- function (object, ..., k = 2) {
deviance(object) + k * length(coef(object))
}
AIC(a)-AIC(a2) ## matches results from lm()
(尽管请注意
AIC(a_lm)
仍不等于AIC(a)
,因为stats:::AIC.default()
使用2 *对数似然性而不是偏差(这两个量度的相加系数不同)...)关于r - biglm和lm之间的AIC不同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21740625/