【統計】Wilcoxonの順位和検定とマンホイットニーのU検定

Wilcoxonの順位和検定(Wilcoxon rank sum test)とマンホイットニーのU検定(Mann–Whitney U test)について。

【目次】

 

両方とも2標本の分布の位置のズレを評価するノンパラメトリックな手法。
これらは等価な手法であり、同じ結果が得られる。

一方、パラメトリックな手法としては t検定が代表的。

cochineal19.hatenablog.com

 

帰無仮説、対立仮設


  • 帰無仮説  H_{0}: 2標本の確率分布に差がない(ズレていない)。
  • 対立仮設  H_{1}: 2標本の確率分布に差がある(ズレている)。

※2標本は同じ形状の確率分布であるという前提で、分布の位置のズレを見ている。正規分布に依存しないのが特徴。

 

計算式等


Wilcoxonの順位和検定とマンホイットニーのU検定は等価であり、同じ結果が得られるが、統計量と期待値に違いがある。

 

順位和

統計量の算出前に、先ず、比較したい2標本の観測値に全体順位(Rank)をつけて、標本ごとの合計(順位和)を算出する。観測値にタイ(同一順位)がある場合は、順位の平均値をつける。
※以降、本記事では標本をA、B、順位和を R_{A} R_{B} とする。
 

Wilcoxonの順位和検定

\quad W = min \left( R_{A},\  R_{B} \right)

\quad E[ W] =\dfrac{n_{A}\left( n_{A}+n_{B}+1\right) }{2}\qquad※R_{B}\verb|の方が小さければ  |\  \dfrac{n_{B}\left( n_{B}+n_{A}+1\right) }{2}

\quad Var[ W] =\dfrac{n_{A}n_{B}\left( n_{A}+n_{B}+1\right) }{12} - \dfrac{n_{A}n_{B}}{12\left( n_{A}+n_{B}\right) \left( n_{A}+n_{B}-1\right) } \sum  \left( t^{3}_{i}-t_{i}\right)

\quad z = \dfrac{W-E[ W] }{\sqrt{Var [ W] }} 

  

マンホイットニーのU検定

\quad U = min \left( R_{A}-\dfrac{n_{A}\left( n_{A}+1\right) }{2} ,\quad R_{B}-\dfrac{n_{B}\left( n_{B}+1\right) }{2} \right)

\quad E[ U] =\dfrac{n_{A} n_{B}}{2}

\quad Var[ U] =\dfrac{n_{A}n_{B}\left( n_{A}+n_{B}+1\right) }{12} - \dfrac{n_{A}n_{B}}{12\left( n_{A}+n_{B}\right) \left( n_{A}+n_{B}-1\right) } \sum \left( t^{3}_{i}-t_{i}\right)

\quad z = \dfrac{U-E[ U] }{\sqrt{Var [ U] }} 

 

Wilcoxonの順位和検定もマンホイットニーのU検定も分散は同じ。
分散の第2項の  \dfrac{n_{A}n_{B}}{12\left( n_{A}+n_{B}\right) \left( n_{A}+n_{B}-1\right) } \sum  \left( t^{3}_{i}-t_{i}\right) はタイ(同一順位)の補正項であり、式中の t が同一値の個数を示す。
例えば、{10,10,11,12,12,12} のデータがあるとき、10が2つ、11が1つ、12が3つになるため、それぞれ  t=2、t=1、t=3 となり、  t^{3}-t の計算で  2^{3}-2=6、1^{1}-1=0、3^{3}-3=24 になる。
タイがない数値は解が0になり、タイにだけ働くことが分かる(タイがまったくない場合は第2項の解全体が0)。
 

計算例


今回は次の架空データAとBを比較してみる。

 A {4, 9, 10, 11, 12, 13, 13, 15, 18, 18, 20}
 B {16, 16, 17, 19, 19, 22, 22, 23, 25}

Excelでの計算。

f:id:cochineal19:20201215223427p:plain

Wilcoxon-Mann–Whitney test
Excelの簡単な説明。
・A列:標本のグループ名
・B列:観測値。小さい順にならべている。
・C列:同値の数を上から数ている(セルC4:=IF(B3<>B4,1,D3+1))。
・D列:同値の最終行のみ表示している(セルD4:=IF(B4=B5,"",C4))。
・E列:分散の補正項用(セルE4:=IF(D4<>"",D4^3-D4,""))
・G列:標本Aの順位(セルG4:=IF($A4=G$3, RANK.AVG($B4,$B:$B,1), ""))
・H列:標本Bの順位(セルH4:=IF($A4=H$3, RANK.AVG($B4,$B:$B,1), ""))

 

Wilcoxonの順位検定の場合

  • W:順位和  R_{A}=77,\ R_{B}=133 だったため、 R_{A}=77(小さい方)をWとする。
  • 期待値: R_{A} の方が小さいため、次の式で計算する。
     E[ W] =\dfrac{n_{A}\left( n_{A}+n_{B}+1\right) }{2} =\dfrac{11\left( 11+9+1\right) }{2}=115.5
  • 分散:タイがあるため補正(E列およびK15参照)した値を導出する。
     Var[ W] = 172.59868
  • z値:z= (77-115.5)/sqrt(172.6) = -38.5/sqrt(172.6) = -2.93050。
  • p値:標準正規分布を使って p=0.00338。
    セルN23:=2*(1-NORM.S.DIST(ABS(N22),TRUE)) 

 

マンホイットニーのU検定の場合

  • U: U_{A}=11,\ U_{B}=88 だったため、  U_{A}=11(小さい方)をUとする。
  • 期待値:計算式のとおり (11×9)/2 = 49.5。
  • 分散:Wilcoxonと同じ。タイを補正した値を導出する。 Var[ W] = 172.59868
  • z値:z= (11-49.5)/sqrt(172.6) = -38.5/sqrt(172.6) = -2.93050。
  • p値:標準正規分布を使って p=0.00338。
    セルK23:=2*(1-NORM.S.DIST(ABS(K22),TRUE))

 

z値の導出過程で、Wilcoxonもマンホイットニーも「-38.5/sqrt(172.6)」となり、等価になることが分る。どちらの検定も今回の架空データでは2標本に差があり(p<0.01)。

 

Rでの実行:

