z検定の理論と導出をわかりやすく解説

z検定は、正規分布に基づく最も基本的な仮説検定のひとつです。母分散が既知の場合、あるいは標本サイズが十分に大きい場合に、母平均に関する仮説を検証するために用いられます。

t検定の特殊なケースとも言えるz検定は、検定の理論体系を理解する出発点として最適です。検定統計量の構成、棄却域の決定、p値の算出といった仮説検定の基本的な手続きが、z検定を通じて最もシンプルな形で学べます。

本記事の内容

  • z検定の前提条件と適用場面
  • 1標本z検定・2標本z検定の検定統計量の導出
  • 片側検定と両側検定の棄却域の決定
  • p値の計算方法
  • t検定との理論的な違いと使い分け
  • Pythonでのスクラッチ実装と可視化

前提知識

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

z検定とは

概要

z検定(z-test)は、検定統計量が標準正規分布 $N(0, 1)$ に従うことを利用した仮説検定の方法です。「ある母集団の母平均が特定の値と等しいかどうか」を判断するために使います。

前提条件

z検定を適用するには、以下のいずれかの条件が必要です。

条件1: 母分散 $\sigma^2$ が既知

母集団の分散がわかっている場合、標本サイズに関係なくz検定を適用できます。ただし実際には母分散が既知であることは稀です。

条件2: 大標本($n$ が十分大きい)

標本サイズが十分に大きい場合(一般に $n \geq 30$ が目安)、中心極限定理により標本平均の分布は近似的に正規分布に従います。また、標本分散 $s^2$ が母分散 $\sigma^2$ の良い推定量になるため、$\sigma$ を $s$ で置き換えてz検定を適用できます。

1標本z検定の検定統計量の導出

問題設定

母集団 $X \sim N(\mu, \sigma^2)$($\sigma^2$ 既知)から、大きさ $n$ の無作為標本 $X_1, X_2, \dots, X_n$ を抽出します。

帰無仮説と対立仮説を次のように設定します。

$$ H_0: \mu = \mu_0, \quad H_1: \mu \neq \mu_0 \quad (\text{両側検定の場合}) $$

標本平均の分布

各 $X_i$ は独立に $N(\mu, \sigma^2)$ に従うため、標本平均 $\bar{X} = \frac{1}{n}\sum_{i=1}^{n} X_i$ の分布は次のようになります。

$$ E[\bar{X}] = E\left[\frac{1}{n}\sum_{i=1}^{n} X_i\right] = \frac{1}{n}\sum_{i=1}^{n} E[X_i] = \frac{1}{n} \cdot n\mu = \mu $$

$$ \text{Var}(\bar{X}) = \text{Var}\left(\frac{1}{n}\sum_{i=1}^{n} X_i\right) = \frac{1}{n^2}\sum_{i=1}^{n} \text{Var}(X_i) = \frac{1}{n^2} \cdot n\sigma^2 = \frac{\sigma^2}{n} $$

2行目では、$X_i$ が独立であることから分散の加法性を用いました。

正規分布の再生性(独立な正規確率変数の線形結合は正規分布に従う)により、

$$ \bar{X} \sim N\left(\mu, \frac{\sigma^2}{n}\right) $$

検定統計量の構成

$\bar{X}$ を標準化します。帰無仮説 $H_0: \mu = \mu_0$ のもとで、

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

この $Z$ の分布を確認します。$H_0$ のもとでは $\bar{X} \sim N(\mu_0, \sigma^2/n)$ ですから、

$$ Z = \frac{\bar{X} – \mu_0}{\sigma / \sqrt{n}} \sim N(0, 1) $$

これがz検定の 検定統計量 です。分母の $\sigma / \sqrt{n}$ は 標準誤差(standard error) と呼ばれます。

導出の意味

検定統計量 $Z$ は、「標本平均 $\bar{X}$ が帰無仮説で想定される値 $\mu_0$ からどれだけ離れているか」を、標準誤差の何倍分かで表したものです。$|Z|$ が大きいほど、データは帰無仮説と矛盾しています。

棄却域の決定

両側検定

対立仮説が $H_1: \mu \neq \mu_0$ の場合、棄却域は検定統計量の絶対値が大きい両端に設定します。

有意水準 $\alpha$ のもとで、棄却域は

$$ |Z| > z_{\alpha/2} $$

