異分散データに対する一元配置分散分析の代替


36

異なるサイズのサンプル(n_A = 15n_B = 13n_C = 12)を含む藻類バイオマスの3つのグループ(、BC)からのデータがあり、これらのグループが同じ母集団からのものかどうかを比較したいと思います。BABn A = 15 n B = 13 n C = 12CnA=15nB=13nC=12

一元配置分散分析は間違いなく進むべき道ですが、私のデータに対して正規性テストを実施する際には、ヘテロスケダシティーが主な問題のようです。私の生データは、変換なしで、臨界値(F _ {\ rm crit} = 4.16)より非常に高い分散比(Fmax=19.1)を生成したため、一元配置分散分析を実行できません。Fcrit=4.16

また、データを正規化するための変換も試みました。さまざまな変換(対数、平方根、平方)の試行後でも、\ log_ {10}変換による変換後に生成された最低のF _ {\ max}7.16であり、F _ {\ rm crit}と比較して依然として高かった。Fmaxlog107.16Fcrit

ここから誰がここからどこに行くべきかをアドバイスできますか?データで正規化する他の変換方法は考えられません。一元配置分散分析に代わるものはありますか?

PS:私の生データは以下の通りです:

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
F検定は、グループが同じ母集団からではないことを明確に示しています。次のステップは、グループごとに分類されたデータの明確な視覚化と定量的な説明から始めて、この結果を解釈することです。
whuber

コインパッケージには置換テストもあります。ANOVAの場合、oneway_test関数になります。Quick-Rの例:statmethods.net/stats/resampling.html
user16263

回答:


73

異分散データを処理する場合、多くのオプションが利用可能です。残念ながら、それらのどれもが常に機能するとは限りません。以下は、私がよく知っているオプションです。

  • 変換
  • ウェルチ分散分析
  • 重み付き最小二乗
  • ロバスト回帰
  • 異分散性の一貫した標準誤差
  • ブートストラップ
  • クラスカル・ワリス検定
  • 順序ロジスティック回帰

更新: 分散の不均一性/不均一性がある場合に、線形モデル(ANOVAまたは回帰)を近似するいくつかの方法のデモがR あります。

まず、データを見てみましょう。便宜上、これらmy.datastacked.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.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                  

これにより、重み付けされていないANOVA(、)とはわずかに異なる値と値が得られますが、不均一性は十分に対処されています。 Fp4.50890.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.70433CWLS: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


1
あなたの答えが大好き!今、私のデータを処理するための家のかすかな光があります!:)これらのすべてのアプローチの中で、私の種類のデータ、特に十分な統計的検出力を提供する条件に対して、どの方法を強くお勧めしますか?私はタイプIエラーを犯す可能性が高いことを意味するため、ノンパラメトリックアプローチ、つまりクラスカル・ワリス検定を使用することにあまり熱心ではありませんか?私が間違っている場合は修正してください。
リックL. 14年

2
機会があればここでさらに詳しく説明しますが、Kruskal-WallisテストはおそらくタイプIエラーに対する最良の保護を提供します。OTOH、それはあなたが持っている最も強力なオプションではないかもしれません。
GUNG -復活モニカ

4
ライブラリcarには、white.adjust=Tホワイト調整された不均一分散修正標準エラーを使用して不均一分散に対処するように設定するオプションもあることに注意してください
トムウェンゼルズ14年

3
はい、それはについてのみ言及していますlmが、についても機能しているようですaov(オプションwhite.adjustwhite.adjust=c(FALSE, TRUE, "hc3", "hc0", "hc1", "hc2", "hc4")-詳細はを参照してください?hccm
トムウェンゼルズ14年

1
@Nakx、いいえ、私が知っていることではありません。これは経験則です。統計文献の論文には載りそうにない。おそらく、いくつかの入門書にあります。
GUNG -復活モニカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.