> ads <- data.frame(
+   TRT01P <- c("A","A","A","A","A","A","A","A","B","B","B","A","A","B","B","A","B","B","B","B")
+   ,AVAL  <- c(4,9,10,11,12,13,13,15,16,16,17,18,18,19,19,20,22,22,23,25)
+ )
> ads$TRT01PF <- factor(ads$TRT01P)
> wilcox_test(AVAL ~ TRT01PF, data=ads, method="exact")

	Asymptotic Wilcoxon-Mann-Whitney Test

data:  AVAL by TRT01PF (A, B)
Z = -2.9305, p-value = 0.003384
alternative hypothesis: true mu is not equal to 0

Rのデフォルトで使えるwilcoxon.testは値が全然一致しない。詳細不明。
coinパッケージのwilcoxon_testを使った方が良い。

 

SASでの実行:

data ads;
  do AVAL = 4,9,10,11,12,13,13,15,18,18,20; TRT01PN=1; output; end;
  do AVAL = 16,16,17,19,19,22,22,23,25; TRT01PN=2; output; end;
run;
proc sort data=ads: by AVAL TRT01PN; run;
proc npar1way data=ads wilcoxon correct=no /*今回は連続修正なし*/;
  class TRT01PN;
  var   AVAL;
run;

f:id:cochineal19:20201219133544p:plain

z値の符号が逆転しているが、Pr > |z| なのでp値は同じ。

SAS社のサイトに詳細がないので不明だが、
T近似のp値は、おそらくz統計量と自由度N-1で算出している。

 = T.DIST.2T(2.9305, 20-1) ≒ 0.008583004

 

プログラムコード


■ Rのコード

library(coin)
wilcox_test(AVAL ~ TRT01PF, data=ads, method="exact")

 

SASのコード

proc npar1way data=[InputDS] wilcoxon correct=no /*連続修正無の場合correct=noを追加*/;
class TRT01PN;
var AVAL;
output out = [OutDS] wilcoxon; /* Z_WIL, P2_WILを取得。*/
run;

 

Pythonのコード

整備中

 

W統計量とU統計量の関係


W統計量とU統計量には次の関係があり等価。

\qquad W-\dfrac{n_{A}\left( n_{A}+1\right) }{2}=U

 <再掲>
 Wilcoxonの順位和検定
\qquad W = min \left( R_{A},\  R_{B} \right)
 マンホイットニーのU検定
\qquad U = min \left( R_{A}-\dfrac{n_{A}\left( n_{A}+1\right) }{2} ,\quad R_{B}-\dfrac{n_{B}\left( n_{B}+1\right) }{2} \right)

 

なお、本検定は同じ形状の確率分布のズレを見ているため、2標本の確率分布が同じ形であれば平均に差があると解釈ができる。

 

参考


http://ex.osaka-kyoiku.ac.jp/~fujii/fujiwara/C/np/WU1.pdf

http://ex.osaka-kyoiku.ac.jp/~fujii/fujiwara/C/np/Wsyoumei.pdf

https://www.sas.com/content/dam/SAS/ja_jp/doc/event/sas-user-groups/usergroups2015-b-03.pdf

https://support.sas.com/documentation/onlinedoc/stat/142/npar1way.pdf

 


サイトマップ

cochineal19.hatenablog.com

 

【統計】コクラン-アーミテージ検定(Cochran-Armitage test)

Cochran-Armitage test(コクラン-アーミテージ検定またはCA検定)について。

【目次】

 

CA検定は、割合の増加/減少傾向を評価する傾向性の検定。 
検定の中身は、割合を目的変数とした回帰分析であり、回帰直線の傾きが0であるかどうかを見ている。
なお、目的変数が連続値の場合は、Jonckheere-Terpstra trend test(ヨンクヒール-タプストラ検定、またはヨンキー検定)等が用いられる。

【統計】ヨンキー検定(傾向性検定) - こちにぃるの日記

 

帰無仮説、対立仮設


  • 帰無仮説  H_{0}: p_{1}=p_{2}=...=p_{k}(直線の傾きが0)
  • 対立仮設  H_{1}: p_{1} \leqq p_{2} \leqq ... \leqq p_{k}(直線の傾きが0でない)

 

計算式等


CA検定では  \chi^{2} 統計量を用いる。
通常の  \chi^{2} 検定の統計量を  \chi _{Total}^{2}、CA検定で扱う統計量を  \chi _{Slope}^{2}、残差を  \chi _{Resid}^{2} とすると次の式が成り立つ。 

\quad \chi _{Total}^{2} = \chi _{Slope}^{2} + \chi _{Resid}^{2}

これら  \chi^{2} 統計量の導出は下表のとおり。

   \chi ^{2} 統計量 自由度(df)
Slope  \chi _{Slope}^{2}= S_{sp}^{2}/S_{ss}  1
Residual  \chi _{Resid}^{2}=\chi _{Total}^{2} - \chi _{Slope}^{2}  k-1-1
Total  \chi _{Total}^{2}=S_{pp}  k-1

表の平方和は次の計算式。

\quad S_{ss}= \sum \{ n_{i} w \left( s_{i} - \overline{s} \right) ^{2} \}

\quad S_{pp}= \sum \{ n_{i} w \left( p_{i} - \overline{p} \right) ^{2} \}

\quad S_{sp}= \sum \{ n_{i} w \left( s_{i} - \overline{s} \right) \left( p_{i} - \overline{p} \right) \}

\quad \overline{p}= \dfrac{A}{N}= \dfrac{\sum a_{i}}{\sum n_{i}},\quad p_{i}= \dfrac{a_{i}}{n_{i}} 

\quad \overline{s}= \dfrac{\sum \left( n_{i}  s_{i} \right)}{N} 

\quad w= \dfrac{1}{\overline{p} \left( 1-\overline{p} \right)}

  ※s_{i}=当該水準でのスコア、n_{i}=当該水準での全体数、 a_{i}=当該水準での該当数

 

計算例


簡単なデータで計算方法を確認。
今回は、病気Xの病状(Score)が悪いほど死亡発生確率(Yes/Total)が増加する傾向があるかを見てみる(架空データ)。
※計算の理解のためScoreにも値を指定。特に指定がない場合は1,2,3,4...と等間隔な値を仮定する。

■ 観測度数

