AIC, lỗi anova: Các mô hình không được trang bị cho cùng một số lượng quan sát, các mô hình không được trang bị cho cùng một kích thước của tập dữ liệu


9

Tôi có những mô hình như thế này:

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)

Bây giờ tôi đang cố gắng đánh giá xem hiệu ứng ngẫu nhiên có nên có trong mô hình hay không. Vì vậy, tôi so sánh các mô hình bằng AIC hoặc anova và tôi gặp lỗi sau:

> 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

Như bạn có thể thấy, trong cả hai trường hợp tôi đều sử dụng cùng một tập dữ liệu. Tôi đã tìm thấy hai biện pháp khắc phục, nhưng tôi không coi chúng là thỏa mãn:

  1. Thêm method = "ML"vào cuộc gọi lme () - không chắc có nên thay đổi phương thức hay không.
  2. Sử dụng lmer()thay thế. Đáng ngạc nhiên, điều này hoạt động, mặc dù thực tế là lmer () sử dụng phương thức REML. Tuy nhiên tôi không thích giải pháp này vì lmer()không hiển thị giá trị p cho các hệ số - lme()thay vào đó tôi thích sử dụng cũ hơn .

Bạn có biết đây có phải là một lỗi hay không và làm thế nào chúng ta có thể đi xung quanh nó?

Câu trả lời:


6

Một tìm kiếm nhanh cho thấy điều đó là có thể (mặc dù tôi phải thừa nhận rằng tôi nghĩ đó không phải là vấn đề) và đó không phải là lỗi ... chỉ là một trường hợp khác trong đó các phương thức trong R bị ẩn và dẫn đến những điều có vẻ 'bất ngờ ', nhưng đám đông RTFM nói, "Nó nằm trong tài liệu." Dù sao ... giải pháp của bạn là làm anovavới lmeđối số thứ nhất và các lmmô hình là đối số thứ hai (và thứ ba nếu bạn muốn). Nếu điều này có vẻ kỳ lạ, đó là bởi vì nó là một chút kỳ lạ. Lý do là khi bạn gọi anova, anova.lmephương thức chỉ được gọi nếu đối số đầu tiên là một lmeđối tượng. Mặt khác, nó gọi anova.lm(lần lượt gọi anova.lmlist; nếu bạn tìm hiểu kỹ anova.lm, bạn sẽ thấy lý do tại sao). Để biết chi tiết về cách bạn muốn được gọianovatrong trường hợp này, kéo lên giúp anova.lme. Bạn sẽ thấy rằng bạn có thể so sánh các mô hình khác với lmecác mô hình, nhưng chúng phải ở một vị trí khác với đối số đầu tiên. Rõ ràng cũng có thể sử dụng anovatrên các mô hình phù hợp bằng cách sử dụng glshàm mà không cần quan tâm quá nhiều đến thứ tự của các đối số mô hình. Nhưng tôi không biết đủ các chi tiết để xác định xem đó có phải là một ý tưởng tốt hay không, hoặc chính xác nó ngụ ý gì (có vẻ như nó ổn, nhưng cuộc gọi của bạn). Từ liên kết đó so sánh lmđể lmexuất hiện phải được ghi chép tốt và trích dẫn là một phương pháp, vì vậy tôi muốn phạm sai lầm theo hướng đó, là tôi bạn.

Chúc may mắn.


1
Ồ, và câu trả lời của người dùng11852 liên quan đến AIC với phần phụ lục của Gavin, không có AIC.lme đặc biệt hay bất cứ điều gì để giải quyết vấn đề đó và toàn bộ vấn đề bắt đầu vượt quá mức lương của tôi
russellpierce

3

Điều này là đặc biệt chắc chắn. Như một ý nghĩ đầu tiên: khi thực hiện mô hình so sánh nơi mô hình đang có tác dụng cố định cấu trúc khác nhau ( m2m3ví dụ), cách tốt nhất là chúng ta như sẽ "thay đổi" . (Nó sẽ nhân nó với , trong đó ) Điều thú vị là nó hoạt động bằng cách sử dụng khiến tôi tin rằng nó có thể không phải là một lỗi. Có vẻ như nó thực thi "thực hành tốt".y k k X = 0MLREMLykkX=0method="ML"

