異分散データを処理する場合、多くのオプションが利用可能です。残念ながら、それらのどれもが常に機能するとは限りません。以下は、私がよく知っているオプションです。
- 変換
- ウェルチ分散分析
- 重み付き最小二乗
- ロバスト回帰
- 異分散性の一貫した標準誤差
- ブートストラップ
- クラスカル・ワリス検定
- 順序ロジスティック回帰
更新: 分散の不均一性/不均一性がある場合に、線形モデル(ANOVAまたは回帰)を近似するいくつかの方法のデモがR
あります。
まず、データを見てみましょう。便宜上、これらmy.data
をstacked.data
(グループごとに1列で上記のように構成された)と呼ばれる2つのデータフレームにロードします(2つの列があります:values
数字とind
グループインジケーター)。
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
追加することにより、のすべての値およびします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
平方根変換を使用すると、これらのデータが非常に安定します。ここで、パラレルユニバースデータの改善を確認できます。
異なる変換を試すだけでなく、より体系的なアプローチは、Box-Coxパラメーターを最適化することです(ただし、通常、最も近い解釈可能な変換に丸めることをお勧めします)。あなたの場合、平方根またはログいずれかが受け入れられますが、どちらも実際には機能しません。パラレルユニバースデータの場合、平方根が最適です。 λλ=.5λ=0
boxcox(values~ind, data=stacked.data, na.action=na.omit)
boxcox(values~ind, data=stacked.pu.data, na.action=na.omit)
このケースはANOVA(つまり、連続変数なし)であるため、不均一性に対処する1つの方法は、テストで分母の自由度にウェルチ補正を使用することです(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
これにより、重み付けされていないANOVA(、)とはわずかに異なる値と値が得られますが、不均一性は十分に対処されています。 Fp4.5089
0.01749
ただし、重み付き最小二乗は万能薬ではありません。不快な事実の1つは、重みが適切である場合にのみ適切であるということです。これは、とりわけ、アプリオリとして知られていることを意味します。非正規性(スキューなど)や外れ値にも対応していません。多くの場合、仕事の罰金は、しかし、あなたは十分なデータを持っている場合は特に、妥当な精度で分散を推定しますあなたのデータから推定した重みを使用して(これは使用しての考え方に似ているの代わりに、-tableあなたが持っているとき、-tableをかzt50100自由度)、データは十分に正常であり、外れ値はないようです。残念ながら、データが比較的少なく(グループごとに13または15)、スキューがあり、外れ値がある可能性があります。これらが大したことを成し遂げるのに十分なものかどうかはわかりませんが、重み付き最小二乗法と堅牢な方法を組み合わせることができます。分散の尺度として分散を使用する代わりに(特に低外れ値に敏感です)、四分位範囲の逆数を使用できます(各グループの最大50%の外れ値の影響を受けません)。これらの重みは、Tukeyのバイスクエアのような異なる損失関数を使用して、ロバスト回帰と組み合わせることができます。 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
:WLS 0.36673
堅牢、0.35722
; B
:WLS 0.77646
堅牢で0.70433
、C
WLS:0.50554
堅牢0.51845
の手段と、)B
そしてC
より少ない極値によって引っ張られます。
計量経済学では、フーバー・ホワイト(「サンドイッチ」)標準誤差が非常に一般的です。ウェルチ補正のように、これは、事前に分散を知る必要がなく、データから、および/または正しくない可能性のあるモデルを条件として重みを推定する必要がありません。一方、これを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
は、ベータ(ダミーコード)の不均一分散一貫性分散共分散行列を計算します。これは、関数呼び出しの文字が表すものです。標準誤差を得るには、主対角線を抽出し、平方根を取ります。ベータの検定を取得するには、係数の推定値をSEで除算し、結果を適切な分布と比較します(つまり、分布と残差自由度)。 ttt
特にR
ユーザーに対して、@ TomWenseleers は、パッケージ内の?Anova関数が引数をcar
受け入れて、不均一分散エラーを使用して因子の値white.adjust
を取得できることを以下のコメントに示しています。 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の下でののサンプリング分布の経験的推定値を取得します。観測された検定統計量と同じか極端なサンプリング分布の割合は、値です。 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の基本的なノンパラメトリックバージョンは、クラスカルワリス検定です。 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
です。尤度比検定とスコア検定の2つのバージョンがリストされています。尤度比検定は通常、最良と見なされます。それは得の-値を。 p0.0363