มีตัวเลือกจำนวนมากเมื่อจัดการกับข้อมูลที่แตกต่างกัน น่าเสียดายที่ไม่มีการรับประกันว่าจะทำงานได้ตลอดเวลา นี่คือตัวเลือกบางอย่างที่ฉันคุ้นเคย:
- แปลง
- เวลช์ ANOVA
- น้ำหนักน้อยที่สุดกำลังสอง
- การถดถอยที่แข็งแกร่ง
- ข้อผิดพลาดมาตรฐานที่สอดคล้องกัน
- บูต
- การทดสอบ Kruskal-Wallis
- การถดถอยโลจิสติกอันดับ
Update: นี่คือการสาธิตใน R
บางวิธีของการปรับตัวแบบเชิงเส้น (เช่น ANOVA หรือการถดถอย) เมื่อคุณมีความแตกต่างของ heteroscedasticity / heterogeneity ของความแปรปรวน
เริ่มต้นด้วยการดูข้อมูลของคุณ เพื่อความสะดวกฉันได้โหลดมันลงในสองเฟรมข้อมูลที่เรียกว่า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
คุณคิดว่าจะใช้การแปลงเช่นล็อกหรือรากที่สองเพื่อสร้างความแปรปรวนให้คงที่ ที่จะใช้งานได้ในบางกรณี แต่การแปลงรูปแบบBox-Cox จะทำให้เกิดความแปรปรวนโดยการบีบอัดข้อมูลแบบไม่สมมาตรบีบทั้งข้อมูลลงด้วยข้อมูลสูงสุดที่บีบมากที่สุดหรือบีบให้สูงที่สุด ดังนั้นคุณต้องการความแปรปรวนของข้อมูลของคุณเพื่อเปลี่ยนแปลงด้วยค่าเฉลี่ยสำหรับสิ่งนี้เพื่อให้ทำงานได้อย่างเหมาะสมที่สุด ข้อมูลของคุณมีความแตกต่างกันมาก แต่มีความแตกต่างกันเล็กน้อยระหว่างค่าเฉลี่ยและค่ามัธยฐานเช่นการแจกแจงส่วนใหญ่ทับซ้อนกัน ในฐานะที่เป็นแบบฝึกหัดการสอนเราสามารถสร้างบางอย่างparallel.universe.data
โดยเพิ่มให้กับค่าทั้งหมดและถึง.72.7B
0.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
การใช้การแปลงแบบสแควร์รูททำให้ข้อมูลเหล่านั้นค่อนข้างคงที่ คุณสามารถเห็นการปรับปรุงสำหรับข้อมูลเอกภพคู่ขนานได้ที่นี่:
แทนที่จะลองเปลี่ยนรูปแบบอื่น ๆ วิธีที่เป็นระบบมากกว่านี้คือการปรับพารามิเตอร์ Box-Cox ให้เหมาะสม (แม้ว่าโดยทั่วไปแล้วจะแนะนำให้ปัดเศษให้เป็นรูปแปรที่ใกล้เคียงที่สุด) ในกรณีของคุณทั้งสแควร์รูทหรือบันทึกสามารถยอมรับได้แม้ว่าจะใช้งานไม่ได้ก็ตาม สำหรับข้อมูลเอกภพคู่ขนานรากที่สองนั้นดีที่สุด: λ = 0.5 λ = 0λλ = .5λ = 0
boxcox(values~ind, data=stacked.data, na.action=na.omit)
boxcox(values~ind, data=stacked.pu.data, na.action=na.omit)
เนื่องจากกรณีนี้เป็น ANOVA (เช่นไม่มีตัวแปรต่อเนื่อง) วิธีหนึ่งที่จะจัดการกับความแตกต่างคือการใช้การแก้ไข Welchเพื่อองศาอิสระของส่วนในการทดสอบ (NB, ค่าเศษส่วนมากกว่า): 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
อัตราผลตอบแทนนี้แตกต่างกันเล็กน้อยและ value กว่า ANOVA ( , ) ที่ ไม่ได้ถ่วงพีFพี4.5089
0.01749
อย่างไรก็ตามน้ำหนักที่น้อยที่สุดไม่ใช่ยาครอบจักรวาล ข้อเท็จจริงที่น่าอึดอัดใจอย่างหนึ่งคือว่ามันถูกต้องหากว่าน้ำหนักนั้นถูกต้องความหมายและเหนือสิ่งอื่นใด มันไม่ได้อยู่ที่ไม่ใช่บรรทัดฐาน (เช่นเอียง) หรือค่าผิดปกติเช่นกัน ใช้น้ำหนักประมาณจากข้อมูลของคุณมักจะปรับการทำงาน แต่โดยเฉพาะอย่างยิ่งถ้าคุณมีข้อมูลมากพอที่จะประเมินความแปรปรวนที่มีความแม่นยำที่เหมาะสม (นี้จะคล้ายคลึงกับความคิดของการใช้ที่โต๊ะแทนที่จะเป็นโต๊ะเมื่อคุณมีหรือt 50 100 NZเสื้อ50100ดีกรีอิสระ) ข้อมูลของคุณเป็นเรื่องปกติและคุณไม่มีค่าผิดปกติใด ๆ น่าเสียดายที่คุณมีข้อมูลค่อนข้างน้อย (13 หรือ 15 ต่อกลุ่ม) ความเบ้และค่าผิดปกติบางอย่าง ฉันไม่แน่ใจว่าสิ่งเหล่านี้ไม่ดีพอที่จะทำให้เป็นเรื่องใหญ่ แต่คุณสามารถผสมกำลังสองน้อยที่สุดกับวิธีที่มีประสิทธิภาพ แทนที่จะใช้ความแปรปรวนเป็นการวัดการแพร่กระจายของคุณ (ซึ่งมีความอ่อนไหวต่อค่าผิดปกติโดยเฉพาะที่มีค่าต่ำ) คุณสามารถใช้ส่วนกลับของช่วงระหว่างควอไทล์ (ซึ่งไม่ได้รับผลกระทบจากค่าผิดปกติสูงสุด 50% ในแต่ละกลุ่ม) น้ำหนักเหล่านี้สามารถรวมกับการถดถอยที่แข็งแกร่งโดยใช้ฟังก์ชันการสูญเสียที่แตกต่างกันเช่น bisquare ของ Tukey: ยังไม่มีข้อความ
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
: WLS 0.36673
, แข็งแกร่ง0.35722
; B
: WLS 0.77646
, แข็งแกร่ง0.70433
; C
: WLS 0.50554
, แข็งแกร่ง0.51845
) ด้วยวิธีการB
และC
ถูกดึงโดยค่าสุดขีดน้อย
ในทางเศรษฐมิติข้อผิดพลาดมาตรฐานของฮูเบอร์ - ไวท์ ("แซนวิช")เป็นที่นิยมมาก เช่นเดียวกับการแก้ไข Welch สิ่งนี้ไม่ต้องการให้คุณทราบความแปรปรวน a-Priori และไม่ต้องการให้คุณประเมินน้ำหนักจากข้อมูลของคุณและ / หรือเกิดขึ้นกับแบบจำลองที่อาจไม่ถูกต้อง ในทางกลับกันฉันไม่ทราบวิธีรวมสิ่งนี้กับ ANOVA ซึ่งหมายความว่าคุณได้รับพวกเขาสำหรับการทดสอบของรหัสจำลองแต่ละตัวเท่านั้นซึ่งทำให้ฉันมีประโยชน์น้อยลงในกรณีนี้ แต่ฉันจะแสดงให้พวกเขาเห็น:
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
คำนวณเมทริกซ์ความแปรปรวนร่วม - แปรปรวนร่วมแบบแปรผันที่สม่ำเสมอสำหรับ Betas ของคุณ (รหัสจำลองของคุณ) ซึ่งเป็นตัวอักษรในฟังก์ชั่นการโทร ในการรับข้อผิดพลาดมาตรฐานคุณจะแยกเส้นทแยงมุมหลักและนำสแควร์รูท ในการรับ test สำหรับ betas ของคุณคุณแบ่งการประมาณค่าสัมประสิทธิ์ของคุณโดย SEs และเปรียบเทียบผลลัพธ์กับ -distribution ที่เหมาะสม(นั่นคือ -distribution กับองศาอิสระที่เหลือของคุณ) t tเสื้อเสื้อเสื้อ
สำหรับR
ผู้ใช้โดยเฉพาะ @TomWenseleers บันทึกในความคิดเห็นด้านล่างว่าฟังก์ชั่น? Anovaในcar
แพคเกจสามารถยอมรับการwhite.adjust
โต้แย้งที่จะได้รับสำหรับปัจจัยที่ใช้ข้อผิดพลาดที่สอดคล้องกัน heteroscedasticity 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
คุณสามารถลองประเมินเชิงประจักษ์ว่าการกระจายตัวตัวอย่างที่แท้จริงของสถิติการทดสอบของคุณนั้นเป็นอย่างไรด้วยการบูตสแตรป ขั้นแรกให้คุณสร้างค่าว่างที่แท้จริงโดยการทำให้ทุกกลุ่มมีความหมายเท่ากันทุกประการ จากนั้นคุณลองสุ่มใหม่พร้อมเปลี่ยนและคำนวณสถิติการทดสอบ ( ) ของคุณในแต่ละตัวอย่างรองเท้าเพื่อรับการประเมินเชิงประจักษ์เกี่ยวกับการกระจายตัวตัวอย่างของภายใต้ค่า Null กับข้อมูลของคุณไม่ว่าสถานะของพวกเขาจะเป็นอย่างไร สัดส่วนของการแจกแจงการสุ่มตัวอย่างที่มากหรือมากเกินกว่าสถิติการทดสอบที่คุณสังเกตเห็นคือค่า : F หน้า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
ในบางวิธีการบูตสแตรปปิ้งเป็นวิธีการลดสมมติฐานขั้นสุดท้ายเพื่อทำการวิเคราะห์พารามิเตอร์ (เช่นหมายถึง) แต่มันจะถือว่าข้อมูลของคุณเป็นตัวแทนที่ดีของประชากรซึ่งหมายความว่าคุณมีขนาดตัวอย่างที่สมเหตุสมผล เนื่องจากของคุณมีขนาดเล็กจึงอาจเชื่อถือได้น้อยลง อาจเป็นการป้องกันที่ดีที่สุดต่อการไม่เป็นมาตรฐานและความแตกต่างคือการใช้การทดสอบที่ไม่ใช่พารามิเตอร์ ANOVA ที่ไม่ใช่พารามิเตอร์พื้นฐานของ ANOVA คือการทดสอบ Kruskal-Wallis : 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
แม้ว่าการทดสอบ Kruskal-Wallis เป็นการป้องกันที่ดีที่สุดต่อความผิดพลาดประเภท 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