Score Yes No Total Prop.
1 10 100 110 0.091
2 20 80 100 0.200
3.5 20 60 80 0.250
5.5 20 40 60 0.333

先ず、全体の基本情報;
例数  N=110+100+80+60=350、死亡数 A=10+20+20+20=70、死亡割合  \overline{p}=70/350=0.2 

CA検定では、割合を目的変数とした回帰分析を行うが、手法として割合の標準誤差の逆数を重みとした「重み付き最小二乗法」を用いる。この重みと各スコアの重み付きN数は次のとおり。
 \quad w=\dfrac{1}{\overline{p}(1-\overline{p})}=\dfrac{1}{0.2×0.8}=6.25
 \quad \verb|Score 1  : | n_{1} w=110 \times 6.25 = 687.5
 \quad \verb|Score 2  : | n_{2} w=100 \times 6.25 = 625.0
 \quad \verb|Score 3.5 : | n_{3} w=80 \times 6.25 = 500.0
 \quad \verb|Score 5.5 : | n_{4} w=60 \times 6.25 = 375.0

重みを使った回帰直線:

f:id:cochineal19:20210207155857p:plain

 ※プロットサイズ:各スコアの重み付き例数
 ※縦の点線:全体の平均スコア \overline{s}= \sum \left( n_{i} s_{i} \right)/N
 ※横の点線:全体の確率 \overline{p}= A/N

 

また、CA検定で扱う偏差は次のもの。これら偏差の平方和を用いて  \chi^{2} 統計量を求める。※下図の緑の両矢印が偏差のイメージ。

 確率の偏差 :個々のスコアでの確率  p_{i} - 全体の確率 \overline{p}
 スコアの偏差:個々のスコア  s_{i} - 全体の平均スコア \overline{s}

f:id:cochineal19:20210208093005p:plain

\quad S= \dfrac{\sum \left( n_{i} s_{i} \right)}{N}=\dfrac{110\times 1 + 100\times 2 + 80\times 3.5+60\times 5.5}{350}=2.629
\quad \overline{p}= \dfrac{A}{N}=\dfrac{70}{350}=0.2
\quad S_{ss}= \sum \{ n_{i} w \left( s_{i} - \overline{s} \right) ^{2} \}=687.5\left(1-2.629 \right)^{2}+625\left(2-2.629 \right)^{2}+500\left(3.5-2.629 \right)^{2}+375\left(5.5-2.629 \right)^{2}=5541.964

\quad S_{pp}= \sum \{ n_{i} w \left( p_{i} - \overline{p} \right) ^{2} \}=687.5\left(0.091-0.2 \right)^{2}+625\left(0.2-0.2 \right)^{2}+500\left(0.25-0.2 \right)^{2}+375\left(0.333-0.2 \right)^{2}=16.098
\quad S_{sp}= \sum \{ n_{i} w \left( s_{i} - \overline{s} \right) \left( p_{i} - \overline{p} \right) \}=687.5\left(1-2.629 \right)\left(0.091-0.2 \right)+625\left(2-2.629 \right)\left(0.2-0.2 \right)+500\left(3.5-2.629 \right)\left(0.25-0.2 \right)+375\left(5.5-2.629 \right)\left(0.333-0.2 \right)=287.5

   \chi ^{2} 統計量 自由度(df) p値
Slope  \chi _{Slope}^{2}=S_{sp}^{2}/S_{ss}
=287.5^{2}/5541.964
=14.9146
 1 0.000112
Residual  \chi _{Resid}^{2}=\chi _{Total}^{2} - \chi _{Slope}^{2}
= 16.0985-14.9146
= 1.1839
 k-1-1
=4-1-1
=2
0.553255
Total  \chi _{Total}^{2}=S_{pp}
=16.098
 k-1
=4-1
=3
0.001082

上の表のうち、 \chi_{Slope}^{2} が回帰直線の傾きに関連する統計量であり、この統計量を使った  \chi^{2} 検定がCA検定
 \chi_{Resid}^{2} は残差項。直線からのズレが有意であるかを示すため、非有意が望まれる。残差項が有意な場合、目的変数と説明変数の関係性を直線で表しきれていないことを意味する。
 \chi_{Total}^{2} は通常の  \chi^{2} 検定の結果。

 

今回の架空データでは、病気Xの病状(Score)が悪いほど死亡発生確率が増加する傾向がある(p for trend<0.001)と結論付けられそう。また、残差項は有意でないため、直線モデルが当てはまっていると解釈できる。

 

Excelでの計算結果は次のとおり。

f:id:cochineal19:20210208092624p:plain



Rでの実行:

> mtx <- matrix(c(10,20,20,20,100,80,60,40), nrow=4, ncol=2)
> chisq.test(mtx, correct = F)
Pearson's Chi-squared test
data: mtx X-squared = 16.098, df = 3, p-value = 0.001082 > prop.trend.test( + x=mtx[,1] + ,n=mtx[,1]+mtx[,2] + ,score = c(1,2,3.5,5.5)) Chi-squared Test for Trend in Proportions

data: mtx[, 1] out of mtx[, 1] + mtx[, 2] , using scores: 1 2 3.5 5.5 X-squared = 14.915, df = 1, p-value = 0.0001125

SASでの実行:

data ads;
input SCORE OUTCOME CNT @@;
datalines;
1 1 10 1 2 100 2 1 20 2 2 80 3.5 1 20 3.5 2 60 5.5 1 20 5.5 2 40
;run;
proc freq data=ads;
  table SCORE * OUTCOME / trend nocol nopercent;
  weight CNT / zeros;
output out=OutputDS trend; run;

f:id:cochineal19:20201219141532p:plain

 z^{2}=\chi ^{2} \left( df=1 \right) の関係があるため、 z^{2}≒3.8619^{2}≒14.9146 で等価。 

 

プログラムコード


■ Rのコード

prop.trend.test(x=ADS$x, n=ADS$n, score=ADS$score)

 

SASのコード

proc freq data=[InputDS];
  table Factor * Outcome / trend nocol nopercent;
  weight Count / zeros;
output out=[OutputDS] trend; /*_TREND_, P2_TRENDを取得。*/ run;

 

Pythonのコード

整備中

 

その他


その1:

SASの出力結果のところで少し触れたが、統計ソフトによって取り扱う統計量が  \chi^{2} のものとz値のものがある。
 \chi^{2} 分布(自由度=1)には  \chi^{2}=z^{2} の関係があるため、p値はどちらも同じ。