です。ここで $z_{\alpha/2}$ は標準正規分布の上側 $\alpha/2$ 点、すなわち

$$ P(Z > z_{\alpha/2}) = \frac{\alpha}{2} $$

を満たす値です。

なぜ $\alpha/2$ で分割するのかを確認しましょう。棄却域を $\{Z > c\} \cup \{Z < -c\}$ と設定したとき、帰無仮説のもとで棄却する確率は、

$$ P(|Z| > c \mid H_0) = P(Z > c) + P(Z < -c) = 2P(Z > c) $$

これが $\alpha$ に等しくなるようにするには、$2P(Z > c) = \alpha$、すなわち $P(Z > c) = \alpha/2$ となる $c = z_{\alpha/2}$ を選べばよいのです。

$\alpha = 0.05$ のとき、$z_{0.025} = 1.96$ です。

片側検定(右側)

対立仮説が $H_1: \mu > \mu_0$ の場合、帰無仮説を棄却する証拠は $\bar{X}$ が $\mu_0$ より大きい方向にのみあります。棄却域は

$$ Z > z_\alpha $$

$\alpha = 0.05$ のとき、$z_{0.05} = 1.645$ です。

片側検定(左側)

対立仮説が $H_1: \mu < \mu_0$ の場合、棄却域は

$$ Z < -z_\alpha $$

p値の計算方法

p値の定義

p値は「帰無仮説のもとで、観測された検定統計量と同等以上に極端な値が得られる確率」です。

両側検定の場合

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

$$ \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} $$

片側検定(右側)の場合

$$ p = P(Z \geq z_{\text{obs}} \mid H_0) = 1 – \Phi(z_{\text{obs}}) $$

片側検定(左側)の場合

$$ p = P(Z \leq z_{\text{obs}} \mid H_0) = \Phi(z_{\text{obs}}) $$

判定基準

$p \leq \alpha$ のとき帰無仮説を棄却し、$p > \alpha$ のとき帰無仮説を棄却しません。

2標本z検定の導出

問題設定

2つの独立な母集団からの標本を用いて、母平均の差を検定します。

$$ X_1, X_2, \dots, X_{n_1} \sim N(\mu_1, \sigma_1^2), \quad Y_1, Y_2, \dots, Y_{n_2} \sim N(\mu_2, \sigma_2^2) $$

$\sigma_1^2, \sigma_2^2$ は既知とします。

$$ H_0: \mu_1 = \mu_2, \quad H_1: \mu_1 \neq \mu_2 $$

検定統計量の導出

標本平均の差 $\bar{X} – \bar{Y}$ の分布を求めます。

$$ E[\bar{X} – \bar{Y}] = E[\bar{X}] – E[\bar{Y}] = \mu_1 – \mu_2 $$

$\bar{X}$ と $\bar{Y}$ は独立ですから、

$$ \text{Var}(\bar{X} – \bar{Y}) = \text{Var}(\bar{X}) + \text{Var}(\bar{Y}) = \frac{\sigma_1^2}{n_1} + \frac{\sigma_2^2}{n_2} $$

正規分布の線形結合は正規分布に従うので、

$$ \bar{X} – \bar{Y} \sim N\left(\mu_1 – \mu_2, \frac{\sigma_1^2}{n_1} + \frac{\sigma_2^2}{n_2}\right) $$

$H_0: \mu_1 = \mu_2$(すなわち $\mu_1 – \mu_2 = 0$)のもとで標準化すると、

$$ Z = \frac{\bar{X} – \bar{Y}}{\sqrt{\dfrac{\sigma_1^2}{n_1} + \dfrac{\sigma_2^2}{n_2}}} \sim N(0, 1) $$

これが2標本z検定の検定統計量です。

等分散の場合の簡略化

$\sigma_1^2 = \sigma_2^2 = \sigma^2$ の場合、

$$ Z = \frac{\bar{X} – \bar{Y}}{\sigma\sqrt{\dfrac{1}{n_1} + \dfrac{1}{n_2}}} $$

さらに $n_1 = n_2 = n$ の場合、

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

t検定との使い分け

理論的な違い

