Heterossedastik verilerle çalışırken bir dizi seçenek mevcuttur. Ne yazık ki, hiçbiri daima işe yaramaz. İşte aşina olduğum bazı seçenekler:
- dönüşümler
- Welch ANOVA
- ağırlıklı en küçük kareler
- güçlü regresyon
- heteroscedastisite tutarlı standart hatalar
- çizme atkısı
- Kruskal-Wallis testi
- sıralı lojistik regresyon
Güncelleme: Burada, heterossedastisite / varyansın heterojenitesine sahip olduğunuzda doğrusal bir modele (yani bir ANOVA veya bir regresyon) uymanın bazı yollarını gösteren bir gösteri bulunmaktadır R
.
Verilerinize göz atarak başlayalım. Kolaylık sağlamak için, bunları my.data
(grup başına bir sütunla yukarıda yapılandırılmış olan) adı verilen iki veri çerçevesine ( stacked.data
iki sütun içeren: values
sayılarla ve ind
grup göstergeli) yükledim.
Levene'nin testiyle heteroserdastisiteyi resmi olarak test edebiliriz :
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
Tabii ki, heteroscedasticity var. Grupların varyanslarının ne olduğunu görmek için kontrol ederiz. Temel kural, lineer modellerin, maksimum varyansın minimum varyansın fazla olmadığı sürece, varyansın heterojenliğine oldukça sağlam olmasıdır , bu yüzden bu oranı da bulacağız: 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
Sizin varyansları, büyük ile büyük ölçüde farklılık B
olma, en küçük, . Bu problemli bir heteroscedsaticity seviyesidir. 19×A
Varyansı dengelemek için log veya karekök gibi dönüşümleri kullanmayı düşündünüz . Bu, bazı durumlarda işe yarayacaktır, ancak Box-Cox tipi dönüşümler, verileri asimetrik olarak sıkarak, aşağı doğru sıkarak veya en fazla sıkılan en yüksek veriyle aşağı doğru sıkıştırarak varyansı dengelemektedir. Bu nedenle, bunun en iyi şekilde çalışması için ortalamayı değiştirmek için verilerinizin varyansına ihtiyacınız vardır. Verileriniz varyansta çok büyük bir fark yaratıyor, ancak araçlar ve medyanlar arasında nispeten küçük bir fark var, yani dağılımlar çoğunlukla örtüşüyor. Bir öğretim egzersiz olarak, bazı oluşturabilir parallel.universe.data
ekleyerek herkese değer ve için2.7B
.7C
nasıl işe yarayacağını göstermek için:
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
Karekök dönüşümünü kullanmak bu verileri oldukça iyi dengeler. Paralel evren verilerinin gelişimini burada görebilirsiniz:
Sadece farklı dönüşümler denemek yerine, daha sistematik bir yaklaşım, Box-Cox parametresini optimize etmektir (bunu en yakın yorumlanabilen dönüşüme yuvarlamak için tavsiye edilse de). Sizin durumunuzda , her ikisi de işe , ya karesel kök, ya da log, kabul edilebilir. Paralel evren verileri için karekök en iyisidir: λλ=.5λ=0
boxcox(values~ind, data=stacked.data, na.action=na.omit)
boxcox(values~ind, data=stacked.pu.data, na.action=na.omit)
Bu durum bir ANOVA (yani sürekli değişkenler olmadığından), heterojenlikle baş etmenin bir yolu Welch düzeltmesini testindeki serbestlik derecelerine göre kullanmaktır (nb , bunun yerine kesirli bir değer ): 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
Daha genel bir yaklaşım ağırlıklı en küçük kareler kullanmaktır . Bazı gruplar ( B
) daha fazla yayıldığından, bu gruplardaki veriler, ortalamanın konumu hakkında diğer gruplardaki verilerden daha az bilgi sağlar. Her veri noktası için bir ağırlık sağlayarak modelin bunu dahil etmesine izin verebiliriz. Yaygın bir sistem, grup varyansının karşılığını ağırlık olarak kullanmaktır:
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
Bu , ağırlıklandırılmamış ANOVA'dan ( , ) biraz farklı ve değerleri verir , ancak heterojenliği iyi ele almıştır: Fp4.5089
0.01749
Ancak ağırlıklı en küçük kareler her derde deva değildir. Rahatsız edici bir gerçek, ağırlıkların sadece doğru olması, yani diğer şeylerin yanı sıra, a priori olarak bilinenlerin doğru olması. Normallik (çarpık gibi) veya aykırı değerlere de değinmez. Genellikle iş ince olsa da, yeterli veriye sahip özellikle makul hassasiyetle varyansı tahmin etmek olacaktır verilerden tahmin ağırlıkları kullanmak (bu kullanma fikri benzerdir yerine ait masaları sen varken masaları veyazt50100serbestlik dereceleri), verileriniz yeterince normal ve hiçbir aykırı değeriniz yok. Ne yazık ki, görece az sayıda veriniz (grup başına 13 veya 15), biraz eğri ve muhtemelen biraz aykırı değeriniz var. Bunların büyük bir anlaşma yapacak kadar kötü olduğundan emin değilim, ancak ağırlıklı en küçük kareleri sağlam yöntemlerle karıştırabilirsiniz . Yayılmanın ölçüsü olarak varyansı kullanmak yerine (ki bu, aykırı değerlere (özellikle düşük ) duyarlıdır ), çeyrekler arası aralığın karşıtlığını (her gruptaki% 50'ye kadar aykırılıklardan etkilenmez) kullanabilirsiniz. Bu ağırlıklar daha sonra Tukey'nin bisquare gibi farklı bir kayıp fonksiyonu kullanılarak güçlü regresyon ile birleştirilebilir: 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 *
Buradaki ağırlıklar aşırı değildir. (Tahmin edilen biçimde grup, biraz farklıdır A
: WLS'nin 0.36673
, sağlam 0.35722
; B
: WLS 0.77646
, sağlam 0.70433
, C
WLS'nin: 0.50554
sağlam 0.51845
vasıtası ile) B
ve C
daha az uç değerler ile çekilmektedir.
Ekonometride Huber-White ("sandviç") standart hatası çok popülerdir. Welch düzeltmesi gibi, bu da sizin a-priori'nin varyanslarını bilmenizi gerektirmez ve verilerinizden ve / veya doğru olmayan bir modele bağlı olduğunuzdan ağırlıklarını tahmin etmenizi gerektirmez. Öte yandan, bunun bir ANOVA ile nasıl birleştirileceğini bilmiyorum, bu da onları yalnızca sahte kodların testleri için alacağınız anlamına gelir; bu da beni bu durumda daha az yardımcı olur.
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
İşlev vcovHC
, fonksiyon çağrısındaki harflerin ne anlama geldiğini gösteren, betalarınız için heterosik veri tutarlı tutarlı varyans-kovaryans matrisini hesaplar. Standart hatalar almak için ana köşegeni çıkarın ve kare kökleri alın. Betalarınız için testi almak için, katsayı tahminlerinizi SE'lere bölün ve sonuçları uygun dağılımına (yani, artık serbestlik derecelerinizle dağılımı) karşılaştırın. ttt
İçin R
aşağıdan yorumlarda özellikle kullanıcılar, @TomWenseleers notlar ? Anova işlevi car
paketinin bir kabul edebilir white.adjust
bir olsun argüman varyans uyumlu hatalarını kullanarak faktör için değerini gösterir. 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
Test istatistiklerinizdeki gerçek örnekleme dağılımının bootstrapping işlemi ile nasıl göründüğünün ampirik bir tahminini almaya çalışabilirsiniz . İlk olarak, tüm grup araçlarının tam olarak eşit olmasını sağlayarak gerçek bir boş değer yaratırsınız. Daha sonra, değiştirme ile yeniden örnekleme yaparsınız ve normalde veya homojenliğe ilişkin durumları ne olursa olsun, verilerinizle boş olarak örnekleme dağılımının ampirik bir tahminini almak için her bir örneklem üzerindeki test istatistiğinizi ( ) hesaplarsınız . Gözlemlenen test istatistiğinizden aşırı veya daha aşırı olan örnekleme dağılımının oranı değeridir: 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
Bazı açılardan, önyükleme, parametrelerin analizini yapmak için nihai azaltılmış varsayım yaklaşımıdır (örneğin, ortalamalar), ancak verilerinizin popülasyonun iyi bir temsili olduğunu, yani makul bir örneklem büyüklüğünüz olduğunu varsaymaktadır. Senin bu yana 'ın küçük, daha az güvenilir olabilir. Muhtemelen normal olmayan ve heterojenliğe karşı en yüksek koruma parametrik olmayan bir test kullanmaktır. ANOVA'nın parametrik olmayan temel versiyonu Kruskal-Wallis testidir : 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 testi kesinlikle tip I hatalara karşı en iyi koruma olmasına rağmen, yalnızca tek bir kategorik değişkenle kullanılabilir (yani, sürekli yordayıcılar veya faktör tasarımları yoktur) ve tartışılan tüm stratejilerin en az gücüne sahiptir. Parametrik olmayan bir başka yaklaşım da sıradan lojistik regresyon kullanmaktır . Bu, birçok insan için garip görünüyor, ancak yalnızca yanıt verilerinizin, kesinlikle yaptıkları meşru sıra bilgileri içerdiğini veya yukarıdaki diğer tüm stratejilerin de geçersiz olduğunu varsaymanız gerekir:
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
Bu çıkışından net olmayabilir, ama bu durumda da grupların testi olan bir bütün olarak modelin testidir chi2
altında Discrimination Indexes
. İki versiyon listelenmiştir, olasılık oranı testi ve puan testi. Olabilirlik oranı testi genellikle en iyi olarak kabul edilir. Bir değeri verir . p0.0363