備忘録がてら z値の導出式も掲載。
平方和の式に重みはなく、z値の導出時に重みを与えている。

\quad S_{sp}= \sum \{ n_{i} \left( s_{i} - \overline{s} \right) \left( p_{i} - \overline{p} \right) \}

\quad S_{ss}= \sum \{ n_{i} \left( s_{i} - \overline{s} \right) ^{2} \}

\quad z=\dfrac{\sum n_{i}\left( p_{i}-\overline{p}\right) \left( s_{i}-\overline{s}\right) }{\sqrt{\overline{p}\left( 1-\overline{p}\right) \sum n_{i}\left( s_{i}-\overline{s}\right) }}=\dfrac{S_{sp}}{\sqrt{\overline{p}\left( 1-\overline{p}\right) S_{ss}}}=\dfrac{S_{sp}^2}{\overline{p}\left( 1-\overline{p}\right) S_{ss}}=w\dfrac{S_{sp}^2}{S_{ss}} 

本記事の架空データで試すと次のとおり。

\quad S_{sp}= \sum \{ n_{i} \left( s_{i} - \overline{s} \right) \left( p_{i} - \overline{p} \right) \}=110\left(1-2.629 \right)\left(0.091-0.2 \right)+100\left(2-2.629 \right)\left(0.2-0.2 \right)+80\left(3.5-2.629 \right)\left(0.25-0.2 \right)+60\left(5.5-2.629 \right)\left(0.333-0.2 \right)=46

\quad S_{ss}= \sum \{ n_{i} \left( s_{i} - \overline{s} \right) ^{2} \}=110\left(1-2.629 \right)^{2}+100\left(2-2.629 \right)^{2}+80\left(3.5-2.629 \right)^{2}+60\left(5.5-2.629 \right)^{2}≒886.714

 \quad w=\dfrac{1}{\overline{p}(1-\overline{p})}=\dfrac{1}{0.2×0.8}=6.25 \verb| <再掲>|

\quad z=w\dfrac{S_{sp}^2}{S_{ss}}=6.25\times\dfrac{46^2}{886.714}≒3.86194 

この  z≒3.86194 の p値を求めると  p≒0.0001124 になる。
\quad \verb|= 2 * (1 - NORM.S.DIST(ABS(3.86194), TRUE))  ※Excel関数|
 

---------------
その2

Rのlm関数のweightオプションに本記事で取り上げた「各スコアの重み付きN数」を指定すれば、重み付き最小二乗法での回帰分析を実行できる。
この結果から分散分析表を作れば、 \chi^{2}_{slope} 統計量を導出できる。

> library(tidyverse)
> x <- c(10,20,20,20)
> n <- c(110,100,80,60)
> score <- c(1,2,3.5,5.5)
> (p1 <- sum(x)/sum(n))
> (p2 <- x/n)
> (w1 <- 1/(p1*(1-p1)))
> (w2 <- n*w1)
[1] 0.2
[1] 0.09090909 0.20000000 0.25000000 0.33333333
[1] 6.25
[1] 687.5 625.0 500.0 375.0
> (fit <- lm(p2 ~ score, weights=w2))
Call:
lm(formula = p2 ~ score, weights = w2)
Coefficients:
(Intercept)        score  
    0.06364      0.05188  

> anova(fit)
Analysis of Variance Table
Response: p2
          Df  Sum Sq Mean Sq F value  Pr(>F)  
score      1 14.9146 14.9146  25.196 0.03747 *
Residuals  2  1.1839  0.5919                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> 
> #-- 例示した回帰直線のグラフはこちら。 > ads <- data.frame(score=score,p=p2,w=w2) > ggplot(ads, aes(x=score, y=p)) + + geom_vline(xintercept=2.629, lty=2) + + geom_hline(yintercept=0.200, lty=2) + + geom_point(aes(size=w), colour="blue", alpha=.5) + + stat_smooth(method="lm", se=F, aes(weight=w))

 

参考


統計学(出版:東京図書), 日本統計学会編

https://www.lexjansen.com/pharmasug/2007/sp/SP05.pdf

統計学入門−第5章

【統計】マンテル・ヘンツェルの検定(Mantel-Haenszel test, Cochran-Mantel-Haenszel test)

マンテル・ヘンツェルの検定(Mantel-Haenszel test)について。

【目次】

 

マンテル・ヘンツェルの検定は、 \chi^{2} 検定やFisher's Exact testと同じく、カテゴリーデータの独立性を評価する手法であり、多層のクロス表の層別解析を行うことができる。

この検定は、Mantel and Haenszel (1959) が開発した手法。
同様の方法を Cochran (1954) も提案しており、彼らの名前から Cochran-Mantel-Haenszel test(CMH検定)とも呼ばれる。
本記事では、マンテル・ヘンツェルの検定と呼称。

 

帰無仮説、対立仮設


 ※OR=Odds Rate(オッズ比)、k=Subgroup(層別因子)

 

計算式等


次のクロス表が k層あると仮定して考える。

■ 観測度数

  Outcome Total
(+) (-)
Factor 1 a b AB
2 c d CD
Total AC BD N

  

 \chi _{MH}^{2} 統計量(CMH統計量とも言う) :

\quad \chi _{MH}^{2}=\dfrac{\left(| \sum \left( a_{i}-\dfrac{AB_{i}×AC_{i}}{N_{i}}\right)| - Correct \right) ^{2}}{\sum \left( \dfrac{AB_{i}×CD_{i}×AC_{i}×BD_{i}}{N_{i}^{3} - N_{i}^{2}}\right) }

 

共通オッズ比(Common OR) :

\quad \widehat{OR}_{MH}=\dfrac{\sum \left( \dfrac{a_{i}× d_{i}}{Ni}\right) }{\sum \left( \dfrac{b_{i} × c_{i}}{Ni}\right) }

 

共通オッズ比の信頼区間 :

\quad \widehat{OR_{MH}}\times{ exp \left(±1 \times z_{1 - \alpha/2} \times \sqrt{Var\left( logOR_{MH} \right)}\ \right)}

\quad \widehat{OR_{MH}}\times{ exp \left(±1 \times 1.96 \times \sqrt{Var\left( logOR_{MH} \right)}\ \right)} ※95%信頼区間

 ただし、

