Проверка гипотезы о неизвестном матожидании (известная дисперсия)

Разбираем сюжет с жирафами в трех вариантах: - левосторонний тест; - правосторонний тест; - двусторонний тест.

Общие условия применимости \(Z\)-теста для среднего: - наблюдения независимы; - либо распределение исследуемой величины нормальное, либо выборка достаточно большая; - известна истинная дисперсия \(\sigma^2\); - уровень значимости фиксирован: \(\alpha = 0.05\).

Во всех графиках показывается именно распределение выборочного среднего при нулевой гипотезе: \[ \bar X \mid H_0 \sim \mathcal N\!\left(\mu_0, \frac{\sigma^2}{n}\right). \]

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


def plot_xbar_test(mu0, sigma, n, x_bar, alpha=0.05, kind='left', title=''):
    se = sigma / np.sqrt(n)
    x_grid = np.linspace(mu0 - 4 * se, mu0 + 4 * se, 1000)
    y_grid = norm.pdf(x_grid, loc=mu0, scale=se)

    plt.figure(figsize=(8, 4))
    plt.plot(x_grid, y_grid, lw=2, label='Плотность распределения $\\bar{X}$ при $H_0$')

    if kind == 'left':
        z_crit = norm.ppf(alpha)
        k = mu0 + z_crit * se
        mask = x_grid <= k
        plt.fill_between(x_grid[mask], y_grid[mask], alpha=0.35, color='tomato', label='Критическая зона')
        plt.axvline(k, color='tomato', ls='--', lw=2, label=f'K = {k:.3f}')
    elif kind == 'right':
        z_crit = norm.ppf(1 - alpha)
        k = mu0 + z_crit * se
        mask = x_grid >= k
        plt.fill_between(x_grid[mask], y_grid[mask], alpha=0.35, color='tomato', label='Критическая зона')
        plt.axvline(k, color='tomato', ls='--', lw=2, label=f'K = {k:.3f}')
    elif kind == 'two-sided':
        z_half = norm.ppf(1 - alpha / 2)
        k_l = mu0 - z_half * se
        k_r = mu0 + z_half * se
        mask_l = x_grid <= k_l
        mask_r = x_grid >= k_r
        plt.fill_between(x_grid[mask_l], y_grid[mask_l], alpha=0.35, color='tomato', label='Критические зоны')
        plt.fill_between(x_grid[mask_r], y_grid[mask_r], alpha=0.35, color='tomato')
        plt.axvline(k_l, color='tomato', ls='--', lw=2, label=f'K_L = {k_l:.3f}')
        plt.axvline(k_r, color='tomato', ls='--', lw=2, label=f'K_R = {k_r:.3f}')
    else:
        raise ValueError("kind должен быть 'left', 'right' или 'two-sided'")

    plt.axvline(x_bar, color='navy', lw=2, label=f'Наблюдаемое $\\bar{{x}}$ = {x_bar:.3f}')
    plt.title(title)
    plt.xlabel('$\\bar{X}$')
    plt.ylabel('Плотность')
    plt.legend(loc='upper left')
    plt.grid(alpha=0.2)
    plt.show()

1) Левосторонний тест

Условия задачи: - \(X\) — длина шеи жирафа (м); - независимая выборка объема \(n = 20\); - известное стандартное отклонение \(\sigma = 0.4\); - наблюдаемое среднее \(\bar x = 2.8\); - проверяем гипотезу о среднем \(\mu_0 = 6.0\) при \(\alpha = 0.05\).

Теория: - гипотезы: \(H_0: \mu = \mu_0\) против \(H_1: \mu < \mu_0\); - при \(H_0\): \[ \bar X \sim \mathcal N\!\left(\mu_0, \frac{\sigma^2}{n}\right); \] - решающая граница задается условием: \[ P_{H_0}(\bar X < K) = \alpha; \] - стандартизуем и делаем замену переменной: \[ P\!\left(\frac{\bar X-\mu_0}{\sigma/\sqrt n} < \frac{K-\mu_0}{\sigma/\sqrt n}\right)=\alpha \Rightarrow P(Z<z_\alpha)=\alpha; \]

  • нужно понимать, что так как \(\alpha\) по своей логике должна быть небольшой вероятностью и по здравому смыслу меньше \(0.5\), то в уравнении выше эта точка по факту будет отрицательной. Можно обозначить ее \((-|z_{\alpha}|)\), чтобы не было сомнений.
  • восстанавливаем границу: \[ \frac{K-\mu_0}{\sigma/\sqrt n}=-|z_{\alpha}| \Rightarrow K=\mu_0 - |z_\alpha| \frac{\sigma}{\sqrt n}; \]
  • правило: отклоняем \(H_0\), если \(\bar x < K\).
# Левосторонний тест
mu0 = 6.0
sigma = 0.4
n = 20
x_bar = 2.8
alpha = 0.05

z_alpha = norm.ppf(1 - alpha)
K = mu0 - z_alpha * sigma / np.sqrt(n)

