AIC, ข้อผิดพลาด anova: โมเดลไม่ได้ติดตั้งทั้งหมดกับจำนวนการสังเกตเท่ากันทุกรุ่นไม่ได้พอดีกับชุดข้อมูลขนาดเดียวกันทั้งหมด


10

ฉันมีโมเดลเช่นนี้:

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 หรือ anova และฉันได้รับข้อผิดพลาดต่อไปนี้:

> 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()แทน

คุณมีความคิดใด ๆ หรือไม่ว่านี่เป็นข้อผิดพลาดหรือไม่และเราจะสามารถแก้ไขได้อย่างไร

คำตอบ:


7

การค้นหาอย่างรวดเร็วแสดงให้เห็นว่าเป็นไปได้ (แม้ว่าฉันต้องยอมรับว่าฉันคิดว่ามันไม่ใช่) และมันไม่ใช่ข้อผิดพลาด ... เป็นอีกกรณีที่วิธีการใน R ถูกซ่อนอยู่และส่งผลให้เกิดสิ่งที่ดูเหมือนไม่คาดคิด 'แต่ฝูงชน RTFM พูดว่า "มันอยู่ในเอกสาร" อย่างไรก็ตาม ... ทางออกของคุณanovaเกี่ยวกับlmeอาร์กิวเมนต์แรกและอาร์กิวเมนต์เป็นอาร์กิวเมนต์lmที่สอง (และสามถ้าคุณต้องการ) ถ้านี่ดูแปลก ๆ ก็เป็นเพราะมันแปลกไปหน่อย เหตุผลก็คือเมื่อคุณเรียกanovaใช้anova.lmeเมธอดจะถูกเรียกก็ต่อเมื่ออาร์กิวเมนต์แรกเป็นlmeวัตถุ มิฉะนั้นจะเรียกanova.lm(ซึ่งจะเปิดสายanova.lmlistถ้าคุณขุดanova.lmคุณจะเห็นว่าทำไม) สำหรับรายละเอียดเกี่ยวกับวิธีที่คุณต้องการโทรanovaanova.lmeในกรณีนี้ดึงความช่วยเหลือ คุณจะเห็นว่าคุณสามารถเปรียบเทียบรุ่นอื่น ๆ กับlmeโมเดล แต่ต้องอยู่ในตำแหน่งที่ไม่ใช่อาร์กิวเมนต์แรก เห็นได้ชัดว่ามันเป็นไปได้ที่จะใช้anovaกับรุ่นที่พอดีกับการใช้glsฟังก์ชั่นโดยไม่ต้องใส่ใจมากเกินไปเกี่ยวกับลำดับของอาร์กิวเมนต์ของโมเดล แต่ฉันไม่ทราบรายละเอียดเพียงพอที่จะพิจารณาว่าเป็นความคิดที่ดีหรือไม่หรือว่ามันมีความหมายอย่างชัดเจน (ดูเหมือนว่าน่าจะดี แต่เป็นสายของคุณ) จากลิงค์นั้นเมื่อเปรียบเทียบlmกับlmeเอกสารและอ้างถึงอย่างดีว่าเป็นวิธีการดังนั้นฉันจึงทำผิดไปในทิศทางนั้นฉันเป็นคุณ

โชคดี.


1
โอ้และคำตอบของผู้ใช้ 11852 เกี่ยวกับ AIC กับภาคผนวกของ Gavin ไม่มี AIC.lme พิเศษหรืออะไรที่จะแก้ไขปัญหานั้นและสิ่งทั้งหมดก็เริ่มเกินระดับการจ่ายของฉัน
russellpierce

4

นี่เป็นเรื่องแปลกอย่างแน่นอน ในฐานะที่เป็นความคิดแรกเมื่อทำเปรียบเทียบรูปแบบที่จำลองจะมีแตกต่างกันโครงสร้างผลกระทบคงที่ ( m2และm3ตัวอย่าง) ที่ดีที่สุดคือให้เราเป็นน้ำพระทัย "เปลี่ยน" Y(มันจะทวีคูณด้วยโดยที่ ) มันน่าสนใจที่มันใช้งานได้ซึ่งทำให้ฉันเชื่อว่ามันอาจไม่ใช่ข้อผิดพลาด ดูเหมือนว่าเกือบจะบังคับใช้ "การปฏิบัติที่ดี"MLREMLykkX=0method="ML"

