AIC,方差分析错误:模型并非都适合于相同数量的观测值,模型并非都适合于相同大小的数据集


9

我有这样的模型:

require(nlme)

set.seed(123)
n <- 100
k <- 5
cat <- as.factor(rep(1:k, n))
cat_i <- 1:k # intercept per kategorie
x <- rep(1:n, each = k)
sigma <- 0.2
alpha <- 0.001
y <- cat_i[cat] + alpha * x + rnorm(n*k, 0, sigma)
plot(x, y)

m1 <- lm(y ~ x)
summary(m1)

m2 <- lm(y ~ cat + x)
summary(m2)

m3 <- lme(y ~ x, random = ~ 1|cat, na.action = na.omit)
summary(m3)

现在,我正在尝试评估模型中是否应该存在随机效应。因此,我使用AIC或方差分析比较模型,但出现以下错误:

> AIC(m1, m2, m3)
   df       AIC
m1  3 1771.4696
m2  7 -209.1825
m3  4 -154.0245
Warning message:
In AIC.default(m1, m2, m3) :
  models are not all fitted to the same number of observations  
> anova(m2, m3)
Error in anova.lmlist(object, ...) : 
  models were not all fitted to the same size of dataset

如您所见,在两种情况下,我都使用相同的数据集。我找到了两种补救措施,但我认为它们并不令人满意:

  1. 添加method = "ML"到lme()调用 -不确定更改方法是否是个好主意。
  2. 使用lmer()代替。出乎意料的是,尽管lmer()使用REML方法,但这仍然有效。但是,我不喜欢这种解决方案,因为lmer()不会显示系数的p值-我喜欢改用较旧的方法lme()

您是否知道这是否是错误,我们如何解决?

Answers:


6

快速搜索表明有可能(尽管我不得不承认我认为不是),并且这不是错误……这是另一种情况,其中R中的方法被隐藏并导致看起来“意外” ”,但是RTFM人群说:“它在文档中。” 无论如何...您的解决方案是将第一个参数作为参数,将模型作为第二个参数(如果需要anova,则lme作为lm模型)。如果这看起来很奇怪,那是因为它有点奇怪。原因是,当您调用时anovaanova.lme仅当第一个参数是lme对象时才调用该方法。否则,它会调用anova.lm(反过来会调用anova.lmlist;如果您深入研究anova.lm,您将了解原因)。有关如何拨打电话的详细信息anova在这种情况下,请寻求帮助anova.lme。您将看到可以将其他模型与lme模型进行比较,但是它们必须处于第一个参数以外的位置。显然,也可以anova在使用该gls函数拟合的模型上使用,而不必太在乎模型参数的顺序。但是我对这些细节不够了解,无法确定这是一个好主意,还是确切地意味着什么(这似乎很好,但是可以打给您)。从那个链接比较lmlme似乎已被很好地证明并被引用为一种方法,所以我会朝那个方向犯错,是我吗。

祝好运。


1
哦,user11852在关于AIC与加文的附录答案看台上,没有特殊AIC.lme或任何解决这一问题,整个事情开始超出了我的薪酬等级滑
russellpierce

3

这绝对是奇特的。作为第一个念头:做在那里模型具有不同固定效应模型的结构比较时(m2以及m3例如),这是最好的我们中号大号以及REML“变化”ÿ。(它将与ķ,在哪里 ķX=0)有趣的是它可以使用method="ML",这使我相信它可能不是bug。似乎几乎强制执行“良好实践”。

话虽如此,让我们来看看幕后花絮:

 methods(AIC)  
 getAnywhere('AIC.default')

 A single object matching AIC.default was found
 It was found in the following places
   registered S3 method for AIC from namespace stats
   namespace:stats with value

 function (object, ..., k = 2) 
 {
     ll <- if ("stats4" %in% loadedNamespaces()) 
         stats4:::logLik
     else logLik
     if (!missing(...)) {
         lls <- lapply(list(object, ...), ll)
         vals <- sapply(lls, function(el) {
             no <- attr(el, "nobs") #THIS IS THE ISSUE!
             c(as.numeric(el), attr(el, "df"), if (is.null(no)) NA_integer_ else no)
         })
         val <- data.frame(df = vals[2L, ], ll = vals[1L, ])
         nos <- na.omit(vals[3L, ])
         if (length(nos) && any(nos != nos[1L])) 
             warning("models are not all fitted to the same number of observations")
         val <- data.frame(df = val$df, AIC = -2 * val$ll + k * val$df)
             Call <- match.call()
             Call$k <- NULL
         row.names(val) <- as.character(Call[-1L])
         val
     }
     else {
         lls <- ll(object)
         -2 * as.numeric(lls) + k * attr(lls, "df")
     }     
 }

在您的情况下,您可以看到:

  lls <- lapply(list(m2,m3), stats4::logLik)
  attr(lls[[1]], "nobs")
  #[1] 500
  attr(lls[[2]], "nobs")
  #[1] 498

显然logLik正在做某事(也许?)出乎意料...?不,不是真的,如果你看的文件logLik?logLik你会看到它明确规定:

 There may be other attributes depending on the method used: see
 the appropriate documentation.  One that is used by several
 methods is "nobs"’, the number of observations used in estimation
 (after the restrictions if REML = TRUE’)

这使我们回到了原来的观点,您应该使用ML

用CS中的一句俗语说:“这不是错误;它是(真正的)功能!”

编辑:(只是为了解决您的评论:)假设您lmer这次使用其他模型:

m3lmer <- lmer(y ~ x + 1|cat)

然后执行以下操作:

lls <- lapply(list(m2,m3, m3lmer), stats4::logLik)
attr(lls[[3]], "nobs")
#[1] 500
 attr(lls[[2]], "nobs")
#[1] 498

看起来两者之间显然存在差异,但实际上并非Gavin解释。仅说明显而易见的内容:

 attr( logLik(lme(y ~ x, random = ~ 1|cat, na.action = na.omit, method="ML")),
 "nobs")
#[1] 500

我认为,从方法论上讲,这是有充分理由的。lme确实会为您理解LME回归,而lmer在进行模型比较时,它会立即返回到ML结果。我认为有在这个问题上没有错误lmelmer每个包的背后只是不同的理由。

另请参阅加文·辛普森(Gavin Simposon)的评论,它对发生的情况进行了更深入的解释anova()(实际上也发生了AIC


“您应该使用ML”-但是如何解释lmer使用REML(请参阅模型摘要)并且在AIC中可以正常工作?因此,有两种可能性:1)错误消息是*功能而不是bug,而错误消息是lmer错误。或者2)错误消息是bug而不是功能。
好奇的2013年

看到更新的帖子(我必须包括一些代码)。我在编写原始答复时已经注意到了您的有效观点,但我最初选择将其保留在外,因此我的回答背后的理由完全基于计算。
usεr11852

3
@Tomas 要求您进行比较时lmer() 使用REML。IIRC他们在其中包含了一些奇特的糖,lmer()因此,ML当您要REML进行个体拟合以获得方差参数的最佳估计值时,您不必仅用比较拟合就可以对模型进行拟合。看一下?lmer,运行第一个LME示例,直到anova(fm1, fm2)调用为止。查看anova()打印输出中报告的对数似然率和先前报告的对数似然率。在anova()越来越ML估计你。
加文·辛普森

好点加文(Gavin),我忘记lmer了同时获得这两者(它使用PLS,因此每次只能估计一个)。我忘了检查你提到的内容。
usεr11852

2
@rpierce:AIC的报道anova()是一个基于ML的一个。AIC报告的只是AIC()基于REML的报告。
usεr11852
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.