Đã nói rằng, hãy nhìn dưới mui xe:

 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")
     }     
 }

trong trường hợp của bạn, bạn có thể thấy rằng:

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

và rõ ràng logLiklà đang làm điều gì đó (có thể?) bất ngờ ...? không, không thực sự, nếu bạn nhìn vào tài liệu của logLik, ?logLik, bạn sẽ thấy nó được quy định rõ ràng:

 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’)

Điều này đưa chúng tôi trở lại điểm ban đầu của chúng tôi, bạn nên sử dụng ML.

Để sử dụng một câu nói phổ biến trong CS: "Đây không phải là lỗi, đó là một tính năng (thực)!"

EDIT : (Chỉ để giải quyết nhận xét của bạn :) Giả sử bạn phù hợp với mô hình khác sử dụng lmerthời gian này:

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

và bạn làm như sau:

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

Có vẻ như là một sự khác biệt rõ ràng giữa hai người nhưng thực sự không phải như lời giải thích của Gavin. Chỉ cần nói rõ ràng:

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

Có một lý do chính đáng tại sao điều này xảy ra về mặt phương pháp tôi nghĩ. lmekhông cố gắng hiểu ý nghĩa của hồi quy LME cho bạn trong lmerkhi thực hiện so sánh mô hình, nó sẽ ngay lập tức trở lại kết quả ML. Tôi nghĩ rằng không có lỗi về vấn đề này lmelmerchỉ là những lý do khác nhau đằng sau mỗi gói.

Xem thêm bình luận của Gavin Simposeon về một lời giải thích sâu sắc hơn về những gì đã anova()xảy ra với (Điều tương tự thực tế xảy ra với AIC)


"Bạn nên sử dụng ML" - nhưng làm thế nào bạn có thể giải thích rằng đó lmerlà sử dụng REML (xem tóm tắt mô hình) và hoạt động tốt trong AIC? Vì vậy, có hai khả năng: 1) thông báo lỗi là * một tính năng , không phải lỗi và thực tế là nó hoạt động lmerlà một lỗi. Hoặc 2) thông báo lỗi là một lỗi , không phải tính năng.
Tò mò

Xem bài đăng cập nhật (tôi phải bao gồm một số mã). Tôi đã nhận thấy điểm hợp lệ của bạn khi viết phản hồi ban đầu của bạn nhưng ban đầu tôi đã chọn cách loại bỏ nó để lý do đằng sau câu trả lời của tôi hoàn toàn dựa trên tính toán.
usεr11852

3
@Tomas lmer() không sử dụng REML khi bạn yêu cầu so sánh. IIRC họ đã bao gồm một số đường ưa thích lmer()để bạn không phải chỉnh lại mô hình MLchỉ để so sánh sự phù hợp khi bạn muốn REMLphù hợp với từng cá nhân để có được ước tính tốt nhất về các tham số phương sai. Nhìn vào ?lmer, chạy ví dụ LME đầu tiên lên đến và bao gồm cả anova(fm1, fm2)cuộc gọi. Nhìn vào khả năng nhật ký được báo cáo bởi anova()và những báo cáo trước đó trong đầu ra được in. Việc anova()nhận được ước tính ML cho bạn.
Gavin Simpson

Điểm hay của Gavin, tôi quên rằng lmercó cả hai cùng một lúc (nó sử dụng PLS để nó chỉ xoay quanh việc ước tính một lần duy nhất). Tôi quên kiểm tra những gì bạn đề cập.
usεr11852

2
@rpierce: AIC được báo cáo trong đóanova() là AIC dựa trên ML. AIC được báo cáo chỉ AIC()là một dựa trên REML.
usεr11852
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.