z検定とt検定の違いは、分母に何を使うかにあります。

  • z検定: 母標準偏差 $\sigma$(既知)を使う → $Z = \frac{\bar{X} – \mu_0}{\sigma / \sqrt{n}} \sim N(0, 1)$
  • t検定: 標本標準偏差 $s$(推定値)を使う → $T = \frac{\bar{X} – \mu_0}{s / \sqrt{n}} \sim t_{n-1}$

$s$ で $\sigma$ を推定する際の不確実性を反映して、t分布は正規分布よりも裾が重くなります。

なぜt分布が必要か

$s^2 = \frac{1}{n-1}\sum_{i=1}^{n}(X_i – \bar{X})^2$ とおくと、

$$ \frac{(n-1)s^2}{\sigma^2} \sim \chi^2_{n-1} $$

検定統計量 $T = \frac{\bar{X} – \mu_0}{s/\sqrt{n}}$ を変形します。

$$ T = \frac{\bar{X} – \mu_0}{\sigma/\sqrt{n}} \cdot \frac{\sigma}{s} = Z \cdot \frac{1}{\sqrt{s^2/\sigma^2}} $$

ここで $Z = \frac{\bar{X} – \mu_0}{\sigma/\sqrt{n}} \sim N(0, 1)$ です。$s^2/\sigma^2 = \frac{1}{n-1}\chi^2_{n-1}$ ですから、

$$ T = \frac{Z}{\sqrt{\chi^2_{n-1}/(n-1)}} $$

これはまさに自由度 $n-1$ のt分布の定義です。$Z$ と $\chi^2_{n-1}$ が独立であることも、正規分布の性質から保証されています。

$n$ が大きいときの収束

$n \to \infty$ のとき、大数の法則により $s^2 \to \sigma^2$ に確率収束します。したがって $T \to Z$ となり、t分布は標準正規分布に収束します。

具体的には、$t_{n-1}$ 分布の上側 $\alpha/2$ 点は次のように正規分布に近づきます。

自由度 $t_{\alpha/2}$($\alpha = 0.05$)
10 2.228
30 2.042
100 1.984
$\infty$ 1.960(= $z_{0.025}$)

実用的な使い分け

条件 使う検定
母分散既知 z検定
母分散未知、$n < 30$ t検定
母分散未知、$n \geq 30$ t検定(推奨)or z検定(近似)

実務では母分散が既知であることはほぼないため、基本的にはt検定を使うのが安全です。ただし大標本の場合は両者の結果がほぼ一致します。

具体例

数値例: 1標本z検定

ある工場の製品の長さは、母平均 $\mu_0 = 50$ mm、母標準偏差 $\sigma = 2$ mm であることが知られています。新しい機械の導入後、25個の製品をランダムに抽出したところ、標本平均 $\bar{x} = 50.8$ mm でした。新しい機械によって製品の長さが変化したかを有意水準5%で検定します。

ステップ1: 仮説の設定

$$ H_0: \mu = 50, \quad H_1: \mu \neq 50 \quad (\text{両側検定}) $$

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

$$ Z = \frac{\bar{x} – \mu_0}{\sigma / \sqrt{n}} = \frac{50.8 – 50}{2 / \sqrt{25}} = \frac{0.8}{0.4} = 2.0 $$

ステップ3: p値の計算

$$ p = 2(1 – \Phi(|2.0|)) = 2(1 – 0.9772) = 2 \times 0.0228 = 0.0456 $$

ステップ4: 判定

$p = 0.0456 < \alpha = 0.05$ なので、帰無仮説を棄却します。新しい機械の導入により、製品の長さに有意な変化があると結論します。

数値例: 2標本z検定

2つの工場A, Bの製品の重量を比較します。

  • 工場A: $n_1 = 36$, $\bar{x}_1 = 102.5$ g, $\sigma_1 = 5$ g(既知)
  • 工場B: $n_2 = 40$, $\bar{x}_2 = 100.3$ g, $\sigma_2 = 4.5$ g(既知)

$$ H_0: \mu_1 = \mu_2, \quad H_1: \mu_1 \neq \mu_2 $$

検定統計量を計算します。

$$ Z = \frac{\bar{x}_1 – \bar{x}_2}{\sqrt{\dfrac{\sigma_1^2}{n_1} + \dfrac{\sigma_2^2}{n_2}}} = \frac{102.5 – 100.3}{\sqrt{\dfrac{25}{36} + \dfrac{20.25}{40}}} = \frac{2.2}{\sqrt{0.6944 + 0.5063}} = \frac{2.2}{\sqrt{1.2007}} = \frac{2.2}{1.0958} \approx 2.008 $$

