Rでブートストラップを使用してp値を計算する


28

「ブート」パッケージを使用して、近似の両側ブートストラップp値を計算しますが、結果はt.testを使用したp値から遠すぎます。Rコードで何が間違っていたかわかりません。誰かが私にこのヒントを教えてください

time = c(14,18,11,13,18,17,21,9,16,17,14,15,
         12,12,14,13,6,18,14,16,10,7,15,10)
group=c(rep(1:2, each=12))
sleep = data.frame(time, group)

require(boot)
diff = function(d1,i){
    d = d1[i,]
    Mean= tapply(X=d$time, INDEX=d$group, mean)
    Diff = Mean[1]-Mean[2]
    Diff
}

set.seed(1234)
b3 = boot(data = sleep, statistic = diff, R = 5000, strata=sleep$group)

pvalue = mean(abs(b3$t) > abs(b3$t0))
pvalue 

両側のブートストラップp値(pvalue)= 0.4804ですが、t.testの両側p値は0.04342です。両方のp値は約11倍の差があります。これはどのように起こりますか?


b3 $ t0に2つのエントリがあるのはなぜですか?
西安

1
それはコルネームです!
エルビス

2
値を誤って計算しています。ドキュメンテーションでは、は観測された統計であり、表記が示すようにヌル分布ではないと述べています。nullの下のサンプリングdist-nの推定値を考え出す必要があります。詳細については私の答えをご覧ください。バイアス未修正テストを試してください。t 0pt0mean(abs(b3$t0) < abs(b3$t-mean(b3$t)))
AdamO

回答:


31

ブートストラップを使用して、観測データの経験的分布の下でデータを生成しています。これは、2つの平均の差に信頼区間を与えるのに役立ちます。

> quantile(b3$t,c(0.025,0.975))
     2.5%     97.5% 
0.4166667 5.5833333 

値を取得するには、帰無仮説の下で順列を生成する必要があります。これは、たとえば次のように実行できます。p

diff2 = function(d1,i){
    d = d1; 
    d$group <- d$group[i];  # randomly re-assign groups
    Mean= tapply(X=d$time, INDEX=d$group, mean)
    Diff = Mean[1]-Mean[2]
    Diff
}

> set.seed(1234)
> b4 = boot(data = sleep, statistic = diff2, R = 5000)
> mean(abs(b4$t) > abs(b4$t0))
[1] 0.046

このソリューションでは、グループのサイズは固定されていません。最初のグループセットからブートストラップすることにより、各個人にグループをランダムに再割り当てします。私には合法的なようですが、より古典的な解決策は各グループの個人の数を修正することですので、ブートストラップの代わりにグループを並べ替えるだけです(これは通常、グループのサイズが事前に固定されている実験のデザインによって動機付けられます):

> R <- 10000; d <- sleep
> b5 <- numeric(R); for(i in 1:R) { 
+    d$group <- sample(d$group, length(d$group)); 
+    b5[i] <- mean(d$time[d$group==1])-mean(d$time[d$group==2]); 
+ }
> mean(abs(b5) > 3)
[1] 0.0372

5
これは技術的には置換テストであり、ブートストラップp値ではありません。
AdamO

@AdamOこの回答に示されているのは置換テスト(およびわずかに変更されたバリアント)です。これは、リサンプリング中にグループがプールされるためです。対照的に、ブートストラップベースのテストでは、同じグループのデータのみを使用して各グループの値をサンプリングする必要があります。:ここではそれを行う方法を説明する1つの答えですstats.stackexchange.com/a/187630/28666が
アメーバは、モニカを復活させる

@amoebaあなたがリンクする答えは置換テストでもあると思います。それらはリサンプリングを含む限りブートストラップに関連しています。報告するのはまったく問題ありませんが、報告には2つの方法が使用されています。ノンパラメトリックブートストラップは、帰無仮説の下でデータを生成することは技術的に不可能です。ブートストラップ分布からp値が生成される方法については、私の回答ご覧ください
-AdamO

