有意水準とp値の正しい理解

統計的仮説検定を正しく使うには、有意水準(significance level)p値(p-value) の2つの概念を正確に理解する必要があります。しかし、これらは最も誤解されやすい統計概念でもあり、2016年にはアメリカ統計学会(ASA)がp値の誤用に関する声明を発表するほどの問題になりました。

本記事では、有意水準とp値の定義を数学的に厳密に述べ、よくある誤解を正したうえで、Pythonによる実演を通じて直感的な理解を深めます。

本記事の内容

  • 有意水準 $\alpha$ の定義と意味
  • p値の正確な数学的定義
  • p値のよくある誤解
  • 検定の完全な手順
  • Pythonでのp値計算と可視化

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

有意水準とは

定義

有意水準(significance level) $\alpha$ とは、帰無仮説 $H_0$ が正しいときに、$H_0$ を誤って棄却する確率の上限です。

$$ \alpha = P(\text{$H_0$ を棄却} \mid H_0 \text{ が真}) $$

これは第1種の過誤の確率そのものです。研究者が 検定を行う前に 設定する閾値であり、「どの程度の偽陽性リスクを許容するか」を表しています。

なぜ事前に設定するのか

有意水準を事前に設定する理由は、データを見てから基準を変えてしまう恣意的な判断を防ぐためです。たとえばp値が 0.06 だったときに「$\alpha = 0.10$ にしよう」と後から変更するのは不適切です。

一般的な有意水準

有意水準 使われる場面
$\alpha = 0.05$ 最も標準的。多くの分野で慣例
$\alpha = 0.01$ より厳しい基準。物理学の一部
$\alpha = 0.001$ 非常に厳しい基準
$\alpha = 5 \times 10^{-7}$ 素粒子物理学の「5シグマ」基準

$\alpha = 0.05$ が広く使われていますが、これは絶対的な基準ではなく、分野や問題の性質に応じて適切な値を選ぶべきです。

p値とは

数学的定義

p値とは、帰無仮説 $H_0$ が正しいという前提のもとで、観測されたデータと同等以上に極端な検定統計量が得られる確率です。

検定統計量の観測値を $T_{\text{obs}}$ とすると、

両側検定の場合:

$$ p = P(|T| \geq |T_{\text{obs}}| \mid H_0) $$

右片側検定の場合:

$$ p = P(T \geq T_{\text{obs}} \mid H_0) $$

左片側検定の場合:

$$ p = P(T \leq T_{\text{obs}} \mid H_0) $$

正規分布に基づくp値の計算

z検定を例に、p値を具体的に計算します。検定統計量 $Z = \frac{\bar{X} – \mu_0}{\sigma / \sqrt{n}}$ とし、$H_0$ のもとで $Z \sim N(0, 1)$ です。

観測された検定統計量の値を $z_{\text{obs}}$ とすると、両側検定のp値は次のようになります。

$$ \begin{align} p &= P(|Z| \geq |z_{\text{obs}}| \mid H_0) \\ &= P(Z \geq |z_{\text{obs}}|) + P(Z \leq -|z_{\text{obs}}|) \\ &= 2P(Z \geq |z_{\text{obs}}|) \quad (\because \text{標準正規分布の対称性}) \\ &= 2(1 – \Phi(|z_{\text{obs}}|)) \end{align} $$

ここで $\Phi(\cdot)$ は標準正規分布の累積分布関数です。

p値の直感的な解釈

p値は「帰無仮説が正しいと仮定したとき、今回のデータがどれだけ珍しいか」を表す指標です。

  • p値が小さい → データが帰無仮説のもとで珍しい → $H_0$ に反する証拠が強い
  • p値が大きい → データが帰無仮説のもとで珍しくない → $H_0$ に反する証拠が弱い

判定基準

$$ \begin{cases} p \leq \alpha & \Rightarrow H_0 \text{ を棄却する} \\ p > \alpha & \Rightarrow H_0 \text{ を棄却しない} \end{cases} $$

p値のよくある誤解

誤解1: 「p値は $H_0$ が正しい確率」

誤り: $p = 0.03$ のとき「帰無仮説が正しい確率は3%」

正しい理解: p値は「$H_0$ が正しいと仮定したとき、このデータ以上に極端な結果が得られる確率」です。$H_0$ の真偽の確率ではありません。

数式で書くと、p値は $P(\text{データ} \mid H_0)$ に関連する量であり、$P(H_0 \mid \text{データ})$ ではありません。後者はベイズの定理を通じてしか求められません。

誤解2: 「p値が小さいほど効果が大きい」

誤り: $p = 0.001$ なら大きな効果がある