\quad Var\left( logOR_{MH} \right) = \dfrac{\sum \left( A_{i}×C_{i} \right)}{2\left( \sum C_{i}\right) ^{2}} + \dfrac{\sum \left( A_{i}\times D_{i}+B_{i}\times C_{i}\right) }{2\left( \sum C_{i}\right) \left( \sum D_{i}\right)} + \dfrac{\sum \left( B_{i}\times D_{i}\right) }{2\left( \sum D_{i}\right) ^{2}}

\quad A = \dfrac{a + d}{n},\ B = \dfrac{b + c}{n},\ C = \dfrac{a \times d}{n},\ D = \dfrac{b \times c}{n}

 \chi _{MH}^{2} 統計量や共通オッズ比は、交絡因子で層別解析した結果を統計学的に併合したもの。この併合手法をマンテル・ヘンツェル法と言う。

  

計算例


簡単なデータで計算方法を確認。
年齢で層別化した遺伝子Xと病気Yのクロス集計表(架空データ)を用いる。
(年齢を交絡因子として扱う)

■ 観測度数 

年齢 遺伝子X 病気Y Total
(+) (-)
< 40 10 40 50
  50 100 150
  Total 60 140 200
40-59 150 50 200
  50 20 70
  Total 200 70 270
60 < 50 50 100
  50 50 100
  Total 100 100 200
All 210 140 350
  150 170 320
  Total 360 310 670

 

今回の架空データの全体表について単純に  χ^{2} 検定を行うと、  χ^{2}=11.0612,\ p=0.000882 となり、遺伝子Xと病気Yの間に有意な関係がありそうだという結論になる。 

マンテル・ヘンツェルの検定を行ってみる。
Excel でデータを横持ちにして、層別解析したものが次の図。

f:id:cochineal19:20201209221310p:plain

マンテル・ヘンツェルの検定(CMH検定)

 \chi _{MH}^{2} 統計量および  \chi^{2} 検定(自由度=1)による p値:

\quad \chi_{MH}^{2} = 0.2301 \left( p=0.63142 \right)(連続修正あり)
\quad \chi_{MH}^{2} = 0.3252 \left( p=0.56847 \right)(連続修正なし)

共通オッズ比、およびその95%信頼区間

\quad \widehat{OR}_{MH} = 0.900875 [ 0.6296054,\ 1.2890219]

 

全体表の  χ^{2} 検定で有意だった結果から一変して、マンテル・ヘンツェルの検定(年齢で調整したデータ全体の独立性検定)では p値が0.05を上回り、統計学的に有意ではないという結論になった。
共通オッズ比も1を下回り、95%信頼区間も1を挟んでいるため、遺伝子Xと病気Yの間に有意な関係性を見出すことはできない。

今回の場合、例えば40-59歳は遺伝子Xの有無問わず病気Yの発生が多いと見られるため、遺伝子Xに直接の要因はなく、年齢やそれに伴う生活習慣などが要因にあたるのかもしれない。

このように、コントロール可能な交絡因子が考えられる場合、単に  \chi^{2} 検定やFisher's exact 検定をするのでなく、層別解析を行うことはとても有用。

 

Rでの実行:

> mymtx1 <- matrix(c( 10, 40, 50, 100), nrow=2, byrow=TRUE)
> mymtx2 <- matrix(c(150, 50, 50,  20), nrow=2, byrow=TRUE)
> mymtx3 <- matrix(c( 50, 50, 50,  50), nrow=2, byrow=TRUE)
> mymtx  <- array(c(mymtx1, mymtx2, mymtx3), dim=c(2,2,3))
> 
> mantelhaen.test(mymtx, correct=T)

	Mantel-Haenszel chi-squared test with continuity correction

data:  mymtx
Mantel-Haenszel X-squared = 0.23013, df = 1, p-value = 0.6314
alternative hypothesis: true common odds ratio is not equal to 1
95 percent confidence interval:
 0.6296054 1.2890219
sample estimates:
common odds ratio 
        0.9008746 

> mantelhaen.test(mymtx, correct=F)

	Mantel-Haenszel chi-squared test without continuity correction

data:  mymtx
Mantel-Haenszel X-squared = 0.32524, df = 1, p-value = 0.5685
alternative hypothesis: true common odds ratio is not equal to 1
95 percent confidence interval:
 0.6296054 1.2890219
sample estimates:
common odds ratio 
        0.9008746 


SASでの実行:

data ads;
input AGEGR1N GENOTYPE OUTCOME CNT @@;
datalines;
1 0 0 10 1 1 0 50 1 0 1 40 1 1 1 100
2 0 0 150 2 1 0 50 2 0 1 50 2 1 1 20
3 0 0 50 3 1 0 50 3 0 1 50 3 1 1 50
;
run;
proc freq data=ads;
  table AGEGR1N * GENOTYPE * OUTCOME / cmh nocol nopercent;
  weight CNT / zeros;
run;

 f:id:cochineal19:20201219122514p:plain

 

プログラムコード


■ Rのコード

mantelhaen.test(mymtx, correct=T) #-- correct T:連続修正あり、F:連続修正なし

 

SASのコード

proc freq data=[InputDS];
  table Subgroup * Factor * Outcome / cmh nocol nopercent;
  weight Count / zeros;
output out=[OutputDS] cmh; run;
 

 

Pythonのコード

整備中

 

CochranとMantel and Haenszelの違い


Cochran (1954) の方法と Mantel and Haenszel (1959) の方法は統計量の計算に違いがあり、若干数値が異なるようだった。気にするレベルではない?
なお、RもSASも Mantel and Haenszelの統計量のようだった。

Mantel and Haenszelの統計量( \chi _{MH}^{2} 統計量)
<再掲>

\quad \chi _{MH}^{2}=\dfrac{\left(| \sum \left( a_{i}-\dfrac{AB_{i}×AC_{i}}{N_{i}}\right)| - Correct \right) ^{2}}{\sum \left( \dfrac{AB_{i}×CD_{i}×AC_{i}×BD_{i}}{N_{i}^{3} - N_{i}^{2}}\right) }

Cochranの統計量

