विषम डेटा के लिए एक तरफ़ा एनोवा के विकल्प


36

मेरे पास शैवाल बायोमास ( , , ) के 3 समूहों के डेटा हैं जिनमें असमान नमूना आकार ( , , ) हैं और मैं तुलना करना चाहूंगा कि क्या ये समूह एक ही आबादी के हैं।बी सी एन = 15 एन बी = 13 एन सी = 12ABCnA=15nB=13nC=12

एक-तरफ़ा एनोवा निश्चित रूप से जाने का रास्ता होगा, हालांकि मेरे डेटा पर सामान्यता परीक्षण करने पर, मुख्य मुद्दे पर विषमतावाद लगता है। बिना किसी परिवर्तन के मेरा कच्चा डेटा, भिन्नताओं ( ) के अनुपात में उत्पन्न हुआ, जो कि महत्वपूर्ण मूल्य ( F _ {\ rm crit} = 4.16 ) से बहुत अधिक है और इसलिए मैं एक तरफ़ा ANOVA नहीं कर सकता ।Fmax=19.1Fcrit=4.16

मैंने अपने डेटा को सामान्य करने के लिए परिवर्तन की कोशिश की। विभिन्न परिवर्तनों (लॉग, वर्गमूल, वर्ग) के परीक्षणों के बाद भी, सबसे कम Fmax उत्पादन परिवर्तन के बाद a log10 परिवर्तन 7.16 , जो कि F _ {\ rm crit} की तुलना में अभी भी अधिक था Fcrit

क्या यहाँ कोई मुझे सलाह दे सकता है कि यहाँ से कहाँ जाना है? मैं डेटा द्वारा सामान्य करने के लिए परिवर्तन के अन्य तरीकों के बारे में नहीं सोच सकता। वहाँ एक तरह से एनोवा के लिए कोई विकल्प हैं?

पुनश्च: मेरा कच्चा डेटा नीचे हैं:

A: 0.178 0.195 0.225 0.294 0.315 0.341 0.36  0.363 0.371 0.398 0.407 0.409 0.432 
   0.494 0.719
B: 0.11  0.111 0.204 0.416 0.417 0.441 0.492 0.965 1.113 1.19  1.233 1.505 1.897
C: 0.106 0.114 0.143 0.435 0.448 0.51  0.576 0.588 0.608 0.64  0.658 0.788 0.958

2
एफ परीक्षण स्पष्ट रूप से दिखाता है कि समूह समान जनसंख्या से नहीं हैं । अगला कदम इस परिणाम की व्याख्या करना होगा , जिसमें स्पष्ट दृश्य और शुरुआत में समूह द्वारा डेटा के मात्रात्मक विवरण के साथ शुरुआत की जाएगी।
whuber

सिक्का पैकेज में क्रमपरिवर्तन परीक्षण भी हैं। एनोवा के लिए यह वनवे_टेस्ट फंक्शन होगा। त्वरित-आर उदाहरण: statmethods.net/stats/resampling.html
user16263

जवाबों:


73

विषम डेटा के साथ काम करते समय कई विकल्प उपलब्ध हैं। दुर्भाग्य से, उनमें से कोई भी हमेशा काम करने की गारंटी नहीं है। यहाँ कुछ विकल्प दिए गए हैं जिनसे मैं परिचित हूँ:

  • परिवर्तनों
  • वेल्श एनोवा
  • कम से कम वर्ग
  • मजबूत प्रतिगमन
  • विषमलैंगिकता लगातार मानक त्रुटियों
  • बूटस्ट्रैप
  • क्रुशल-वालिस परीक्षण
  • ऑर्डिनल लॉजिस्टिक रिग्रेशन

अद्यतन: यहाँ एक रैखिक मॉडल (यानी, एक एनोवा या एक प्रतिगमन) फिटिंग के कुछ तरीकों का प्रदर्शन है R जब आपके पास विचरण की विषमता / विषमता है।