正しい理解: p値は効果の大きさ(効果量)を直接反映しません。標本サイズが非常に大きければ、ごく小さな効果でもp値は極めて小さくなります。

z検定の検定統計量 $Z = \frac{\bar{X} – \mu_0}{\sigma / \sqrt{n}}$ を見ると、$n$ が大きくなれば $Z$ が大きくなり、p値は小さくなります。効果の実質的な大きさは 効果量(effect size) で評価すべきです。

誤解3: 「p > 0.05 なら効果がない」

誤り: $p = 0.08$ だから効果がない

正しい理解: 帰無仮説を棄却できないことは、帰無仮説が正しいことの証明ではありません(「証拠がない」と「ないことの証拠」は異なります)。検出力が不足している可能性もあります。

誤解4: 「$1 – p$ は $H_1$ が正しい確率」

誤り: $p = 0.03$ だから対立仮説が正しい確率は97%

正しい理解: $1 – p$ に確率的な意味はありません。p値はあくまで $H_0$ のもとでの確率計算です。

検定の完全な手順

以上を踏まえて、仮説検定の正しい手順を整理します。

ステップ1: 仮説の設定

$$ H_0: \mu = \mu_0, \quad H_1: \mu \neq \mu_0 $$

ステップ2: 有意水準 $\alpha$ の設定

$\alpha = 0.05$ など、事前に決める。

ステップ3: 検定統計量の計算

$$ Z = \frac{\bar{X} – \mu_0}{\sigma / \sqrt{n}} $$

ステップ4: p値の計算

$$ p = 2(1 – \Phi(|z_{\text{obs}}|)) $$

ステップ5: 判定

$p \leq \alpha$ なら $H_0$ を棄却。$p > \alpha$ なら $H_0$ を棄却しない。

ステップ6: 結論の記述

効果量や信頼区間とあわせて報告する。

Pythonでの実演

p値の計算と可視化

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# 具体例: ある工場の製品の長さ
mu_0 = 50.0    # 帰無仮説の母平均 (mm)
sigma = 2.0    # 母標準偏差 (既知)
n = 25         # 標本サイズ

# 標本データ(母平均50.8から生成)
np.random.seed(42)
data = np.random.normal(50.8, sigma, n)
x_bar = np.mean(data)

# 検定統計量
se = sigma / np.sqrt(n)
z_obs = (x_bar - mu_0) / se

# p値(両側検定)
p_value = 2 * (1 - stats.norm.cdf(np.abs(z_obs)))

print(f"標本平均: {x_bar:.4f}")
print(f"検定統計量: Z = {z_obs:.4f}")
print(f"p値: {p_value:.4f}")
print(f"α = 0.05 での判定: {'棄却' if p_value < 0.05 else '棄却しない'}")

# 可視化
x = np.linspace(-4, 4, 1000)
pdf = stats.norm.pdf(x)

fig, ax = plt.subplots(figsize=(10, 6))

# 標準正規分布
ax.plot(x, pdf, 'k-', linewidth=2, label='$N(0, 1)$')

# p値の領域を塗りつぶし(両側)
x_right = x[x >= np.abs(z_obs)]
ax.fill_between(x_right, stats.norm.pdf(x_right),
                color='red', alpha=0.4, label=f'p-value = {p_value:.4f}')
x_left = x[x <= -np.abs(z_obs)]
ax.fill_between(x_left, stats.norm.pdf(x_left),
                color='red', alpha=0.4)

# 棄却域(α = 0.05)
z_crit = stats.norm.ppf(1 - 0.05 / 2)
ax.axvline(z_crit, color='blue', linestyle='--', linewidth=1.5,
           label=f'$z_{{\\alpha/2}}$ = $\\pm${z_crit:.3f}')
ax.axvline(-z_crit, color='blue', linestyle='--', linewidth=1.5)

# 観測された検定統計量
ax.axvline(z_obs, color='darkred', linewidth=2.5,
           label=f'$z_{{obs}}$ = {z_obs:.3f}')

ax.set_xlabel('$z$', fontsize=13)
ax.set_ylabel('Probability Density', fontsize=13)
ax.set_title('p-value Visualization (Two-sided Z-test)', fontsize=14)
ax.legend(fontsize=10)
ax.set_ylim(bottom=0)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

標本サイズとp値の関係

p値が標本サイズに強く依存することを示します。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# 固定パラメータ
mu_0 = 50.0
mu_true = 50.5   # 真の母平均(わずかな差)
sigma = 2.0

# 標本サイズの範囲
sample_sizes = np.arange(10, 2001, 10)

np.random.seed(42)
p_values = []