\quad \chi _{cochran}^{2}=\dfrac{\sum \left( \dfrac{a_{i} \times d_{i} - b_{i} \times c_{i}}{N_{i}}\right) ^{2}}{\sum \left( \dfrac{AB_{i}×CD_{i}×AC_{i}×BD_{i}}{\left( N_{i} - 1 \right) \times N_{i}^{2}}\right) } 

 

参考


https://support.sas.com/documentation/onlinedoc/stat/121/freq.pdf

https://www.pharmasug.org/proceedings/2020/SA/PharmaSUG-2020-SA-051.pdf

https://www.annualreviews.org/doi/pdf/10.1146/annurev.pu.09.050188.001011

Cochran-Mantel-Haenszel Test with Breslow-Day & Tarone Correction

コクラン-マンテル-ヘンツェル検定とは - Minitab

 


サイトマップ

cochineal19.hatenablog.com

【統計】Fisher's exact test

Fisher's exact testについて。

【目次】

 

Fisher's Exact testは  χ^{2} 検定と同じく、カテゴリーデータの独立性を評価する手法。

cochineal19.hatenablog.com

 

帰無仮説、対立仮設


要因と結果の間に関係がないか(独立であるか)を評価する。
 

計算式等


次のクロス表で考える。

■ 観測度数

  Outcome Total
(+) (-)
Factor 1 a b AB
2 c d CD
Total AC BD N

\quad p_{i}=\dfrac{AB!×CD!×AC!×BD!}{N!×a!×b!×c!×d!}

\quad p=\sum p_{i}\quad\verb| ( if | p_{i} \leqq \verb|Cut off )|

 

計算例


 \chi^{2} 検定では、 \chi^{2} 統計量(期待度数と観測度数のズレ)を算出し、 \chi^{2} 分布を使って p値を導出する。一方、Fisher's exact test は、統計量を算出して確率分布に近似するのではなく、直接 p値を求める方法。そのため直接確率検定とも呼ばれる。

簡単なデータを用いて計算方法を確認。
 \chi^{2} 検定の記事で使った次のクロス表を用いる。

■ 観測度数

  肺がん Total
(+) (-)
喫煙 28 12 40
17 25 42
Total 45 37 82

 

先ず、この観測度数が起きる確率を求める。
当該確率は、次のステップでカットオフ値として用いる。

\quad \verb|Cut off|=\dfrac{ 40!×42!×45!×37! }{ 82!×28!×12!×17!×25! }≒0.00493


次に、周辺度数(AB、CD、AC、BD)を固定した場合に観測度数が取り得る全パターンを列挙し、生起確率を求める。
今回は次のパターンが列挙される。このうち、(  p_{i} \leqq \verb|Cut off| ) が "Y" になっている部分(背景ピンク色の行)が、カットオフ値以下の確率(観測パターンとそれより珍しいパターン)。 

 

最後に、カットオフ値以下の確率を総和することでp値を導出する。

\quad p=\sum p_{i}≒0.008564 

なお、上表の黄色セルが上下にあるとおり本計算は両側検定。

 

Rでの実行:

> mtx1 <- matrix(c(28, 12, 17, 25), nrow=2, byrow=TRUE)
> fisher.test(mtx1)

	Fisher's Exact Test for Count Data

data:  mtx1
p-value = 0.008564
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 1.256537 9.512684
sample estimates:
odds ratio 
  3.377065  


SASでの実行:

data ads;
input FACTOR OUTCOME CNT;
datalines;
1 1 28
1 0 12
0 1 17
0 0 25
;
run;
proc freq data=ads;
  table FACTOR * OUTCOME / chisq exact nocol nopercent;
  weight CNT / zeros;
  output out=Outds chisq exact;
run;

 f:id:cochineal19:20201219150829p:plain

 

プログラムコード


■ Rのコード

fisher.test(mtx1)

 

SASのコード

proc freq data=[InputDS];
  table Factor * Outcome / fisher nocol nopercent;
  weight Count / zeros;
  exact fisher;   /* 2*2以上の表に検定を要求できる */
output out=[OutputDS] fisher; /* XP2_FISHを取得。*/ run;

 

Pythonのコード

整備中

 

参考


https://mathworld.wolfram.com/FishersExactTest.html

統計学基礎(出版:東京図書), 日本統計学会編

統計学(出版:東京図書), 日本統計学会編

 


サイトマップ

cochineal19.hatenablog.com

【統計】χ二乗検定

独立性の  \chi^{2} 検定について。

【目次】

 

 \chi^{2} 検定はカテゴリデータのクロス表(分割表、クロステーブル)で用いられる検定。

  

帰無仮説、対立仮設


要因と結果の間に関係がないか(独立であるか)を評価する。

 

計算式等


次のクロス表で考える。

■ 観測度数

  Outcome Total
(+) (-)
Factor 1 a b AB
2 c d CD
Total AC BD N


■ 期待度数

  Outcome
(+) (-)
Factor 1  \dfrac{AB\times AC}{N}  \dfrac{AB\times BD}{N}
2  \dfrac{CD\times AC}{N}  \dfrac{CD\times BD}{N}


■  \chi^{2} 統計量

\quad \chi^{2} = \Sigma _{i=1}^{r}\Sigma _{j=1}^{c}\dfrac{\left(  max \left( ❘ O_{ij} - E_{ij} ❘ - Correct,\  0 \right) \right) ^{2}}{E_{ij}}

 自由度= \left( r - 1 \right)\left( c - 1 \right)
 ※r=行数、c=列数、Correct=連続修正(有の場合 0.5、無の場合 0)

 

ノート


期待度数は、要因と結果の間に関係がない時(独立である時)に取り得る理論値。
 \chi^{2} 検定では、この期待度数と観測度数の差(理論値と実際の値のズレ)を見ており、このズレが大きいほど独立の仮定から離れていく。
(ズレが大きいほど  \chi^{2} 統計量は大きくなり、p値が小さくなる。)


簡単なデータで計算方法を確認。
今回は、喫煙有無と肺がんの関係性という良くある例で、観測度数が下表のとおりだったとする。架空データ。

■ 観測度数

  肺がん Total
(+) (-)
喫煙 28 12 40
17 25 42
Total 45 37 82

 

この期待度数を計算すると下表のとおり。

■ 期待度数

  肺がん
(+) (-)
喫煙  \dfrac{40×45}{82}≒21.951  \dfrac{40×37}{82}≒18.049
 \dfrac{42×45}{82}≒23.049  \dfrac{42×37}{82}≒18.951

 

