Cochran-Armitage test(コクラン-アーミテージ検定またはCA検定)について。
【目次】
CA検定は、割合の増加/減少傾向を評価する傾向性の検定。
検定の中身は、割合を目的変数とした回帰分析であり、回帰直線の傾きが0であるかどうかを見ている。
なお、目的変数が連続値の場合は、Jonckheere-Terpstra trend test(ヨンクヒール-タプストラ検定、またはヨンキー検定)等が用いられる。
帰無仮説、対立仮設
- 帰無仮説
(直線の傾きが0)
- 対立仮設
(直線の傾きが0でない)
計算式等
CA検定では 統計量を用いる。
通常の 検定の統計量を
、CA検定で扱う統計量を
、残差を
とすると次の式が成り立つ。
これら 統計量の導出は下表のとおり。
自由度(df) | ||
Slope | ||
Residual | ||
Total |
表の平方和は次の計算式。
※=当該水準でのスコア、
=当該水準での全体数、
=当該水準での該当数
計算例
簡単なデータで計算方法を確認。
今回は、病気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 |
先ず、全体の基本情報;
例数 、死亡数
、死亡割合
CA検定では、割合を目的変数とした回帰分析を行うが、手法として割合の標準誤差の逆数を重みとした「重み付き最小二乗法」を用いる。この重みと各スコアの重み付きN数は次のとおり。
重みを使った回帰直線:
※プロットサイズ:各スコアの重み付き例数
※縦の点線:全体の平均スコア
※横の点線:全体の確率
また、CA検定で扱う偏差は次のもの。これら偏差の平方和を用いて 統計量を求める。※下図の緑の両矢印が偏差のイメージ。
確率の偏差 :個々のスコアでの確率 - 全体の確率
スコアの偏差:個々のスコア - 全体の平均スコア
自由度(df) | p値 | ||
Slope | |||
Residual | |||
Total |
上の表のうち、 が回帰直線の傾きに関連する統計量であり、この統計量を使った
検定がCA検定。
は残差項。直線からのズレが有意であるかを示すため、非有意が望まれる。残差項が有意な場合、目的変数と説明変数の関係性を直線で表しきれていないことを意味する。
は通常の
検定の結果。
今回の架空データでは、病気Xの病状(Score)が悪いほど死亡発生確率が増加する傾向がある(p for trend<0.001)と結論付けられそう。また、残差項は有意でないため、直線モデルが当てはまっていると解釈できる。
Excelでの計算結果は次のとおり。
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;
の関係があるため、
で等価。
プログラムコード
■ 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の出力結果のところで少し触れたが、統計ソフトによって取り扱う統計量が のものとz値のものがある。
分布(自由度=1)には
の関係があるため、p値はどちらも同じ。
備忘録がてら z値の導出式も掲載。
平方和の式に重みはなく、z値の導出時に重みを与えている。
本記事の架空データで試すと次のとおり。
この の p値を求めると
になる。
---------------
その2
Rのlm関数のweightオプションに本記事で取り上げた「各スコアの重み付きN数」を指定すれば、重み付き最小二乗法での回帰分析を実行できる。
この結果から分散分析表を作れば、 統計量を導出できる。
> 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))