To jest zdecydowanie szczególne. Pierwsza myśl: gdy porównujemy modele, w których modele mają różne struktury efektów stałych ( m2
i m3
na przykład), najlepiej dla nasMLjak REML
się 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 logLik
robi coś (może?) nieoczekiwanego ...? nie, nie bardzo, jeśli spojrzysz na dokumentację logLik
, ?logLik
zobaczysz, ż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 lmer
tego 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. lme
stara się zrozumieć dla ciebie regresję LME, podczas lmer
gdy podczas porównywania modeli natychmiast wraca do wyników ML. Myślę, że nie ma żadnych błędów w tej sprawie lme
i lmer
po 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
)