@AdamOそれは用語の問題だと思いますが、リンクされた回答に記載されている手順が「順列」テストと呼ばれることはありません。グループのみ。
アメーバは、モニカの復活を

1
エルビス、あなたの答えの最初のコードは置換テストでもあると思います。リサンプリングすると、グループが一緒にプールされます!これが、置換テストを定義するものです。
アメーバは、モニカの復活を

25

Elvisの答えは順列に依存していますが、私の意見では、元のブートストラップアプローチの何が問題なのかは明確ではありません。ブートストラップのみに基づくソリューションについて説明します。

元のシミュレーションの重大な問題は、ブートストラップが常にテスト統計の真の分布を提供することです。ただし、p値を計算する場合、取得した検定統計量の値をH0の下の分布と比較する必要があります。つまり、真の分布と比較する必要はありません。

[明確にしましょう。たとえば、古典的なt検定の検定統計量Tは、H0の下で古典的な「中心」t分布を持ち、一般に非中心分布を持つことが知られています。しかし、Tの観測値が古典的な「中心」t分布と比較されるという事実に誰もが精通しています。つまり、Tと比較するために真の[非中心] t分布を得ようとはしません。

検定統計量Mean [1] -Mean [2]の観測値 "t0"は、ブートストラップされたサンプル "t"の中心に非常に近いため、p値0.4804は非常に大きくなります。ブートストラップされたサンプル "t"はMean [1] -Mean [2]の実際の分布をエミュレートするため、それは自然であり、通常は常にそうです(つまり、H0の有効性に関係なく)。しかし、上記(およびエルビス)で述べたように、本当に必要なのは、H0の下でのMean [1] -Mean [2]の分布です。それは明らかです

1)H0の下では、Mean [1] -Mean [2]の分布は0を中心とします。

2)その形状はH0の有効性に依存しません。

これらの2つのポイントは、H0の下でのMean [1] -Mean [2]の分布が、ブートストラップされたサンプル "t"によってエミュレートされ、0を中心とすることを意味します。

b3.under.H0 <- b3$t - mean(b3$t)

対応するp値は次のようになります。

mean(abs(b3.under.H0) > abs(b3$t0))

これにより、 "非常に良い"値0.0232が得られます。:-)

上記の「2)」のポイントは、検定統計量の「翻訳の等分散」と呼ばれ、一般に保持する必要はありません。つまり、一部のテスト統計では、ブートストラップされた「t」をシフトしても、HO!でのテスト統計の分布の有効な推定値は得られません この議論、特にP. Dalgaardの返信をご覧ください:http ://tolstoy.newcastle.edu.au/R/e6/help/09/04/11096.html

テストの問題は、テスト統計の完全に対称な分布をもたらしますが、テスト統計の歪んだブートストラップ分布の場合、TWO-SIDED p値の取得にはいくつかの問題があることに留意してください。もう一度、上記のリンクを読んでください。

[そして最後に、私はあなたの状況で「純粋な」置換テストを使用します。すなわち、エルビスの答えの後半。:-)]


17

ブートストラップCIとp値を計算する方法は多数あります。主な問題は、帰無仮説ではブートストラップがデータを生成できないことです。順列検定は、これに代わる実行可能なリサンプリングに基づいています。適切なブートストラップを使用するには、検定統計量のサンプリング分布についていくつかの仮定を行う必要があります。

β0=β^β^β0=β^β^

通常のブートストラップ

一つのアプローチは、通常のブートストラップブートストラップ分布の平均と標準偏差をとり、分布をシフトさせると、元のブートストラップ試料中の推定の点でヌル分布から通常パーセンタイルを使用してヌル下サンプリング分布を計算します。これは、ブートストラップの分布が正常である場合の合理的なアプローチであり、通常はここで目視検査で十分です。このアプローチを使用した結果は、通常、不均一分散および/または有限サンプル分散の仮定に対してロバストな、ロバストまたはサンドイッチベースのエラー推定に非常に近いです。通常の検定統計量の仮定は、次に説明するブートストラップ検定の仮定のより強い条件です。

