p値(p-value)は、仮説検定において最も頻繁に使われる指標ですが、同時に最も誤解されやすい概念でもあります。多くの研究者やデータサイエンティストがp値を正しく理解せずに使っていると指摘されており、2016年にはアメリカ統計学会(ASA)がp値に関する声明を発表するほどの問題になりました。
本記事では、p値の正確な定義と正しい解釈、そしてよくある誤解について丁寧に解説します。
本記事の内容
- p値の正確な定義
- よくある誤解と正しい解釈
- 有意水準との関係
- 多重検定問題
- Pythonでのシミュレーション
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
p値の定義
正確な定義
p値とは、帰無仮説 $H_0$ が正しいと仮定したとき、観測されたデータ以上に極端な結果が得られる確率です。
数式で書くと、検定統計量 $T$ に対して、
$$ p = P(|T| \geq |t_{\text{obs}}| \mid H_0) \quad \text{(両側検定の場合)} $$
ここで $t_{\text{obs}}$ は実際のデータから計算された検定統計量の値です。
直感的な理解
イメージとしては、「帰無仮説が正しい世界で、今回のデータと同じくらい(またはもっと)極端な結果が偶然得られる確率」です。
p値が小さいということは、「帰無仮説が正しいなら、今回のような結果はめったに起きない」ことを意味し、帰無仮説に対する証拠の強さを表します。
p値のよくある誤解
誤解1: 「p値は帰無仮説が正しい確率」
正: p値は「帰無仮説が正しい確率」ではありません。
p値は「帰無仮説が正しいと仮定したときに、観測以上に極端な結果が得られる確率」です。帰無仮説が正しい確率を求めるにはベイズ統計の枠組みが必要です。
誤解2: 「p < 0.05 は結果が重要(実用的に意味がある)」
正: 統計的有意性と実用的重要性は異なります。
標本サイズが非常に大きければ、些細な差でも統計的に有意になります。例えば、新薬が平均体温を0.01度下げることが $p < 0.001$ で有意でも、医学的には無意味です。
誤解3: 「p > 0.05 は差がないことの証拠」
正: p値が大きいことは「差がないとは言えない」のであり、「差がない」ことの証拠ではありません。
検定力が低い(標本サイズが小さい)場合、実際に差があっても $p > 0.05$ となることがあります。
誤解4: 「p値が小さいほど効果が大きい」
正: p値は効果の大きさを示しません。標本サイズにも強く依存します。
$p = 0.001$ が $p = 0.04$ より大きな効果を示すとは限りません。効果の大きさは効果量(effect size)で測るべきです。
有意水準とp値
有意水準 $\alpha$
有意水準 $\alpha$ は、帰無仮説が正しいときに誤って棄却する確率の上限(第一種の過誤の確率)で、検定の前に設定します。通常 $\alpha = 0.05$ が使われます。
判定ルール: $p < \alpha$ なら $H_0$ を棄却、$p \geq \alpha$ なら $H_0$ を棄却しない。
$\alpha = 0.05$ は絶対的な基準ではない
$\alpha = 0.05$ という基準はフィッシャーが提案した慣習的なものであり、物理的な意味があるわけではありません。分野や状況に応じて $\alpha = 0.01$ や $\alpha = 0.001$ を使うこともあります。
第一種の過誤と第二種の過誤
| $H_0$ が真 | $H_0$ が偽 | |
|---|---|---|
| $H_0$ を棄却 | 第一種の過誤(偽陽性)確率 $\alpha$ | 正しい棄却(検定力 $1 – \beta$) |
| $H_0$ を棄却しない | 正しい判断 | 第二種の過誤(偽陰性)確率 $\beta$ |
多重検定問題
問題
複数の検定を同時に行うと、少なくとも1つで偽陽性が出る確率(ファミリーワイズエラー率, FWER)が膨れ上がります。
$m$ 回の独立な検定を有意水準 $\alpha = 0.05$ で行うと、少なくとも1つで偽陽性が出る確率は、
$$ \text{FWER} = 1 – (1 – \alpha)^m $$
$m = 20$ なら $\text{FWER} = 1 – 0.95^{20} \approx 0.64$(64%の確率で偽陽性が出る)。
ボンフェローニ補正
最も単純な多重検定補正です。$m$ 回の検定を行う場合、各検定の有意水準を $\alpha/m$ に下げます。
$$ \alpha_{\text{adjusted}} = \frac{\alpha}{m} $$
ベンジャミニ・ホッホベルク法(FDR制御)
ボンフェローニ補正は保守的すぎることがあります。FDR(False Discovery Rate: 偽発見率)を制御するBH法がより実用的です。
Pythonでのシミュレーション
p値の分布: 帰無仮説が正しいとき
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(42)
n_simulations = 10000
n_samples = 30
mu_0 = 0 # 帰無仮説のμ
# 帰無仮説が正しい場合(真の平均 = 0)
p_values_null = []
for _ in range(n_simulations):
sample = np.random.normal(0, 1, n_samples) # H0が正しい
_, p = stats.ttest_1samp(sample, mu_0)
p_values_null.append(p)
# 帰無仮説が間違っている場合(真の平均 = 0.5)
p_values_alt = []
for _ in range(n_simulations):
sample = np.random.normal(0.5, 1, n_samples) # H0が間違い
_, p = stats.ttest_1samp(sample, mu_0)
p_values_alt.append(p)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
ax = axes[0]
ax.hist(p_values_null, bins=50, density=True, alpha=0.7, color='steelblue', edgecolor='white')
ax.axhline(y=1, color='r', linestyle='--', linewidth=2, label='Uniform(0,1)')
ax.set_xlabel('$p$-value')
ax.set_ylabel('Density')
ax.set_title('$H_0$ is TRUE: p-values are uniform')
ax.legend()
ax.grid(True, alpha=0.3)
ax = axes[1]
ax.hist(p_values_alt, bins=50, density=True, alpha=0.7, color='orange', edgecolor='white')
ax.set_xlabel('$p$-value')
ax.set_ylabel('Density')
ax.set_title('$H_0$ is FALSE: p-values skewed toward 0')
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('p_value_distribution.png', dpi=150, bbox_inches='tight')
plt.show()
# 偽陽性率の確認
false_positive_rate = np.mean(np.array(p_values_null) < 0.05)
print(f"偽陽性率(α=0.05): {false_positive_rate:.4f}")
帰無仮説が正しいとき、p値は $[0, 1]$ の一様分布に従います。これは非常に重要な性質です。
多重検定問題のシミュレーション
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(42)
n_simulations = 5000
# m回の検定を行ったときのFWER
m_values = range(1, 51)
fwer_theoretical = [1 - (1 - 0.05)**m for m in m_values]
fwer_simulated = []
for m in m_values:
any_significant = 0
for _ in range(n_simulations):
p_values = []
for _ in range(m):
sample = np.random.normal(0, 1, 30) # H0が正しい
_, p = stats.ttest_1samp(sample, 0)
p_values.append(p)
if min(p_values) < 0.05:
any_significant += 1
fwer_simulated.append(any_significant / n_simulations)
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(list(m_values), fwer_theoretical, 'r-', linewidth=2, label='Theoretical FWER')
ax.plot(list(m_values), fwer_simulated, 'bo', markersize=4, alpha=0.7, label='Simulated FWER')
ax.axhline(y=0.05, color='gray', linestyle='--', label='$\\alpha = 0.05$')
ax.set_xlabel('Number of tests $m$')
ax.set_ylabel('Family-wise error rate')
ax.set_title('Multiple testing: Family-wise error rate')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('multiple_testing_fwer.png', dpi=150, bbox_inches='tight')
plt.show()
p値と効果量の関係
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(42)
# 同じ効果量でも標本サイズによりp値が異なる
effect_size = 0.3 # 小さい効果量
sample_sizes = [10, 30, 100, 300, 1000]
fig, ax = plt.subplots(figsize=(10, 6))
for n in sample_sizes:
p_values = []
for _ in range(2000):
sample = np.random.normal(effect_size, 1, n)
_, p = stats.ttest_1samp(sample, 0)
p_values.append(p)
ax.hist(p_values, bins=40, density=True, alpha=0.4, label=f'$n = {n}$')
ax.axvline(x=0.05, color='r', linestyle='--', linewidth=2, label='$\\alpha = 0.05$')
ax.set_xlabel('$p$-value')
ax.set_ylabel('Density')
ax.set_title(f'Same effect size ($d = {effect_size}$), different sample sizes')
ax.legend()
ax.grid(True, alpha=0.3)
ax.set_xlim(0, 1)
plt.tight_layout()
plt.savefig('p_value_vs_sample_size.png', dpi=150, bbox_inches='tight')
plt.show()
同じ効果量でも、標本サイズが大きいほどp値が小さくなる(帰無仮説を棄却しやすくなる)ことが確認できます。
まとめ
本記事では、p値の定義と正しい解釈を解説しました。
- p値の定義: 帰無仮説が正しいとき、観測以上に極端な結果が得られる確率
- p値は帰無仮説が正しい確率ではない
- 統計的有意性と実用的重要性は別物 — 効果量も確認すべき
- 多重検定問題: 複数の検定を行うと偽陽性率が膨れ上がる
- 帰無仮説のもとでp値は一様分布に従う
p値は有用な指標ですが、それだけに頼るのではなく、効果量や信頼区間、実用的な意味も合わせて判断することが重要です。