p値を計算します。

$$ p = 2(1 – \Phi(2.008)) \approx 2(1 – 0.9777) = 2 \times 0.0223 = 0.0446 $$

$p = 0.0446 < 0.05$ なので、帰無仮説を棄却します。2つの工場の製品重量には有意な差があると結論します。

Pythonでの実装

1標本z検定のスクラッチ実装

import numpy as np
from scipy import stats

def z_test_one_sample(data, mu_0, sigma, alternative='two-sided'):
    """
    1標本z検定を実行する関数

    Parameters
    ----------
    data : array-like
        標本データ
    mu_0 : float
        帰無仮説の母平均
    sigma : float
        母標準偏差(既知)
    alternative : str
        'two-sided', 'greater', 'less'

    Returns
    -------
    z_stat : float
        検定統計量
    p_value : float
        p値
    """
    data = np.array(data)
    n = len(data)
    x_bar = np.mean(data)
    se = sigma / np.sqrt(n)

    # 検定統計量
    z_stat = (x_bar - mu_0) / se

    # p値の計算
    if alternative == 'two-sided':
        p_value = 2 * (1 - stats.norm.cdf(np.abs(z_stat)))
    elif alternative == 'greater':
        p_value = 1 - stats.norm.cdf(z_stat)
    elif alternative == 'less':
        p_value = stats.norm.cdf(z_stat)

    return z_stat, p_value


# 具体例: 工場の製品長さの検定
np.random.seed(42)
mu_0 = 50      # 帰無仮説の母平均
sigma = 2       # 母標準偏差(既知)
n = 25          # 標本サイズ

# 実際のデータ(母平均50.8から生成)
data = np.random.normal(50.8, sigma, n)

z_stat, p_value = z_test_one_sample(data, mu_0, sigma, alternative='two-sided')

print("=== 1標本z検定の結果 ===")
print(f"標本サイズ: n = {n}")
print(f"標本平均: x̄ = {np.mean(data):.4f}")
print(f"帰無仮説: μ = {mu_0}")
print(f"母標準偏差: σ = {sigma}")
print(f"検定統計量: Z = {z_stat:.4f}")
print(f"p値: {p_value:.4f}")
print(f"有意水準 α = 0.05 での判定: {'棄却' if p_value < 0.05 else '棄却しない'}")

2標本z検定のスクラッチ実装

import numpy as np
from scipy import stats

def z_test_two_sample(data1, data2, sigma1, sigma2, alternative='two-sided'):
    """
    2標本z検定を実行する関数

    Parameters
    ----------
    data1, data2 : array-like
        各群の標本データ
    sigma1, sigma2 : float
        各群の母標準偏差(既知)
    alternative : str
        'two-sided', 'greater', 'less'

    Returns
    -------
    z_stat : float
        検定統計量
    p_value : float
        p値
    """
    data1, data2 = np.array(data1), np.array(data2)
    n1, n2 = len(data1), len(data2)
    x_bar1, x_bar2 = np.mean(data1), np.mean(data2)

    # 標準誤差
    se = np.sqrt(sigma1**2 / n1 + sigma2**2 / n2)

    # 検定統計量
    z_stat = (x_bar1 - x_bar2) / se

    # p値の計算
    if alternative == 'two-sided':
        p_value = 2 * (1 - stats.norm.cdf(np.abs(z_stat)))
    elif alternative == 'greater':
        p_value = 1 - stats.norm.cdf(z_stat)
    elif alternative == 'less':
        p_value = stats.norm.cdf(z_stat)

    return z_stat, p_value


# 具体例: 2つの工場の製品重量の比較
np.random.seed(42)

# 工場A
sigma1 = 5.0
data1 = np.random.normal(102.5, sigma1, 36)

# 工場B
sigma2 = 4.5
data2 = np.random.normal(100.3, sigma2, 40)

z_stat, p_value = z_test_two_sample(data1, data2, sigma1, sigma2, alternative='two-sided')