for n in sample_sizes:
    # 理論的なp値(期待値ベースで計算)
    se = sigma / np.sqrt(n)
    z = (mu_true - mu_0) / se
    p = 2 * (1 - stats.norm.cdf(np.abs(z)))
    p_values.append(p)

p_values = np.array(p_values)

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(sample_sizes, p_values, 'b-', linewidth=2)
ax.axhline(y=0.05, color='red', linestyle='--', linewidth=1.5,
           label='$\\alpha$ = 0.05')
ax.axhline(y=0.01, color='orange', linestyle='--', linewidth=1.5,
           label='$\\alpha$ = 0.01')

# p < 0.05 となるnを探す
n_sig = sample_sizes[np.argmax(p_values < 0.05)]
ax.axvline(x=n_sig, color='gray', linestyle=':', alpha=0.7,
           label=f'p < 0.05 at n = {n_sig}')

ax.set_xlabel('Sample Size $n$', fontsize=13)
ax.set_ylabel('p-value', fontsize=13)
ax.set_title(f'p-value vs Sample Size ($\\mu_0$={mu_0}, $\\mu_{{true}}$={mu_true}, $\\sigma$={sigma})',
             fontsize=13)
ax.set_yscale('log')
ax.legend(fontsize=11)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

print(f"真の効果量: d = {(mu_true - mu_0) / sigma:.3f}")
print(f"p < 0.05 となる最小の標本サイズ: n = {n_sig}")

このグラフから、効果量がわずか $d = 0.25$ でも標本サイズを増やせばp値はいくらでも小さくなることがわかります。p値の大きさと効果の実質的な意味は別のものです。

p値のシミュレーション: 帰無仮説が真のときのp値の分布

帰無仮説が正しいとき、p値は一様分布 $U(0, 1)$ に従います。これをシミュレーションで確認します。

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

np.random.seed(42)

mu_0 = 0
sigma = 1
n = 30
n_sim = 10000

# H0が真のもとでp値を繰り返し計算
p_values_h0 = []
for _ in range(n_sim):
    sample = np.random.normal(mu_0, sigma, n)
    z = (np.mean(sample) - mu_0) / (sigma / np.sqrt(n))
    p = 2 * (1 - stats.norm.cdf(np.abs(z)))
    p_values_h0.append(p)

p_values_h0 = np.array(p_values_h0)

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 左: p値のヒストグラム
axes[0].hist(p_values_h0, bins=50, density=True, alpha=0.7, color='steelblue',
             edgecolor='white')
axes[0].axhline(y=1.0, color='red', linestyle='--', linewidth=2,
                label='Uniform(0, 1)')
axes[0].set_xlabel('p-value', fontsize=12)
axes[0].set_ylabel('Density', fontsize=12)
axes[0].set_title('Distribution of p-values under $H_0$', fontsize=13)
axes[0].legend(fontsize=11)

# 右: 偽陽性率
alpha_levels = np.linspace(0, 1, 200)
false_positive_rates = [np.mean(p_values_h0 <= a) for a in alpha_levels]

axes[1].plot(alpha_levels, false_positive_rates, 'b-', linewidth=2,
             label='Observed')
axes[1].plot([0, 1], [0, 1], 'r--', linewidth=1.5, label='Theoretical')
axes[1].set_xlabel('$\\alpha$', fontsize=12)
axes[1].set_ylabel('$P(p \\leq \\alpha)$', fontsize=12)
axes[1].set_title('False Positive Rate vs $\\alpha$', fontsize=13)
axes[1].legend(fontsize=11)
axes[1].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

print(f"α = 0.05 での偽陽性率: {np.mean(p_values_h0 <= 0.05):.4f}")
print(f"α = 0.01 での偽陽性率: {np.mean(p_values_h0 <= 0.01):.4f}")

$H_0$ が真のときp値は一様分布に従うため、$P(p \leq \alpha) = \alpha$ が成り立ちます。これが「有意水準 $\alpha$ で第1種の過誤の確率が $\alpha$ になる」ことの直接的な帰結です。

まとめ

本記事では、有意水準とp値の正しい理解について解説しました。

  • 有意水準 $\alpha$: 第1種の過誤の確率の上限。検定前に事前に設定する
  • p値: $H_0$ のもとで、観測データ以上に極端な結果が得られる確率
  • p値の誤解: 「$H_0$ が正しい確率」ではない。効果の大きさも反映しない
  • 判定基準: $p \leq \alpha$ なら $H_0$ を棄却、$p > \alpha$ なら棄却しない
  • 標本サイズ依存性: 大標本ではわずかな差でもp値が小さくなるため、効果量とあわせて解釈すべき

次のステップとして、以下の記事も参考にしてください。