आइए अपने डेटा पर एक नज़र डालकर शुरू करें। सुविधा के लिए, मैंने उन्हें दो डेटा फ़्रेम में लोड किया है जिसे कहा जाता है my.data(जो प्रति समूह एक कॉलम के साथ ऊपर की तरह संरचित है) और stacked.data(जिसमें दो कॉलम हैं: valuesसंख्याओं के indसाथ और समूह संकेतक के साथ)।

हम औपचारिक रूप से के लिए परीक्षण कर सकते हैं heteroscedasticity Levene के परीक्षण के साथ:

library(car)
leveneTest(values~ind, stacked.data)
# Levene's Test for Homogeneity of Variance (center = median)
#       Df F value   Pr(>F)   
# group  2  8.1269 0.001153 **
#       38                    

निश्चित रूप से पर्याप्त, आपके पास विषमलैंगिकता है। हम यह देखने के लिए जाँच करेंगे कि समूहों के प्रकार क्या हैं। अंगूठे का एक नियम है कि रैखिक मॉडल विचरण की विषमता के लिए काफी मजबूत होते हैं, जब तक कि अधिकतम विचरण न्यूनतम विचरण से अधिक या अधिक न हो, इसलिए हम उस अनुपात को भी पा लेंगे: 4×

apply(my.data, 2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.01734578 0.33182844 0.06673060 
var(my.data$B, na.rm=T) / var(my.data$A, na.rm=T)
# [1] 19.13021

आपके संस्करण भिन्न रूप से भिन्न हैं, सबसे बड़े के साथ B, सबसे छोटा होने के नाते ,। यह एक विषम स्तर की समस्या है। 19×A

आपने बदलाव को स्थिर करने के लिए लॉग या वर्गमूल जैसे परिवर्तनों का उपयोग करने के बारे में सोचा था । यह कुछ मामलों में काम करेगा, लेकिन बॉक्स-कॉक्स प्रकार के परिवर्तनों को विषम रूप से डेटा को निचोड़कर विचरण को स्थिर करते हैं, या तो उन्हें निचोड़कर सबसे अधिक डेटा निचोड़ा जाता है, या उन्हें सबसे नीचे निचोड़कर सबसे अधिक डेटा निचोड़ा जाता है। इस प्रकार, आपको इसके लिए अपने डेटा के विचरण की आवश्यकता है ताकि आप इसके लिए बेहतर तरीके से काम कर सकें। आपके डेटा में विचरण में बहुत बड़ा अंतर है, लेकिन साधन और मध्यस्थों के बीच अपेक्षाकृत कम अंतर है, यानी, वितरण ज्यादातर ओवरलैप होते हैं। एक शिक्षण अभ्यास के रूप में, हम सभी मानों में और को parallel.universe.dataजोड़कर कुछ बना सकते हैं2.7B.7Cयह दिखाने के लिए कि यह कैसे काम करेगा:

parallel.universe.data = with(my.data, data.frame(A=A, B=B+2.7, C=C+.7))
apply(parallel.universe.data,       2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.01734578 0.33182844 0.06673060 
apply(log(parallel.universe.data),  2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.12750634 0.02631383 0.05240742 
apply(sqrt(parallel.universe.data), 2, function(x){ var(x, na.rm=T) })
#          A          B          C 
# 0.01120956 0.02325107 0.01461479 
var(sqrt(parallel.universe.data$B), na.rm=T) / 
var(sqrt(parallel.universe.data$A), na.rm=T)
# [1] 2.074217

वर्गमूल परिवर्तन का उपयोग उन डेटा को काफी अच्छी तरह से स्थिर करता है। आप यहाँ समानांतर ब्रह्मांड डेटा के लिए सुधार देख सकते हैं:

यहाँ छवि विवरण दर्ज करें

केवल अलग-अलग परिवर्तनों की कोशिश करने के बजाय, एक अधिक व्यवस्थित दृष्टिकोण बॉक्स-कॉक्स पैरामीटर का अनुकूलन करना है (हालांकि आमतौर पर इसे निकटतम व्याख्यात्मक परिवर्तन के लिए गोल करने की सिफारिश की जाती है)। आपके मामले में या तो वर्गमूल, , या लॉग, , स्वीकार्य हैं, हालांकि न तो वास्तव में काम करता है। समानांतर ब्रह्मांड डेटा के लिए, वर्गमूल सबसे अच्छा है: λλ=.5λ=0

boxcox(values~ind, data=stacked.data,    na.action=na.omit)
boxcox(values~ind, data=stacked.pu.data, na.action=na.omit) 

यहाँ छवि विवरण दर्ज करें

चूंकि यह मामला एक एनोवा (यानी, कोई निरंतर चर नहीं है), विषमता से निपटने का एक तरीका -ेस्ट (आज , एक भिन्नात्मक मूल्य, इसके बजाय ) में स्वतंत्रता के हर डिग्री के लिए वेल्च सुधार का उपयोग करना है : Fdf = 19.445df = 38

oneway.test(values~ind, data=stacked.data, na.action=na.omit, var.equal=FALSE)
#  One-way analysis of means (not assuming equal variances)
# 
# data:  values and ind
# F = 4.1769, num df = 2.000, denom df = 19.445, p-value = 0.03097

अधिक सामान्य दृष्टिकोण भारित वर्गों का उपयोग करना है । चूंकि कुछ समूह ( B) अधिक फैल गए हैं, उन समूहों में डेटा अन्य समूहों में डेटा की तुलना में औसत स्थान के बारे में कम जानकारी प्रदान करता है। हम प्रत्येक डेटा बिंदु के साथ वजन प्रदान करके मॉडल को इसमें शामिल कर सकते हैं। वजन के रूप में समूह विचरण के पारस्परिक उपयोग के लिए एक सामान्य प्रणाली है:

wl = 1 / apply(my.data, 2, function(x){ var(x, na.rm=T) })
stacked.data$w = with(stacked.data, ifelse(ind=="A", wl[1], 
                                           ifelse(ind=="B", wl[2], wl[3])))
w.mod = lm(values~ind, stacked.data, na.action=na.omit, weights=w)
anova(w.mod)
# Response: values
#           Df Sum Sq Mean Sq F value  Pr(>F)  
# ind        2   8.64  4.3201  4.3201 0.02039 *
# Residuals 38  38.00  1.0000                  

यह अनवांटेड एनोवा ( , ) की तुलना में थोड़ा अलग और पैदावार देता है , लेकिन इसने विषमता को अच्छी तरह से संबोधित किया है: Fp4.50890.01749

यहाँ छवि विवरण दर्ज करें

भारित कम से कम वर्ग एक रामबाण नहीं है, हालांकि। एक असुविधाजनक तथ्य यह है कि यह सिर्फ सही है अगर वज़न सिर्फ सही है, अर्थ, अन्य बातों के अलावा, कि वे एक प्राथमिकता-प्राथमिकता के रूप में जाने जाते हैं। यह या तो गैर-सामान्यता (जैसे तिरछा) या आउटलेर को संबोधित नहीं करता है। आपके डेटा से अनुमानित वजन का उपयोग करना अक्सर ठीक काम करेगा, हालांकि, विशेष रूप से यदि आपके पास उचित सटीकता के साथ विचरण का अनुमान लगाने के लिए पर्याप्त डेटा है (यह या जब आपके पास है तो एक विटेबल के बजाय -table का उपयोग करने के विचार के अनुरूप हैzt50100स्वतंत्रता की डिग्री), आपका डेटा पर्याप्त रूप से सामान्य है, और आपके पास कोई आउटलेयर नहीं है। दुर्भाग्य से, आपके पास अपेक्षाकृत कुछ डेटा (13 या 15 प्रति समूह), कुछ तिरछा और संभवतः कुछ आउटलेयर हैं। मुझे यकीन नहीं है कि ये एक बड़ा सौदा करने के लिए काफी खराब हैं, लेकिन आप कम से कम चौकों को मजबूत तरीकों से मिला सकते हैं। प्रसार के अपने उपाय के रूप में विचरण का उपयोग करने के बजाय (जो आउटलेर्स के प्रति संवेदनशील है, विशेष रूप से कम साथ ), आप अंतर-चतुर्थक सीमा के पारस्परिक उपयोग कर सकते हैं (जो प्रत्येक समूह में 50% आउटलेर द्वारा अप्रभावित है)। इन वज़न को तब एक अलग नुकसान के साथ जोड़कर मजबूत प्रतिगमन के साथ जोड़ा जा सकता था जैसे कि टकी के बिसक्वार: N

1 / apply(my.data,       2, function(x){ var(x, na.rm=T) })
#         A         B         C 
# 57.650907  3.013606 14.985628 
1 / apply(my.data,       2, function(x){ IQR(x, na.rm=T) })
#        A        B        C 
# 9.661836 1.291990 4.878049 

rw = 1 / apply(my.data, 2, function(x){ IQR(x, na.rm=T) })
stacked.data$rw = with(stacked.data, ifelse(ind=="A", rw[1], 
                                            ifelse(ind=="B", rw[2], rw[3])))
library(robustbase)
w.r.mod = lmrob(values~ind, stacked.data, na.action=na.omit, weights=rw)
anova(w.r.mod, lmrob(values~1,stacked.data,na.action=na.omit,weights=rw), test="Wald")
# Robust Wald Test Table
# 
# Model 1: values ~ ind
# Model 2: values ~ 1
# Largest model fitted by lmrob(), i.e. SM
# 
#   pseudoDf Test.Stat Df Pr(>chisq)  
# 1       38                          
# 2       40    6.6016  2    0.03685 *

यहाँ वजन उतना चरम नहीं है। अनुमानित समूह का अर्थ थोड़ा अलग होता है A: ( डब्ल्यूएलएस 0.36673, मजबूत 0.35722; B: डब्ल्यूएलएस 0.77646, मजबूत 0.70433; C: डब्ल्यूएलएस 0.50554, मजबूत 0.51845), के माध्यम से Bऔर Cअत्यधिक मूल्यों द्वारा कम खींचा जा रहा है।

अर्थमिति में ह्यूबर-व्हाइट ("सैंडविच") मानक त्रुटि बहुत लोकप्रिय है। वेल्च सुधार की तरह, इसके लिए आपको वेरिएंस-प्रायरिटी को जानने की आवश्यकता नहीं है और आपको अपने डेटा और / या किसी मॉडल पर आकस्मिक भार का अनुमान लगाने की आवश्यकता नहीं है जो सही नहीं हो सकता है। दूसरी ओर, मैं नहीं जानता कि इसे एनोवा के साथ कैसे शामिल किया जाए, इसका मतलब है कि आप केवल उन्हें व्यक्तिगत डमी कोड के परीक्षणों के लिए प्राप्त करते हैं, जो मुझे इस मामले में कम सहायक के रूप में प्रभावित करता है, लेकिन मैं उन्हें वैसे भी प्रदर्शित करूंगा:

library(sandwich)
mod = lm(values~ind, stacked.data, na.action=na.omit)
sqrt(diag(vcovHC(mod)))
# (Intercept)        indB        indC 
#  0.03519921  0.16997457  0.08246131 
2*(1-pt(coef(mod) / sqrt(diag(vcovHC(mod))), df=38))
#  (Intercept)         indB         indC 
# 1.078249e-12 2.087484e-02 1.005212e-01 

फ़ंक्शन vcovHCआपके बेटस (आपके डमी कोड) के लिए एक विषमकोणीय सुसंगत विचरण-सहसंयोजक मैट्रिक्स की गणना करता है, जो कि फ़ंक्शन कॉल में अक्षरों के लिए है। मानक त्रुटियां प्राप्त करने के लिए, आप मुख्य विकर्ण को निकालते हैं और वर्गमूल लेते हैं। प्राप्त करने के लिए -tests अपने बीटा के लिए, आप सत्र के आधार पर आपके गुणांक अनुमान विभाजित और उचित परिणामों की तुलना -distribution (अर्थात्, स्वतंत्रता के अपने अवशिष्ट डिग्री के साथ -distribution)। ttt

के लिए Rउपयोगकर्ताओं को विशेष रूप से, नीचे है कि टिप्पणी में @TomWenseleers नोट्स ? Anova में समारोह carपैकेज एक स्वीकार कर सकते हैं white.adjustतर्क एक पाने के लिए कारक heteroscedasticity लगातार त्रुटियों प्रयोग करने के लिए -value। p

Anova(mod, white.adjust=TRUE)
# Analysis of Deviance Table (Type II tests)
# 
# Response: values
#           Df      F  Pr(>F)  
# ind        2 3.9946 0.02663 *
# Residuals 38                 
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

आप बूटस्ट्रैपिंग द्वारा अपने टेस्ट स्टेटिस्टिक के वास्तविक नमूने वितरण के बारे में एक अनुभवजन्य अनुमान प्राप्त करने का प्रयास कर सकते हैं । सबसे पहले, आप सभी समूह साधनों को एक समान बनाकर एक सच्चा अशक्त बनाते हैं। फिर आप प्रतिस्थापन के साथ फिर से जुड़ते हैं और प्रत्येक बूट पर अपने टेस्ट स्टेटिस्टिक ( ) की गणना करते हैं, जो कि सामान्यता या समरूपता के संबंध में उनके डेटा के साथ नल के तहत के नमूना वितरण का अनुभवजन्य अनुमान प्राप्त करने के लिए है । कि नमूना वितरण है कि अत्यधिक या अपने मनाया परीक्षण आंकड़ा से अधिक चरम रूप में के अनुपात में है -value: FFp

mod    = lm(values~ind, stacked.data, na.action=na.omit)
F.stat = anova(mod)[1,4]
  # create null version of the data
nullA  = my.data$A - mean(my.data$A)
nullB  = my.data$B - mean(my.data$B, na.rm=T)
nullC  = my.data$C - mean(my.data$C, na.rm=T)
set.seed(1)
F.vect = vector(length=10000)
for(i in 1:10000){
  A = sample(na.omit(nullA), 15, replace=T)
  B = sample(na.omit(nullB), 13, replace=T)
  C = sample(na.omit(nullC), 13, replace=T)
  boot.dat  = stack(list(A=A, B=B, C=C))
  boot.mod  = lm(values~ind, boot.dat)
  F.vect[i] = anova(boot.mod)[1,4]
}
1-mean(F.stat>F.vect)
# [1] 0.0485

कुछ मायनों में, बूटस्ट्रैपिंग मापदंडों के विश्लेषण (जैसे, साधन) का संचालन करने के लिए अंतिम कम धारणा दृष्टिकोण है, लेकिन यह मान लेता है कि आपका डेटा आबादी का एक अच्छा प्रतिनिधित्व है, जिसका अर्थ है कि आपके पास एक उचित नमूना आकार है। चूँकि आपके छोटे हैं, इसलिए यह कम भरोसेमंद हो सकता है। संभवतः गैर-सामान्यता और विषमता के खिलाफ अंतिम सुरक्षा गैर-पैरामीट्रिक परीक्षण का उपयोग करना है। एक एनोवा का मूल गैर-पैरामीट्रिक संस्करण क्रुस्कल-वालिस परीक्षण है : n

kruskal.test(values~ind, stacked.data, na.action=na.omit)
#  Kruskal-Wallis rank sum test
# 
# data:  values by ind
# Kruskal-Wallis chi-squared = 5.7705, df = 2, p-value = 0.05584

यद्यपि क्रुस्ल-वालिस परीक्षण निश्चित रूप से टाइप I त्रुटियों के खिलाफ सबसे अच्छा संरक्षण है, इसका उपयोग केवल एक एकल श्रेणीगत चर (यानी, कोई निरंतर भविष्यवक्ता या तथ्यात्मक डिजाइन) के साथ नहीं किया जा सकता है और इसमें चर्चा की गई सभी रणनीतियों की कम से कम शक्ति है। एक अन्य गैर-पैरामीट्रिक दृष्टिकोण है, जो ऑर्डिनल लॉजिस्टिक रिग्रेशन का उपयोग करता है । यह बहुत से लोगों को अजीब लगता है, लेकिन आपको केवल यह मानने की ज़रूरत है कि आपके प्रतिक्रिया डेटा में वैध अध्यादेश संबंधी जानकारी है, जो वे निश्चित रूप से करते हैं या फिर उपरोक्त हर अन्य रणनीति अमान्य है:

library(rms)
olr.mod = orm(values~ind, stacked.data)
olr.mod
# Model Likelihood          Discrimination          Rank Discrim.    
# Ratio Test                 Indexes                Indexes       
# Obs            41    LR chi2      6.63    R2                  0.149    rho     0.365
# Unique Y       41    d.f.            2    g                   0.829
# Median Y    0.432    Pr(> chi2) 0.0363    gr                  2.292
# max |deriv| 2e-04    Score chi2   6.48    |Pr(Y>=median)-0.5| 0.179
#                      Pr(> chi2) 0.0391

यह आउटपुट से स्पष्ट नहीं हो सकता है, लेकिन एक पूरे के रूप में मॉडल का परीक्षण, जो इस मामले में आपके समूहों का परीक्षण है, chi2अंडर है Discrimination Indexes। दो संस्करण सूचीबद्ध हैं, एक संभावना अनुपात परीक्षण और एक स्कोर परीक्षण। संभावना अनुपात परीक्षण आमतौर पर सबसे अच्छा माना जाता है। यह एक पैदावार के -value । p0.0363


1
अपने उत्तरों से प्यार करो! अब मेरे डेटा से निपटने के लिए घर की एक झलक है! :) इन सभी दृष्टिकोणों के लिए, जो आप मेरे डेटा के लिए अत्यधिक अनुशंसा करेंगे, विशेष रूप से पर्याप्त सांख्यिकीय शक्ति प्रदान करने की शर्तें? मैं एक गैर-पैरामीट्रिक दृष्टिकोण यानी क्रुस्कल-वालिस परीक्षण का उपयोग करने के लिए उत्सुक नहीं हूं क्योंकि इसका मतलब यह होगा कि मुझे टाइप I त्रुटि करने की संभावना है? यदि मैं गलत हूं तो मुझे सही करों।
रिक एल।

2
जब मुझे मौका मिलता है तो मैं कुछ और सामग्री यहाँ काम करूँगा, लेकिन नहीं, क्रुस्कल-वालिस परीक्षण शायद आपकी गलतियों के खिलाफ सबसे अच्छी सुरक्षा प्रदान करता है। OTOH, यह आपके पास सबसे शक्तिशाली विकल्प नहीं हो सकता है।
गंग - मोनिका

4
ध्यान दें कि लाइब्रेरी में व्हाइट- carwhite.adjust=T
एडजेस्टेड हेटेरोसेक्शुअलिटी को

3
हाँ, यह केवल इसका उल्लेख करता है lm, लेकिन यह काम करने के लिए भी लगता है aov(विकल्प white.adjustहैं white.adjust=c(FALSE, TRUE, "hc3", "hc0", "hc1", "hc2", "hc4")- अधिक जानकारी के लिए देखें ?hccm)
20

1
@Nxx, नहीं, यह नहीं कि मुझे पता है। यह अंगूठे का एक नियम है; यह सांख्यिकीय साहित्य में एक पेपर में होने की संभावना नहीं है। यह शायद कुछ परिचयात्मक पाठ्यपुस्तकों में है।
गुंग - को पुनः स्थापित मोनिका
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.