ต้องบอกว่าให้ดูภายใต้ประทุน:

 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

ซึ่งดูเหมือนว่าจะมีความแตกต่างที่ชัดเจนระหว่างทั้งสอง แต่จริงๆแล้วมันไม่ได้เป็นอย่างที่กาวินอธิบาย เพียงเพื่อระบุชัดเจน:

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

มีเหตุผลที่ดีว่าทำไมสิ่งนี้เกิดขึ้นในแง่ของวิธีการที่ฉันคิดว่า lmeลองใช้ความรู้สึกของการถดถอย LME สำหรับคุณในขณะlmerที่ทำการเปรียบเทียบแบบจำลองมันจะย้อนกลับไปที่ผลลัพธ์ ML ทันที ฉันคิดว่าไม่มีข้อบกพร่องในเรื่องนี้lmeและlmerเหตุผลที่แตกต่างกันตามแต่ละแพ็คเกจ

ดูความคิดเห็นของ Gavin Simposon เกี่ยวกับคำอธิบายที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับanova()สิ่งที่เกิดขึ้นด้วย (สิ่งเดียวกันเกิดขึ้นจริงด้วยAIC)


"คุณควรใช้ ML" - แต่คุณจะอธิบายได้อย่างไรว่าlmerใช้ REML (ดูข้อมูลสรุปรุ่น) และทำงานได้ดีใน AIC ดังนั้นจึงมีความเป็นไปได้สองประการ: 1) ข้อความแสดงข้อผิดพลาดคือ * คุณสมบัติไม่ใช่ข้อผิดพลาดและข้อเท็จจริงที่ใช้งานได้lmerคือข้อผิดพลาด หรือ 2) ข้อความแสดงข้อผิดพลาดเป็นข้อผิดพลาดไม่ใช่คุณสมบัติ
อยากรู้อยากเห็น

ดูโพสต์ที่อัปเดต (ฉันต้องมีรหัส) ฉันสังเกตเห็นจุดที่ถูกต้องของคุณเองเมื่อเขียนคำตอบดั้งเดิมของคุณ แต่ฉันเลือกที่จะเก็บมันไว้ในตอนแรกดังนั้นเหตุผลที่อยู่เบื้องหลังคำตอบของฉันก็คือการคำนวณอย่างเคร่งครัด
usεr11852

4
@Tomas lmer() ไม่ได้ใช้ REML เมื่อคุณขอให้ทำการเปรียบเทียบ IIRC พวกเขารวมน้ำตาลแฟนซีไว้ในlmer()ดังนั้นคุณไม่จำเป็นต้องดัดแปลงโมเดลด้วยMLการเปรียบเทียบพอดีเมื่อคุณต้องการREMLในแต่ละพอดีเพื่อรับการประมาณค่าที่ดีที่สุดของพารามิเตอร์ความแปรปรวน ดู?lmerเรียกใช้ตัวอย่าง LME แรกจนถึงและรวมถึงการanova(fm1, fm2)โทร ดูความน่าจะเป็นบันทึกที่รายงานโดยanova()และที่รายงานก่อนหน้านี้ในผลลัพธ์ที่พิมพ์ anova()จะได้รับการประมาณการ ML สำหรับคุณ
Gavin Simpson

จุดที่ดีกาวินฉันลืมว่าlmerมีทั้งสองอย่างในเวลาเดียวกัน (ใช้ PLS เพื่อให้ประมาณหนึ่งครั้งเท่านั้น) ฉันลืมตรวจสอบสิ่งที่คุณพูดถึง
usεr11852

2
@rpierce: AIC ที่รายงานภายในanova()นั้นเป็นข้อมูลที่อ้างอิง ML AIC รายงานว่าAIC()เป็นเพียงแค่อิงจาก REML
usεr11852
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.