🐋

HCI研究者の心理統計ノート:ウィルコクソンの符号順位検定 / Wilcoxon signed-rank test

2023/01/04に公開

HCI研究者の心理統計ノート

https://zenn.dev/tmizuho/articles/e8890371f683bd

Introduction

ウィルコクソンの符号順位検定 (Wilcoxon signed-rank test) は、2つの対応のあるデータに差があるかどうかを検定する方法です。似た名前の ウィルコクソンの順位和検定 とは全く異なる検定方法なので注意してください。

HCI研究では、2条件参加者内計画 (within-subject design) の実験において、条件1と条件2で評価指標に統計的に有意な差があるかどうかを調べる際に使用します (e.g., 既存手法 vs 提案手法)。特に、質問紙の評定(リッカート尺度)を比較する場面などでよく使います。

対応のある t 検定 (Paired t-test) とは違い、正規性の仮定は必要ありません。正規性が仮定できるデータ、できないデータともに適用することができます。正規性の検定は精度がサンプルサイズに大きく依存するといった問題も指摘されており、正規性の仮定に不安があれば、ウィルコクソンの符号順位検定を使っておくと無難といった考え方もあるようです。

R Sample Code

# ライブラリのインポート
library(tidyverse)

# csvファイルの読み込み
# 整然データを想定: 一行が一観測。 "参加者ID, 独立変数, 従属変数" の形。
data <- read_csv("csvファイルのパス", show_col_types=F) %>%
    # コードの再利用可能性を高めるために列名を変更
    mutate(s=factor("参加者IDの列名"), A=factor("独立変数の列名"), y="従属変数の列名") %>%
    # 必要な列だけ抽出
    select(s, A, y) %>%
    # ソート(対応関係に注意しておく必要がある)
    arrange(A, s)

# 欠損値や外れ値など、解析から除外するべきデータがあれば削除
# 割愛

# 記述統計量の確認
data %>%
    group_by(A) %>%
    summarize(N=n(), Mean=mean(y), SD=sd(y), SE=sd(y)/sqrt(n()), Min=min(y), Median=median(y), Max=max(y))

# 簡単なグラフを描画して確認
data %>%
    # ggplot で作図開始。x軸は実験条件、y軸は評価指標(平均値)。
    ggplot(aes(x=A, y=y, fill=A)) +
    # 箱ひげ図
    geom_boxplot() +
    # 平均値
    stat_summary(fun=mean, geom="point", color="black", shape=4, size=2) +
    # 軸ラベルの設定
    labs(x="Condition", y="Measurement") +
    # カラーパレット
    scale_fill_brewer(palette="Blues") +
    # テーマの調整
    theme_light() +
    theme(legend.position="none") +
    theme(panel.grid.major.x=element_blank(), panel.grid.minor.y=element_blank())

# exactRankTests パッケージを使用する方法
library(exactRankTests)
(table <- wilcox.exact(y~A, data=data, paired=T))

#効果量 Cohen's r : 目安は small(0.1), medium(0.3), large(0.5)
p <- table$p.value
z <- qnorm(1 - p/2)#両側検定の場合
r <- z / sqrt(length(data$y))
print(paste("Cohen's r = ", r))

How to Report : LaTeX Sample

Japanese

ウィルコクソンの符号順位検定を実施した結果,YはA1条件がA2条件に比べて有意に高かった (\textit{p} = .XX, Cohen's \textit{r} = X.XX).

English

We conducted an Wilcoxon signed-rank test. The result showed that Y was significantly higher in the A1 condition than in the A2 condition (\textit{p} = .XX, Cohen's \textit{r} = X.XX).

For Your Information

効果量について

ノンパラメトリック検定の効果量は、サンプルサイズ N と検定統計量 Z を用いて、以下のように計算しています。

r = {Z}/{\sqrt{N}}

coin パッケージを使う方法について

exactRankTests パッケージをインポートすると、「exactRankTests は開発が終わっているので coin を使ってください」と表示されるかもしれません。気になる方は、以下のように実装すれば、exactRankTests と coin で同じ結果が得られます。zero.method オプションを設定していない例がネット上によく見られますが、デフォルト値の "Pratt" では結果が一致しない場合があるようです[1]。ただし、一つ注意するべきは、wilcoxsign_test の結果に表示される Z は p 値の計算に使われるものではないため[2]、効果量 r の計算に使用してはいけません。

ちなみに、R の標準パッケージで使える wilcox.test 関数でもウィルコクソンの符号順位検定を実行できますが、正確な p 値が計算できない場合があるので、使わないようにしましょう。

library(coin)
a1 <- data %>% filter(A==levels(data$A)[1]) %>% pull(y)
a2 <- data %>% filter(A==levels(data$A)[2]) %>% pull(y)
(table <- wilcoxsign_test(a1~a2, distribution="exact", zero.method="Wilcoxon"))# y~A, data のように指定できないので、注意してください。

p <- pvalue(table)
z <- qnorm(1 - p/2)#両側検定の場合
r <- z / sqrt(length(data$y))
print(paste("Cohen's r = ", r))
脚注
  1. R-help, "The three routines in R that calculate the wilcoxon signed-rank test give different p-values.......which is correct?", https://stat.ethz.ch/pipermail/r-help/2011-April/274931.html, viewed 2023/1/4. ↩︎

  2. 裏 RjpWiki, "wilcox.test と wilcox_test 前者だったら残念ですね", https://blog.goo.ne.jp/r-de-r/e/019d0afc8e702b044768dd8eeaed3dcf, viewed 2023/1/4. ↩︎

Discussion