print(f"K = {K:.3f}")
print("Решение:", "Отклоняем H0" if x_bar < K else "Не отклоняем H0")

plot_xbar_test(
    mu0=mu0,
    sigma=sigma,
    n=n,
    x_bar=x_bar,
    alpha=alpha,
    kind='left',
    title='Левосторонний тест: распределение $\\bar{X}$ при $H_0$'
)

2) Правосторонний тест

Условия задачи: - \(X\) — длина шеи жирафа (м); - независимая выборка объема \(n = 20\); - известное стандартное отклонение \(\sigma = 0.1\); - наблюдаемое среднее \(\bar x = 2.8\); - проверяем гипотезу о среднем \(\mu_0 = 1.8\) при \(\alpha = 0.05\).

Теория: - гипотезы: \(H_0: \mu = \mu_0\) против \(H_1: \mu > \mu_0\); - при \(H_0\): \[ \bar X \sim \mathcal N\!\left(\mu_0, \frac{\sigma^2}{n}\right); \] - решающая граница задается условием: \[ P_{H_0}(\bar X > K) = \alpha; \] - стандартизуем и делаем замену переменной: \[ P\!\left(\frac{\bar X-\mu_0}{\sigma/\sqrt n} > \frac{K-\mu_0}{\sigma/\sqrt n}\right)=\alpha \Rightarrow P(Z>z_{\alpha})=\alpha; \] - снова так как \(\alpha\) по своей логике должна быть небольшой вероятностью и по здравому смыслу меньше \(0.5\), то в уравнении выше эта точка должна быть положительной. Тут не возникнет путаницы, можно продолжать без знака модуля.

  • восстанавливаем границу: \[ \frac{K-\mu_0}{\sigma/\sqrt n}=z_{\alpha} \Rightarrow K=\mu_0+z_{\alpha}\frac{\sigma}{\sqrt n}; \]
  • правило: отклоняем \(H_0\), если \(\bar x > K\).
# Правосторонний тест
mu0 = 1.8
sigma = 0.1
n = 20
x_bar = 2.8
alpha = 0.05

z_alpha = norm.ppf(1 - alpha)
K = mu0 + z_alpha * sigma / np.sqrt(n)

print(f"K = {K:.3f}")
print("Решение:", "Отклоняем H0" if x_bar > K else "Не отклоняем H0")

plot_xbar_test(
    mu0=mu0,
    sigma=sigma,
    n=n,
    x_bar=x_bar,
    alpha=alpha,
    kind='right',
    title='Правосторонний тест: распределение $\\bar{X}$ при $H_0$'
)

3) Двусторонний тест

Условия задачи (модификация): - \(X\) — длина шеи жирафа (м); - независимая выборка объема \(n = 20\); - известное стандартное отклонение \(\sigma = 0.4\); - наблюдаемое среднее \(\bar x = 2.8\); - проверяем гипотезу о среднем \(\mu_0 = 3.0\) при \(\alpha = 0.05\).

Теория: - гипотезы: \(H_0: \mu = \mu_0\) против \(H_1: \mu \neq \mu_0\); - при \(H_0\): \[ \bar X \sim \mathcal N\!\left(\mu_0, \frac{\sigma^2}{n}\right); \] - границы задаются условиями: \[ P_{H_0}(\bar X < K_L)=\frac{\alpha}{2},\qquad P_{H_0}(\bar X > K_R)=\frac{\alpha}{2}; \] - стандартизуем и делаем замену переменной: \[ P\!\left(\frac{K_L-\mu_0}{\sigma/\sqrt n} < Z < \frac{K_R-\mu_0}{\sigma/\sqrt n}\right)=1-\alpha \Rightarrow P(-z_{\alpha/2}<Z<z_{\alpha/2})=1-\alpha; \] - восстанавливаем границы: \[ K_L=\mu_0-z_{\alpha/2}\frac{\sigma}{\sqrt n},\qquad K_R=\mu_0+z_{\alpha/2}\frac{\sigma}{\sqrt n}; \] - правило: отклоняем \(H_0\), если \(\bar x < K_L\) или \(\bar x > K_R\).

# Двусторонний тест
mu0 = 3.0
sigma = 0.4
n = 20
x_bar = 2.8
alpha = 0.05

z_half = norm.ppf(1 - alpha / 2)
K_L = mu0 - z_half * sigma / np.sqrt(n)
K_R = mu0 + z_half * sigma / np.sqrt(n)

print(f"K_L = {K_L:.3f}, K_R = {K_R:.3f}")
print("Решение:", "Отклоняем H0" if (x_bar < K_L or x_bar > K_R) else "Не отклоняем H0")

plot_xbar_test(
    mu0=mu0,
    sigma=sigma,
    n=n,
    x_bar=x_bar,
    alpha=alpha,
    kind='two-sided',
    title='Двусторонний тест: распределение $\\bar{X}$ при $H_0$'
)