विषम डेटा के साथ काम करते समय कई विकल्प उपलब्ध हैं। दुर्भाग्य से, उनमें से कोई भी हमेशा काम करने की गारंटी नहीं है। यहाँ कुछ विकल्प दिए गए हैं जिनसे मैं परिचित हूँ:
- परिवर्तनों
- वेल्श एनोवा
- कम से कम वर्ग
- मजबूत प्रतिगमन
- विषमलैंगिकता लगातार मानक त्रुटियों
- बूटस्ट्रैप
- क्रुशल-वालिस परीक्षण
- ऑर्डिनल लॉजिस्टिक रिग्रेशन
अद्यतन: यहाँ एक रैखिक मॉडल (यानी, एक एनोवा या एक प्रतिगमन) फिटिंग के कुछ तरीकों का प्रदर्शन है 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.445
df = 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.5089
0.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