print("=== 2標本z検定の結果 ===")
print(f"群1: n₁ = {len(data1)}, x̄₁ = {np.mean(data1):.4f}, σ₁ = {sigma1}")
print(f"群2: n₂ = {len(data2)}, x̄₂ = {np.mean(data2):.4f}, σ₂ = {sigma2}")
print(f"標本平均の差: {np.mean(data1) - np.mean(data2):.4f}")
print(f"検定統計量: Z = {z_stat:.4f}")
print(f"p値: {p_value:.4f}")
print(f"有意水準 α = 0.05 での判定: {'棄却' if p_value < 0.05 else '棄却しない'}")

z検定の可視化

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

def plot_z_test(z_obs, alpha=0.05, alternative='two-sided'):
    """
    z検定の結果を可視化する関数

    Parameters
    ----------
    z_obs : float
        観測された検定統計量
    alpha : float
        有意水準
    alternative : str
        'two-sided', 'greater', 'less'
    """
    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)$')

    if alternative == 'two-sided':
        z_crit = stats.norm.ppf(1 - alpha / 2)
        p_value = 2 * (1 - stats.norm.cdf(np.abs(z_obs)))

        # 棄却域(両側)を塗りつぶし
        x_right = x[x >= z_crit]
        ax.fill_between(x_right, stats.norm.pdf(x_right), color='red', alpha=0.3,
                        label=f'Rejection region ($\\alpha/2$ = {alpha/2})')
        x_left = x[x <= -z_crit]
        ax.fill_between(x_left, stats.norm.pdf(x_left), color='red', alpha=0.3)

        # 境界線
        ax.axvline(z_crit, color='red', linestyle='--', linewidth=1.5,
                   label=f'$z_{{\\alpha/2}}$ = $\\pm${z_crit:.3f}')
        ax.axvline(-z_crit, color='red', linestyle='--', linewidth=1.5)

    elif alternative == 'greater':
        z_crit = stats.norm.ppf(1 - alpha)
        p_value = 1 - stats.norm.cdf(z_obs)

        x_right = x[x >= z_crit]
        ax.fill_between(x_right, stats.norm.pdf(x_right), color='red', alpha=0.3,
                        label=f'Rejection region ($\\alpha$ = {alpha})')
        ax.axvline(z_crit, color='red', linestyle='--', linewidth=1.5,
                   label=f'$z_\\alpha$ = {z_crit:.3f}')

    elif alternative == 'less':
        z_crit = stats.norm.ppf(alpha)
        p_value = stats.norm.cdf(z_obs)

        x_left = x[x <= z_crit]
        ax.fill_between(x_left, stats.norm.pdf(x_left), color='red', alpha=0.3,
                        label=f'Rejection region ($\\alpha$ = {alpha})')
        ax.axvline(z_crit, color='red', linestyle='--', linewidth=1.5,
                   label=f'$-z_\\alpha$ = {z_crit:.3f}')

    # 観測された検定統計量
    ax.axvline(z_obs, color='blue', linewidth=2.5,
               label=f'$z_{{obs}}$ = {z_obs:.3f} (p = {p_value:.4f})')
    ax.plot(z_obs, stats.norm.pdf(z_obs), 'bo', markersize=8)

    ax.set_xlabel('$z$', fontsize=13)
    ax.set_ylabel('Probability Density', fontsize=13)
    ax.set_title(f'Z-Test ({alternative}, $\\alpha$ = {alpha})', fontsize=14)
    ax.legend(fontsize=10, loc='upper left')
    ax.set_ylim(bottom=0)
    ax.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()


# 両側検定の可視化
plot_z_test(z_obs=2.0, alpha=0.05, alternative='two-sided')

# 片側検定(右側)の可視化
plot_z_test(z_obs=1.8, alpha=0.05, alternative='greater')

# 片側検定(左側)の可視化
plot_z_test(z_obs=-2.3, alpha=0.05, alternative='less')

z検定とt検定の比較シミュレーション

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

np.random.seed(42)

# シミュレーション設定
mu_0 = 0        # 帰無仮説の母平均
mu_true = 0     # 真の母平均(H0が真のケース)
sigma = 1       # 母標準偏差
n_simulations = 50000

# 異なる標本サイズでの比較
sample_sizes = [5, 10, 30, 100]

fig, axes = plt.subplots(2, 2, figsize=(14, 10))
axes = axes.flatten()

