आपके प्रश्न का सीधा उत्तर यह है कि आपने जो अंतिम मॉडल लिखा था,
anova(lmer(y ~ a*b*c +(1|subject) + (1|a:subject) + (1|b:subject) + (1|c:subject) +
(1|a:b:subject) + (1|a:c:subject) + (1|b:c:subject), d))
मेरा मानना है कि "सिद्धांत रूप में" सही है, हालांकि यह एक अजीब पैरामीटर है जो वास्तविक अभ्यास में हमेशा अच्छा काम नहीं करता है।
क्यों कि इस मॉडल से आपको जो आउटपुट मिलता है वह aov()
आउटपुट के साथ असंगत है , मुझे लगता है कि इसके दो कारण हैं।
- आपका सरल नकली डेटासेट पैथोलॉजिकल है कि सर्वश्रेष्ठ-फिटिंग मॉडल वह है जो नकारात्मक विचरण घटकों का अर्थ रखता है, जो मिश्रित मॉडल
lmer()
(और अधिकांश अन्य मिश्रित मॉडल प्रोग्राम) द्वारा फिट होते हैं, जो अनुमति नहीं देगा।
- गैर-पैथोलॉजिकल डेटासेट के साथ भी, जिस तरह से आपके पास मॉडल सेट अप है, जैसा कि ऊपर उल्लेख किया गया है, हमेशा अभ्यास में अच्छी तरह से काम नहीं करता है, हालांकि मुझे मानना होगा कि मैं वास्तव में क्यों नहीं समझता। यह भी मेरी राय में आम तौर पर अजीब है, लेकिन यह एक और कहानी है।
मुझे पहले उस पैरामीटर का प्रदर्शन करना चाहिए जिसे मैं आपके शुरुआती दो-तरफ़ा एनोवा उदाहरण पर पसंद करता हूं। मान लें कि आपका डेटासेट d
लोड हो गया है। आपका मॉडल (ध्यान दें कि मैंने डमी से कॉन्ट्रास्ट कोड में बदलाव किया था):
options(contrasts=c("contr.sum","contr.poly"))
mod1 <- lmer(y ~ a*b+(1|subject) + (1|a:subject) + (1|b:subject),
data = d[d$c == "1",])
anova(mod1)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 2.20496 2.20496 3.9592
# b 1 0.13979 0.13979 0.2510
# a:b 1 1.23501 1.23501 2.2176
जो यहाँ ठीक काम किया है कि यह aov()
उत्पादन से मेल खाता है । जिस मॉडल को मैं पसंद करता हूं, उसमें दो बदलाव शामिल हैं: मैन्युअल रूप से इसके विपरीत-कारकों को कोड करना, ताकि हम आर कारक वस्तुओं (जो मैं 100% मामलों में करने की सलाह देता हूं) के साथ काम नहीं कर रहा हूं, और यादृच्छिक प्रभावों को अलग तरीके से निर्दिष्ट कर रहा हूं:
d <- within(d, {
A <- 2*as.numeric(paste(a)) - 3
B <- 2*as.numeric(paste(b)) - 3
C <- 2*as.numeric(paste(c)) - 3
})
mod2 <- lmer(y ~ A*B + (1|subject)+(0+A|subject)+(0+B|subject),
data = d[d$c == "1",])
anova(mod2)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# A 1 2.20496 2.20496 3.9592
# B 1 0.13979 0.13979 0.2510
# A:B 1 1.23501 1.23501 2.2176
logLik(mod1)
# 'log Lik.' -63.53034 (df=8)
logLik(mod2)
# 'log Lik.' -63.53034 (df=8)
सरल 2-वे समस्या में दो दृष्टिकोण पूरी तरह से बराबर हैं। अब हम 3-तरफ़ा समस्या पर जाएँगे। मैंने पहले उल्लेख किया है कि आपके द्वारा दिया गया उदाहरण डेटासेट पैथोलॉजिकल था। इसलिए आपके उदाहरण के डेटासेट को संबोधित करने से पहले मैं जो करना चाहता हूं, वह यह है कि वास्तविक वेरिएंट कंपोनेंट्स मॉडल (यानी, जहां नॉन-जीरो वर्जन कंपोनेंट को सच्चे मॉडल में बनाया गया है) से डेटासेट जनरेट किया जाए। पहले मैं दिखाऊंगा कि मेरा पसंदीदा पैरामीटर आपके प्रस्तावित प्रस्ताव से बेहतर कैसे काम करता है। तब मैं विचरण घटकों के आकलन का एक और तरीका प्रदर्शित करूँगा जो यह नहीं लगाता है कि उन्हें गैर-नकारात्मक होना चाहिए। तब हम मूल उदाहरण डेटासेट के साथ समस्या को देखने की स्थिति में होंगे।
नए डेटासेट संरचना में समान होंगे सिवाय इसके कि हमारे पास 50 विषय होंगे:
set.seed(9852903)
d2 <- expand.grid(A=c(-1,1), B=c(-1,1), C=c(-1,1), sub=seq(50))
d2 <- merge(d2, data.frame(sub=seq(50), int=rnorm(50), Ab=rnorm(50),
Bb=rnorm(50), Cb=rnorm(50), ABb=rnorm(50), ACb=rnorm(50), BCb=rnorm(50)))
d2 <- within(d2, {
y <- int + (1+Ab)*A + (1+Bb)*B + (1+Cb)*C + (1+ABb)*A*B +
(1+ACb)*A*C + (1+BCb)*B*C + A*B*C + rnorm(50*2^3)
a <- factor(A)
b <- factor(B)
c <- factor(C)
})
हम जिस एफ-अनुपात का मिलान करना चाहते हैं वह हैं:
aovMod1 <- aov(y ~ a*b*c + Error(factor(sub)/(a*b*c)), data = d2)
tab <- lapply(summary(aovMod1), function(x) x[[1]][1,2:4])
do.call(rbind, tab)
# Sum Sq Mean Sq F value
# Error: factor(sub) 439.48 8.97
# Error: factor(sub):a 429.64 429.64 32.975
# Error: factor(sub):b 329.48 329.48 27.653
# Error: factor(sub):c 165.44 165.44 17.924
# Error: factor(sub):a:b 491.33 491.33 49.694
# Error: factor(sub):a:c 305.46 305.46 41.703
# Error: factor(sub):b:c 466.09 466.09 40.655
# Error: factor(sub):a:b:c 392.76 392.76 448.101
यहाँ हमारे दो मॉडल हैं:
mod3 <- lmer(y ~ a*b*c + (1|sub)+(1|a:sub)+(1|b:sub)+(1|c:sub)+
(1|a:b:sub)+(1|a:c:sub)+(1|b:c:sub), data = d2)
anova(mod3)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 32.73 32.73 34.278
# b 1 21.68 21.68 22.704
# c 1 12.53 12.53 13.128
# a:b 1 60.93 60.93 63.814
# a:c 1 50.38 50.38 52.762
# b:c 1 57.30 57.30 60.009
# a:b:c 1 392.76 392.76 411.365
mod4 <- lmer(y ~ A*B*C + (1|sub)+(0+A|sub)+(0+B|sub)+(0+C|sub)+
(0+A:B|sub)+(0+A:C|sub)+(0+B:C|sub), data = d2)
anova(mod4)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# A 1 28.90 28.90 32.975
# B 1 24.24 24.24 27.653
# C 1 15.71 15.71 17.924
# A:B 1 43.56 43.56 49.694
# A:C 1 36.55 36.55 41.703
# B:C 1 35.63 35.63 40.655
# A:B:C 1 392.76 392.76 448.101
logLik(mod3)
# 'log Lik.' -984.4531 (df=16)
logLik(mod4)
# 'log Lik.' -973.4428 (df=16)
जैसा कि हम देख सकते हैं, केवल दूसरी विधि आउटपुट से मेल खाती है aov()
, हालांकि पहली विधि कम से कम बॉलपार्क में है। दूसरी विधि भी एक उच्च लॉग-संभावना प्राप्त करती है। मुझे यकीन नहीं है कि ये दो विधियां अलग-अलग परिणाम क्यों देती हैं, जैसा कि फिर से मुझे लगता है कि वे "सिद्धांत रूप में" समकक्ष हैं, लेकिन शायद यह कुछ संख्यात्मक / कम्प्यूटेशनल कारणों से है। या हो सकता है कि मुझसे गलती हुई हो और वे सिद्धांत रूप में भी समान नहीं हैं।
अब मैं पारंपरिक एनोवा विचारों के आधार पर विचरण घटकों के आकलन का एक और तरीका दिखाऊंगा। मूल रूप से हम आपके डिजाइन के लिए अपेक्षित औसत वर्ग समीकरण लेंगे, मतलब वर्गों के अवलोकन किए गए मूल्यों में स्थानापन्न करेंगे, और विचरण घटकों के लिए हल करेंगे। अपेक्षित माध्य वर्गों को प्राप्त करने के लिए हम एक आर फ़ंक्शन का उपयोग करेंगे जो मैंने कुछ साल पहले लिखा था, जिसे कहा जाता है EMS()
, जो यहां पर प्रलेखित है । नीचे मुझे लगता है कि फ़ंक्शन पहले से लोड है।
# prepare coefficient matrix
r <- 1 # number of replicates
s <- 50 # number of subjects
a <- 2 # number of levels of A
b <- 2 # number of levels of B
c <- 2 # number of levels of C
CT <- EMS(r ~ a*b*c*s, random="s")
expr <- strsplit(CT[CT != ""], split="")
expr <- unlist(lapply(expr, paste, collapse="*"))
expr <- sapply(expr, function(x) eval(parse(text=x)))
CT[CT != ""] <- expr
CT[CT == ""] <- 0
mode(CT) <- "numeric"
# residual variance and A*B*C*S variance are confounded in
# this design, so remove the A*B*C*S variance component
CT <- CT[-15,-2]
CT
# VarianceComponent
# Effect e b:c:s a:c:s a:b:s a:b:c c:s b:s a:s b:c a:c a:b s c b a
# a 1 0 0 0 0 0 0 4 0 0 0 0 0 0 200
# b 1 0 0 0 0 0 4 0 0 0 0 0 0 200 0
# c 1 0 0 0 0 4 0 0 0 0 0 0 200 0 0
# s 1 0 0 0 0 0 0 0 0 0 0 8 0 0 0
# a:b 1 0 0 2 0 0 0 0 0 0 100 0 0 0 0
# a:c 1 0 2 0 0 0 0 0 0 100 0 0 0 0 0
# b:c 1 2 0 0 0 0 0 0 100 0 0 0 0 0 0
# a:s 1 0 0 0 0 0 0 4 0 0 0 0 0 0 0
# b:s 1 0 0 0 0 0 4 0 0 0 0 0 0 0 0
# c:s 1 0 0 0 0 4 0 0 0 0 0 0 0 0 0
# a:b:c 1 0 0 0 50 0 0 0 0 0 0 0 0 0 0
# a:b:s 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0
# a:c:s 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0
# b:c:s 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0
# e 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# get mean squares
(MSmod <- summary(aov(y ~ a*b*c*factor(sub), data=d2)))
# Df Sum Sq Mean Sq
# a 1 429.6 429.6
# b 1 329.5 329.5
# c 1 165.4 165.4
# factor(sub) 49 439.5 9.0
# a:b 1 491.3 491.3
# a:c 1 305.5 305.5
# b:c 1 466.1 466.1
# a:factor(sub) 49 638.4 13.0
# b:factor(sub) 49 583.8 11.9
# c:factor(sub) 49 452.2 9.2
# a:b:c 1 392.8 392.8
# a:b:factor(sub) 49 484.5 9.9
# a:c:factor(sub) 49 358.9 7.3
# b:c:factor(sub) 49 561.8 11.5
# a:b:c:factor(sub) 49 42.9 0.9
MS <- MSmod[[1]][,"Mean Sq"]
# solve
ans <- solve(CT, MS)
cbind(rev(ans[c(grep("e",names(ans)),grep("s",names(ans)))])/
c(1,2,2,2,4,4,4,1))
# s 1.0115549
# a:s 1.5191114
# b:s 1.3797937
# c:s 1.0441351
# a:b:s 1.1263331
# a:c:s 0.8060402
# b:c:s 1.3235126
# e 0.8765093
summary(mod4)
# Random effects:
# Groups Name Variance Std.Dev.
# sub (Intercept) 1.0116 1.0058
# sub.1 A 1.5191 1.2325
# sub.2 B 1.3798 1.1746
# sub.3 C 1.0441 1.0218
# sub.4 A:B 1.1263 1.0613
# sub.5 A:C 0.8060 0.8978
# sub.6 B:C 1.3235 1.1504
# Residual 0.8765 0.9362
# Number of obs: 400, groups: sub, 50
ठीक है, अब हम मूल उदाहरण पर लौटेंगे। हम जिस एफ-अनुपात का मिलान करने की कोशिश कर रहे हैं वह हैं:
aovMod2 <- aov(y~a*b*c+Error(subject/(a*b*c)), data = d)
tab <- lapply(summary(aovMod2), function(x) x[[1]][1,2:4])
do.call(rbind, tab)
# Sum Sq Mean Sq F value
# Error: subject 13.4747 1.2250
# Error: subject:a 1.4085 1.4085 1.2218
# Error: subject:b 3.1180 3.1180 5.5487
# Error: subject:c 6.3809 6.3809 5.2430
# Error: subject:a:b 1.5706 1.5706 2.6638
# Error: subject:a:c 1.0907 1.0907 1.5687
# Error: subject:b:c 1.4128 1.4128 2.3504
# Error: subject:a:b:c 0.1014 0.1014 0.1149
यहाँ हमारे दो मॉडल हैं:
mod5 <- lmer(y ~ a*b*c + (1|subject)+(1|a:subject)+(1|b:subject)+
(1|c:subject)+(1|a:b:subject)+(1|a:c:subject)+(1|b:c:subject),
data = d)
anova(mod5)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 0.8830 0.8830 1.3405
# b 1 3.1180 3.1180 4.7334
# c 1 3.8062 3.8062 5.7781
# a:b 1 1.5706 1.5706 2.3844
# a:c 1 0.9620 0.9620 1.4604
# b:c 1 1.4128 1.4128 2.1447
# a:b:c 1 0.1014 0.1014 0.1539
mod6 <- lmer(y ~ A*B*C + (1|subject)+(0+A|subject)+(0+B|subject)+
(0+C|subject)+(0+A:B|subject)+(0+A:C|subject)+
(0+B:C|subject), data = d)
anova(mod6)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 0.8830 0.8830 1.3405
# b 1 3.1180 3.1180 4.7334
# c 1 3.8062 3.8062 5.7781
# a:b 1 1.5706 1.5706 2.3844
# a:c 1 0.9620 0.9620 1.4604
# b:c 1 1.4128 1.4128 2.1447
# a:b:c 1 0.1014 0.1014 0.1539
logLik(mod5)
# 'log Lik.' -135.0351 (df=16)
logLik(mod6)
# 'log Lik.' -134.9191 (df=16)
इस मामले में दो मॉडल मूल रूप से एक ही परिणाम प्राप्त करते हैं, हालांकि दूसरी विधि में बहुत अधिक लॉग-लाइबिलिटी है। न ही विधि मैच aov()
। लेकिन हम देखते हैं कि जब हम ऊपर दिए गए वेरिएशन घटकों के लिए हल करते हैं, तो जैसा कि हमने किया था, एनोवा प्रक्रिया का उपयोग करते हुए, जो वैरिएंट घटकों को गैर-नकारात्मक बनाने के लिए विवश नहीं करती है (लेकिन जिसका उपयोग केवल संतुलित डिजाइन में किया जा सकता है, जिसमें कोई निरंतर भविष्यवाणियां नहीं हैं और नहीं लापता डेटा; शास्त्रीय एनोवा धारणाएं)।
# prepare coefficient matrix
r <- 1 # number of replicates
s <- 12 # number of subjects
a <- 2 # number of levels of A
b <- 2 # number of levels of B
c <- 2 # number of levels of C
CT <- EMS(r ~ a*b*c*s, random="s")
expr <- strsplit(CT[CT != ""], split="")
expr <- unlist(lapply(expr, paste, collapse="*"))
expr <- sapply(expr, function(x) eval(parse(text=x)))
CT[CT != ""] <- expr
CT[CT == ""] <- 0
mode(CT) <- "numeric"
# residual variance and A*B*C*S variance are confounded in
# this design, so remove the A*B*C*S variance component
CT <- CT[-15,-2]
# get mean squares
MSmod <- summary(aov(y ~ a*b*c*subject, data=d))
MS <- MSmod[[1]][,"Mean Sq"]
# solve
ans <- solve(CT, MS)
cbind(rev(ans[c(grep("e",names(ans)),grep("s",names(ans)))])/
c(1,2,2,2,4,4,4,1))
# s 0.04284033
# a:s 0.03381648
# b:s -0.04004005
# c:s 0.04184887
# a:b:s -0.03657940
# a:c:s -0.02337501
# b:c:s -0.03514457
# e 0.88224787
summary(mod6)
# Random effects:
# Groups Name Variance Std.Dev.
# subject (Intercept) 7.078e-02 2.660e-01
# subject.1 A 6.176e-02 2.485e-01
# subject.2 B 0.000e+00 0.000e+00
# subject.3 C 6.979e-02 2.642e-01
# subject.4 A:B 1.549e-16 1.245e-08
# subject.5 A:C 4.566e-03 6.757e-02
# subject.6 B:C 0.000e+00 0.000e+00
# Residual 6.587e-01 8.116e-01
# Number of obs: 96, groups: subject, 12
अब हम देख सकते हैं कि मूल उदाहरण के बारे में क्या विकृति है। सर्वश्रेष्ठ-फिटिंग मॉडल वह है जिसका अर्थ है कि यादृच्छिक यादृच्छिक घटकों में से कई नकारात्मक हैं। लेकिन lmer()
(और अधिकांश अन्य मिश्रित मॉडल कार्यक्रम) विचरण घटकों के अनुमानों को गैर-नकारात्मक मानते हैं। यह आमतौर पर एक समझदार बाधा माना जाता है, क्योंकि वेरिएंस निश्चित रूप से कभी भी नकारात्मक नहीं हो सकते हैं। हालांकि, इस बाधा का एक परिणाम यह है कि मिश्रित मॉडल उन सटीक डेटासेट्स का प्रतिनिधित्व करने में असमर्थ हैं जो नकारात्मक इंट्राक्लास सहसंबंधों को दर्शाते हैं, अर्थात्, डेटासेट जहां एक ही क्लस्टर से अवलोकन कम हैं(बजाय अधिक से अधिक) औसत रूप से डेटासेट से औसतन निकाली गई टिप्पणियों की तरह, और फलस्वरूप जहां क्लस्टर क्लस्टर के भीतर क्लस्टर क्लस्टर के बीच पर्याप्त रूप से अधिक है। इस तरह के डेटासेट पूरी तरह से उचित डेटासेट होते हैं कि कोई कभी-कभार वास्तविक दुनिया (या गलती से अनुकरण!) में आ जाएगा, लेकिन उन्हें समझदारी से एक विचरण-घटक मॉडल द्वारा वर्णित नहीं किया जा सकता है, क्योंकि वे नकारात्मक विचरण घटकों को दर्शाते हैं। वे हालांकि ऐसे मॉडल द्वारा वर्णित "गैर-समझदार" हो सकते हैं, अगर सॉफ्टवेयर इसे अनुमति देगा। aov()
अनुमति देता है। lmer()
नहीं करता।
y ~ a*b + (1 + a*b|subject), d[d$c == "1",]
? या शायद मुझे कुछ याद आ रहा है?