To jest zdecydowanie szczególne. Pierwsza myśl: gdy porównujemy modele, w których modele mają różne struktury efektów stałych ( m2i m3na przykład), najlepiej dla nasMLjak REMLsię zmieniy. (Pomnoży tok, gdzie k X= 0) To ciekawe, że działa, method="ML"co sprawia, że uważam, że to nie błąd. Wygląda na to, że wymusza „dobrą praktykę”.
Powiedziawszy to, spójrzmy pod maską:
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")
}
}
gdzie w twoim przypadku możesz zobaczyć, że:
lls <- lapply(list(m2,m3), stats4::logLik)
attr(lls[[1]], "nobs")
#[1] 500
attr(lls[[2]], "nobs")
#[1] 498
i oczywiście logLikrobi coś (może?) nieoczekiwanego ...? nie, nie bardzo, jeśli spojrzysz na dokumentację logLik, ?logLikzobaczysz, że jest to wyraźnie określone:
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’)
co przywraca nas do pierwotnego punktu, którego powinieneś używać ML.
Aby użyć wspólnego powiedzenia w CS: „To nie jest błąd; to (prawdziwa) funkcja!”
EDYCJA : (tylko w celu skomentowania komentarza :) Załóżmy, że pasujesz do innego modelu, używając lmertego czasu:
m3lmer <- lmer(y ~ x + 1|cat)
i wykonujesz następujące czynności:
lls <- lapply(list(m2,m3, m3lmer), stats4::logLik)
attr(lls[[3]], "nobs")
#[1] 500
attr(lls[[2]], "nobs")
#[1] 498
Co wydaje się wyraźną rozbieżnością między nimi, ale tak naprawdę nie jest tak, jak wyjaśnił Gavin. Wystarczy powiedzieć oczywiste:
attr( logLik(lme(y ~ x, random = ~ 1|cat, na.action = na.omit, method="ML")),
"nobs")
#[1] 500
Myślę, że istnieje dobry powód, dla którego dzieje się tak pod względem metodologii. lmestara się zrozumieć dla ciebie regresję LME, podczas lmergdy podczas porównywania modeli natychmiast wraca do wyników ML. Myślę, że nie ma żadnych błędów w tej sprawie lmei lmerpo prostu inne uzasadnienia dla każdego pakietu.
Zobacz także komentarz Gavina Simposona na bardziej wnikliwe wyjaśnienie tego, co się działo anova()(To samo dzieje się praktycznie z AIC)