for idx, n in enumerate(sample_sizes):
    z_stats = []
    t_stats = []

    for _ in range(n_simulations):
        sample = np.random.normal(mu_true, sigma, n)
        x_bar = np.mean(sample)
        s = np.std(sample, ddof=1)

        # z検定統計量(σ既知)
        z = (x_bar - mu_0) / (sigma / np.sqrt(n))
        z_stats.append(z)

        # t検定統計量(σ未知)
        t = (x_bar - mu_0) / (s / np.sqrt(n))
        t_stats.append(t)

    z_stats = np.array(z_stats)
    t_stats = np.array(t_stats)

    # ヒストグラム
    x_range = np.linspace(-5, 5, 200)
    axes[idx].hist(z_stats, bins=80, density=True, alpha=0.5, color='blue', label='Z statistics')
    axes[idx].hist(t_stats, bins=80, density=True, alpha=0.5, color='red', label='t statistics')

    # 理論分布
    axes[idx].plot(x_range, stats.norm.pdf(x_range), 'b-', linewidth=2, label='$N(0,1)$')
    axes[idx].plot(x_range, stats.t.pdf(x_range, df=n-1), 'r--', linewidth=2,
                   label=f'$t_{{{n-1}}}$')

    axes[idx].set_title(f'n = {n}', fontsize=13)
    axes[idx].set_xlabel('Statistic Value', fontsize=11)
    axes[idx].set_ylabel('Density', fontsize=11)
    axes[idx].legend(fontsize=9)
    axes[idx].set_xlim(-5, 5)
    axes[idx].grid(True, alpha=0.3)

plt.suptitle('Comparison of Z and t Statistics under $H_0$', fontsize=14, y=1.02)
plt.tight_layout()
plt.show()

信頼区間とz検定の関係

import numpy as np
from scipy import stats

def z_confidence_interval(data, sigma, confidence=0.95):
    """
    z検定に基づく信頼区間を計算する関数

    Parameters
    ----------
    data : array-like
        標本データ
    sigma : float
        母標準偏差(既知)
    confidence : float
        信頼水準

    Returns
    -------
    ci_lower, ci_upper : float
        信頼区間の下限・上限
    """
    data = np.array(data)
    n = len(data)
    x_bar = np.mean(data)
    se = sigma / np.sqrt(n)
    alpha = 1 - confidence
    z_crit = stats.norm.ppf(1 - alpha / 2)

    ci_lower = x_bar - z_crit * se
    ci_upper = x_bar + z_crit * se

    return ci_lower, ci_upper


# 具体例
np.random.seed(42)
sigma = 2
data = np.random.normal(50.8, sigma, 25)

ci_low, ci_high = z_confidence_interval(data, sigma, confidence=0.95)

print("=== z検定に基づく95%信頼区間 ===")
print(f"標本平均: {np.mean(data):.4f}")
print(f"95%信頼区間: [{ci_low:.4f}, {ci_high:.4f}]")
print(f"")
print("帰無仮説 μ₀ = 50 は信頼区間に含まれるか?")
mu_0 = 50
if ci_low <= mu_0 <= ci_high:
    print(f"  → μ₀ = {mu_0} は信頼区間に含まれる → H₀を棄却しない")
else:
    print(f"  → μ₀ = {mu_0} は信頼区間に含まれない → H₀を棄却する")
print(f"")

# z検定との対応を確認
z_stat, p_value = z_test_one_sample(data, mu_0, sigma, alternative='two-sided')
print(f"z検定の結果: Z = {z_stat:.4f}, p = {p_value:.4f}")
print(f"→ 信頼区間による判定とz検定の判定は{'一致' if (p_value < 0.05) != (ci_low <= mu_0 <= ci_high) else '一致'}します")

まとめ

本記事では、z検定の理論と導出について解説しました。

  • z検定の検定統計量: $Z = \frac{\bar{X} – \mu_0}{\sigma / \sqrt{n}} \sim N(0, 1)$($H_0$ のもと)
  • 前提条件: 母分散既知、または大標本(中心極限定理による正規近似)
  • 棄却域: 両側検定では $|Z| > z_{\alpha/2}$、片側検定では $Z > z_\alpha$ または $Z < -z_\alpha$
  • p値: 帰無仮説のもとで観測値以上に極端な値が得られる確率
  • t検定との違い: z検定は $\sigma$ 既知を仮定、t検定は $s$ で推定。$n$ が大きければ両者は一致

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