パーセンタイルブートストラップ

F0)推定値からブートストラップ分布を減算し、を使用して、推定値よりも「極端な」DSNHの割合を計算します2×F0β^1F0β^

スチューデント化されたブートストラップ

値を計算する最も簡単なブートストラップソリューションは、スチューデント化されたブートストラップを使用することです。ブートストラップの反復ごとに、統計その標準誤差を計算し、学生の統計を返します。これにより、シスとp値を非常に簡単に計算するために使用できる仮説のブートストラップされた学生分布が得られます。これはまた、バイアス補正されたブートストラップの背後にある直感の根底にあります。外れ値の結果は、対応する高い分散によって重みづけされるため、t分布はヌルの下ではるかに簡単にシフトします。p

プログラミング例

例として、cityブートストラップパッケージのデータを使用します。ブートストラップ信頼区間は、次のコードを使用して計算されます。

ratio <- function(d, w) sum(d$x * w)/sum(d$u * w)
city.boot <- boot(city, ratio, R = 999, stype = "w", sim = "ordinary")
boot.ci(city.boot, conf = c(0.90, 0.95),
        type = c("norm", "basic", "perc", "bca"))

この出力を生成します:

BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 999 bootstrap replicates

CALL : 
boot.ci(boot.out = city.boot, conf = c(0.9, 0.95), type = c("norm", 
    "basic", "perc", "bca"))

Intervals : 
Level      Normal              Basic         
90%   ( 1.111,  1.837 )   ( 1.030,  1.750 )   
95%   ( 1.042,  1.906 )   ( 0.895,  1.790 )  

Level     Percentile            BCa          
90%   ( 1.291,  2.011 )   ( 1.292,  2.023 )   
95%   ( 1.251,  2.146 )   ( 1.255,  2.155 )  
Calculations and Intervals on Original Scale

通常のブートストラップの95%CIは、次の計算によって取得されます。

with(city.boot, 2*t0 - mean(t) + qnorm(c(0.025, 0.975)) %o% sqrt(var(t)[1,1]))

p値はこうして得られます:

> with(city.boot, pnorm(abs((2*t0 - mean(t) - 1) / sqrt(var(t)[1,1])), lower.tail=F)*2)
[1] 0.0315

95%の通常のCIにはヌル比の値1が含まれていないことに同意します。

パーセンタイルCIが取得されます(タイの方法によるいくつかの違いはあります)。

quantile(city.boot$t, c(0.025, 0.975))

パーセンタイルブートストラップのp値は次のとおりです。

cvs <- quantile(city.boot$t0 - city.boot$t + 1, c(0.025, 0.975))
mean(city.boot$t > cvs[1] & city.boot$t < cvs[2])

0.035のapを与えます。これは、値から1を除外するという点で信頼区間とも一致します。一般に、パーセンタイルCIの幅は通常のCIとほぼ同じ幅であり、パーセンタイルCIはnullから離れているため、パーセンタイルCIがより低いp値を提供することは一般的に観察できません。これは、パーセンタイル方式のCIの基礎となるサンプリング分布の形状が非正規であるためです。


@AdamOは非常に興味深い回答ですが、いくつか例を挙げていただけますか?Rでは、関数boot.ciを使用し、引数 "type"を使用してスチューデント化されたCIを選択できます(BCA CIも選択できます)。しかし、どのようにしてp値を計算できますか?推定値または検定統計量を使用していますか?私が持っていた同様の質問の回答をいただければ幸いです。
ケビンザルカ

1
スチューデント化されたブートストラップの利点を明確に説明するために+1。
eric_kernfeld

@KevinOunetブートパッケージのCIからp値を複製する2つの例を挙げました。これは役立ちますか?
AdamO

1
@AdamO、ありがとうございます、本当に役立ちます!スチューデント化されたブートストラップの最後の例を提供できますか?
ケビンザルカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.