観測度数と期待度数から  \chi^{2} 統計量を計算する。

 \chi^{2} 統計量

  肺がん
(+) (-)
喫煙  \dfrac{\left(28-21.951\right)^{2}}{21.951}≒1.667

 \dfrac{\left(12-18.049\right)^{2}}{18.049}≒2.027

 \dfrac{\left(17-23.049\right)^{2}}{23.049}≒1.587  \dfrac{\left(25-18.951\right)^{2}}{18.951}≒1.931

上の表を総和したものが  \chi^{2} 統計量(連続修正なし)。

\quad \chi^{2}=1.667+2.027+1.587+1.931≒7.212

また、連続修正ありの場合は次のとおり。

\quad \chi^{2}=1.403+1.706+1.336+1.625≒6.0689

 

今回のクロス表は2×2表のため、自由度=1 の  \chi^{2} 分布のもと、p値は次のようになります。

 p≒0.007242(連続修正なし)
 p≒0.01376 (連続修正あり)

 

Rでの実行:

> mtx1 <- matrix(c(28, 12, 17, 25), nrow=2, byrow=TRUE)
> chisq.test(mtx1, correct=F)

	Pearson's Chi-squared test

data:  mtx1
X-squared = 7.212, df = 1, p-value = 0.007242

> chisq.test(mtx1, correct=T)

	Pearson's Chi-squared test with Yates' continuity correction

data:  mtx1
X-squared = 6.0689, df = 1, p-value = 0.01376


SASでの実行:

data ads;
input FACTOR OUTCOME CNT;
datalines;
1 1 28
1 0 12
0 1 17
0 0 25
;
run;
proc freq data=ads;
  table FACTOR * OUTCOME / chisq nocol nopercent;
  weight CNT / zeros;
  output out=Outds chisq;
run;

f:id:cochineal19:20201219150829p:plain

 

プログラムコード


■ Rのコード

chisq.test(mtx1, correct=T) #--correctで連続修正

 

SASのコード

proc freq data=[InputDS];
  table Outcome * Factor / chisq nocol nopercent;
  weight Count / zeros;
  output out=[OutputDS] chisq; /*連続修正無:_PCHI_,P_PCHI, 有:_AJCHI_,P_AJCHIを取得*/
run;

 

Pythonのコード 

整備中

 

Cochran's rule


期待度数が5未満のものが全体の20%を上回る場合や全体のN数が20未満の場合、 χ^{2} 検定は近似が悪くなるため使用しない方が良いと言われる(Cochran's rule)。
この場合は、水準の併合やFisher's Exact testが推奨される。

cochineal19.hatenablog.com

 

なお、交絡因子を考慮した手法としてマンテル・ヘンツェルの検定(CMH検定)などがある。

cochineal19.hatenablog.com

 

参考


統計学基礎(出版:東京図書), 日本統計学会編

統計学(出版:東京図書), 日本統計学会編

 


サイトマップ

cochineal19.hatenablog.com

【統計】ヨンキー検定(傾向性検定)

傾向性検定(ヨンキー検定)について。

【目次】

 

 Jonckheere-Terpstra trend test(ヨンクヒール-タプストラ検定、またはヨンキー検定)は目的変数が連続値の時に使用できる傾向性検定。
目的変数が割合の場合は Cochran-Armitage trend test(コクラン-アミテージ検定)を使用。 

cochineal19.hatenablog.com

 

帰無仮説、対立仮設


ヨンキー検定は中央値を用いるノンパラメトリックな手法です。
対立仮説が「<」ではなく「<=」であるため、A=B<=CでもA<=B=Cでも有意になる可能性があります。

 

計算式等


\quad JT=\sum U_{ij}=\sum _{i=1}^{n_{i}}\sum _{j=1}^{n_{j}}\left( WIN_{ij}+\dfrac{1}{2}TIE_{ij}\right)\verb|  ※i<j の組み合わせのみ|

\quad E[ JT] =\dfrac{n^{2}-\sum n_{i}^{2}}{4}

\quad Var[ JT] =\dfrac{n^{2}\left( 2n+3\right) -\sum \{ n_{i}^{2}\left( 2n_{i}+3\right) \} }{72}

\quad z=\dfrac{JT-E[ JT] }{\sqrt{Var[ JT] }}

 

JT統計量は、水準間の総当たり戦(ただし、i < jの組み合わせのみ)。勝ち数と引き分け数(0.5倍)を総和したものが統計量となる。

ただし、タイ(同一順位)を考慮して、分散を次のとおり算出する方法がある。
SAS社のアルゴリズムはこちらのよう(ホームページ見る限り)。

\quad A=n\left( n-1\right) \left( 2n+5\right)-\sum \{\left( n_{i}-1\right) \left( 2n_{i}+5\right)\} - \sum \{ d_{i}\left( d_{i}-1\right) \left( 2d_{i}+5\right)\}

\quad B =\sum \{ \left( n_{i}-1\right) \left( n_{i}-2\right) \} \cdot \sum \{ d_{i}\left( d_{i}-1\right) \left( d_{i}-2\right) \}

\quad C=\sum \left( n_{i}-1\right) \cdot \sum \{d_{i}\left( d_{i}-1\right) \}

\quad Var[ JT ] =\dfrac{A}{72}+\dfrac{B}{36n\left( n-1\right) \left( n-2\right) }+\dfrac{C}{8n\left( n-1\right) }


A~Cにある  \sum d_{i} ....データの頻度の総和。
例えば {10,10,11,12,16} であれば、 { d_{10}=2,  d_{11}=1,  d_{12}=1,  d_{16}=1} となる。この例では10が2つあるので、 d_{10}=2 になるのが特徴。

 

計算例


簡単なデータを使って手順を確認。
今回は簡単のため、グループ1~3に4つずつ、計12個のデータ。

  g1{11, 13, 10, 11}
  g2{15, 12, 10, 11}
  g3{20, 20, 16, 19}

先にExcelにまとめたものを掲載。 

f:id:cochineal19:20201205161816p:plain

JT統計量:

グループの順序が i < j の組み合わせのみで大小比較するため、今回の3グループ(g1、g2、g3)では、g1 vs. g2(U_{12})、g1 vs. g3(U_{13})、g2 vs. g3(U_{23}) の3つが比較対象。
例えば U_{12} のg1{11} vs. g2{15,12,10,11} では、{勝ち、勝ち、負け、引き分け}になるため、1+1+0+1×0.5=2.5となる(Excel F2:H6)。
これら個々の勝敗を足し合わせたものが JT統計量(Excel Q9)。
2.5 + 1 + 3.5 + 2.5 + 4 + 4+ 4 + 4 + 4 + 4+ 4 + 4 = 41.5

 

タイの補正:

データ全体で、10に2つ、11に3つ、20に2つの同値がある。
タイを補正する場合、分散の式中の  \sum d_{i} .... が役割を担う(Excel J9:N16、Q12:Q14)。
なお、図のとおり、タイがない値は d(d-1) = 1×(1-1) = 0 でゼロになるため、タイのみ考慮されることが分かる。

期待値・分散、z値・p値:

公式のとおり計算を行うと次の結果が得られる(Excel Q11:R18)。
\quad E[JT]=24
\quad VAR[JT]=45.6000,\quad z=2.5915,\quad p=0.004778\quad \left(タイの補正ありの式\right)
\quad VAR[JT]=46.6667,\quad z=2.5617,\quad p=0.005207\quad \left(タイ補正なしの式\right)

今回の架空データでは、TRT01P=1→2→3の順で観測値(AVAL)が増加する傾向があった(p for trend < 0.01)と結論付けられそう(タイ補正の有無問わず)。

 

Excelの関数の中身はこちら。

f:id:cochineal19:20201205160318p:plain

f:id:cochineal19:20201205161958p:plain

Rでの実行:
PMCMRplusとclinfunの2パッケージを見つけたのでこれらを試す。

> ADS1 <- data.frame(AVAL=c(11,13,10,11,15,12,10,11,20,20,16,19)
+                    , TRT01PN=c(1,1,1,1,2,2,2,2,3,3,3,3))
> ADS1$TRT01PF <- factor(ADS1$TRT01PN, levels = c("1","2","3"))
> 
> #-- PMCMRplu タイ補正あり
> library(PMCMRplus)
> jonckheereTest(ADS1$AVAL, ADS1$TRT01PF, alternative="greater")

	Jonckheere-Terpstra test

data:  ADS1$AVAL and ADS1$TRT01PF
z = 2.5915, p-value = 0.004778
alternative hypothesis: greater
sample estimates:
  JT 
41.5 

 警告メッセージ: 
 jonckheereTest.default(ADS1$AVAL, ADS1$TRT01PF, alternative = "greater") で: 
  Ties are present. Jonckheere z was corrected for ties.
  
> #-- clinfun タイ補正なし
> library(clinfun)
> jonckheere.test(ADS1$AVAL, ADS1$TRT01PN, alternative="increasing")

	Jonckheere-Terpstra test

data:  
JT = 41.5, p-value = 0.005207
alternative hypothesis: increasing

 警告メッセージ: 
 jonckheere.test(ADS1$AVAL, ADS1$TRT01PN, alternative = "increasing") で: 
  Sample size > 100 or data with ties 
 p-value based on normal approximation. Specify nperm for permutation p-value

両パッケージともJT統計量=41.5で同値だが、
PMCMRplusはタイ補正ありの p=0.004778、
clinfunはタイ補正なしの p=0.005207 と一致(タイがない場合は、p値は同じ)。


SASでの実行:
タイ補正ありの結果が得られる。増減を見たいので片側検定の結果を見る。

data ads;
  do AVAL=11,13,10,11; TRT01PN=1; output; end;
  do AVAL=15,12,10,11; TRT01PN=2; output; end;
  do AVAL=20,20,16,19; TRT01PN=3; output; end;
run;
proc sort data=ads: by TRT01PN AVAL; run;
proc freq data=ads;
  tables TRT01PN * AVAL / jt;
  exact jt;
  output out=OutputDS jt;
run;

f:id:cochineal19:20201219164014p:plain

 

プログラムコード


■ Rのコード

library(PMCMRplus) #-- タイ補正あり
jonckheereTest(ADS1$AVAL, ADS1$TRT01PF, alternative=c("greater","less"))

library(clinfun) #-- タイ補正なし
jonckheere.test(ADS1$AVAL, ADS1$TRT01PN, alternative=c("decreasing","increasing"))

 

SASのコード

proc freq data=[InputDS];
tables GROUP * AVAL / jt; /* 群*測定値の順序にする。*/
exact jt; /* 正確検定する場合設定。*/
output out=[OutputDS] jt; /* _JT_,Z_JTを取得。XPR_JTは正確確率(右側)*/
run;

 

Pythonのコード 

整備中

 

ヨンキー検定とケンドールの順位相関


ヨンキー検定はケンドールの順位相関と同じ考え方のよう。
実行してみると、z値、p値ともにタイ補正ありの式と同値だった。 

■ ケンドールの順位相関

> cor.test(ADS1$TRT01PN, ADS1$AVAL, method="kendall", alternative="greater")

	Kendall's rank correlation tau

data:  ADS1$TRT01PN and ADS1$AVAL
z = 2.5915, p-value = 0.004778
alternative hypothesis: true tau is greater than 0
sample estimates:
      tau 
0.6468186 

 警告メッセージ: 
 cor.test.default(ADS1$TRT01PN, ADS1$AVAL, method = "kendall",  で: 
   タイのため正確な p 値を計算することができません 

 

参考


Tao Xu, Jonckheere-Terpstra test

Programming Documentetion, SAS

 


サイトマップ

cochineal19.hatenablog.com

【HTML+CSS】数式を書く

LaTeXという組み込みソフトで数式を書けるようです。

[tex: 数式] で表します。

数式の作成には、以下のサイトさんがとても使いやすいです。
手書きした数式をコードに変換してくれて、とても便利です。

webdemo.myscript.com

 

試しに適当な数式を書いてみました。

z=\dfrac{1}{2}a^{2}+b+\sqrt{c}-\sum \left( x_{i}-\overline{x}\right)

 

これを [tex: 数式] で囲うと…

 z=\dfrac{1}{2}a^{2}+b+\sqrt{c}-\sum \left( x_{i}-\overline{x}\right)

本ブログは個人メモです。 本ブログの内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。