← Назад к вопросам

В чем разница между t-тестом и тестом Манна-Уитни?

2.2 Middle🔥 151 комментариев
#Статистика и A/B тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

T-тест vs Тест Манна-Уитни: полное сравнение

Оба теста используются для сравнения двух групп данных, но они основаны на разных предположениях и работают с разными типами данных. Выбор между ними критичен для корректности статистического анализа.

T-тест (Student's t-test)

Назначение: Проверяет, отличаются ли средние значения двух групп значимо.

Нулевая гипотеза (H0): μ₁ = μ₂ (средние двух групп равны)

Альтернативная гипотеза (H1): μ₁ ≠ μ₂ (средние отличаются)

Основные предположения:

  1. Нормальность: Данные в обеих группах должны быть нормально распределены
  2. Гомогенность дисперсии: Дисперсии двух групп должны быть примерно равны
  3. Независимость: Наблюдения в двух группах независимы
  4. Количественные данные: Данные должны быть непрерывными и количественными

Формула статистики t:

t = (x₁ - x₂) / sqrt(s²ₚ * (1/n₁ + 1/n₂))

где:
x₁, x₂ — средние значения групп
s²ₚ — объединенная дисперсия
n₁, n₂ — размеры групп

Пример реализации:

from scipy import stats
import numpy as np

# Две группы данных
group1 = np.array([23, 45, 56, 78, 89, 95, 102, 110])
group2 = np.array([15, 32, 48, 61, 73, 88, 99, 105])

# Independent samples t-test
t_statistic, p_value = stats.ttest_ind(group1, group2)

print(f"T-statistic: {t_statistic:.4f}")
print(f"P-value: {p_value:.4f}")

if p_value < 0.05:
    print("Отвергаем H0: средние значения значимо отличаются")
else:
    print("Не отвергаем H0: средние значения не отличаются")

Пример интерпретации:

Группа 1 (обучение с методом А): среднее = 78, SD = 20
Группа 2 (обучение с методом В): среднее = 62, SD = 22

t-тест: t = 1.85, p = 0.083
Вывод: При α = 0.05, нет значимого различия между методами обучения

Тест Манна-Уитни (Mann-Whitney U test)

Назначение: Непараметрический альтернатив t-тесту. Проверяет, отличаются ли распределения двух групп.

Нулевая гипотеза (H0): Два распределения идентичны (или медианы равны)

Альтернативная гипотеза (H1): Распределения отличаются

Основные предположения:

  1. Независимость: Наблюдения независимы
  2. Порядковые/количественные данные: Данные должны быть хотя бы ординальными
  3. НЕ требует нормальности: Работает с любыми распределениями
  4. НЕ требует равных дисперсий: Не чувствителен к разным дисперсиям

Как это работает (на примере U-статистики):

1. Объединить две группы и отранжировать все значения от 1 до n₁+n₂
2. Суммировать ранги для первой группы: R₁
3. Вычислить U-статистику: U = n₁*n₂ + n₁(n₁+1)/2 - R₁
4. Найти p-value на основе U

Пример реализации:

from scipy import stats
import numpy as np

# Две группы данных (может быть любое распределение)
group1 = np.array([23, 45, 56, 78, 89, 95, 102, 110])
group2 = np.array([15, 32, 48, 61, 73, 88, 99, 105])

# Mann-Whitney U test
u_statistic, p_value = stats.mannwhitneyu(group1, group2, alternative='two-sided')

print(f"U-statistic: {u_statistic:.4f}")
print(f"P-value: {p_value:.4f}")

# Также можно получить медианы
print(f"Медиана группы 1: {np.median(group1)}")
print(f"Медиана группы 2: {np.median(group2)}")

Пример с ранжированием

Группа 1: [10, 20, 30]
Группа 2: [15, 25, 35]

Объединенные и отранжированные:
Значение: 10   15   20   25   30   35
Ранг:     1    2    3    4    5    6
Группа:   1    2    1    2    1    2

R₁ = 1 + 3 + 5 = 9
R₂ = 2 + 4 + 6 = 12

U = 3*3 + 3(3+1)/2 - 9 = 9 + 6 - 9 = 6

Сравнение: t-тест vs Манна-Уитни

АспектT-тестМанна-Уитни
ТипПараметрическийНепараметрический
Требует нормальностиДАНЕТ
Требует равных дисперсийДАНЕТ
Тип данныхКоличественные (непрерывные)Ординальные, количественные
Что сравниваетСредниеМедианы (или распределения)
МощностьВыше (если условия выполнены)Ниже, но более робустен
ВыбросыЧувствителенУстойчив (использует ранги)
Размер выборкиНужно n > 30Работает на малых выборках
P-valueНа основе t-распределенияНа основе U-распределения

Практический пример: когда выбрать что

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

# Пример 1: Нормальные данные
normal_group1 = np.random.normal(100, 15, 50)  # μ=100, σ=15
normal_group2 = np.random.normal(110, 15, 50)  # μ=110, σ=15

# Проверка нормальности (тест Шапиро-Уилка)
stat1, p1 = shapiro(normal_group1)
stat2, p2 = shapiro(normal_group2)
print(f"Нормальные данные - p1: {p1:.4f}, p2: {p2:.4f}")

if p1 > 0.05 and p2 > 0.05:
    print("Данные нормальны → используй t-тест")
    t_stat, t_p = stats.ttest_ind(normal_group1, normal_group2)
    print(f"t-тест: t={t_stat:.4f}, p={t_p:.4f}")
else:
    print("Данные не нормальны → используй Манна-Уитни")

# Пример 2: Ненормальные данные (с выбросами)
outlier_group1 = np.concatenate([np.random.normal(100, 10, 48), [500, 510]])  # два выброса
outlier_group2 = np.random.normal(110, 10, 50)

stat1, p1 = shapiro(outlier_group1)
stat2, p2 = shapiro(outlier_group2)
print(f"\nДанные с выбросами - p1: {p1:.6f}, p2: {p2:.4f}")

print(f"Средние: {np.mean(outlier_group1):.1f} vs {np.mean(outlier_group2):.1f}")
print(f"Медианы: {np.median(outlier_group1):.1f} vs {np.median(outlier_group2):.1f}")

# t-тест пострадает от выбросов
t_stat, t_p = stats.ttest_ind(outlier_group1, outlier_group2)
print(f"t-тест: t={t_stat:.4f}, p={t_p:.4f}")

# Манна-Уитни более робустен
u_stat, u_p = stats.mannwhitneyu(outlier_group1, outlier_group2)
print(f"Манна-Уитни: u={u_stat:.4f}, p={u_p:.4f}")

Варианты t-теста

1. Independent samples t-test

Для независимых групп (разные люди):

stats.ttest_ind(group1, group2)

2. Paired samples t-test

Для зависимых групп (один и тот же человек до и после):

before = np.array([10, 20, 30, 40, 50])
after = np.array([12, 22, 32, 42, 52])

stats.ttest_rel(before, after)  # rel = related/paired

3. Welch's t-test

Для независимых групп с неравными дисперсиями:

stats.ttest_ind(group1, group2, equal_var=False)  # Welch's t-test

Проверка предположений перед выбором теста

from scipy.stats import shapiro, levene

def choose_test(group1, group2):
    # 1. Проверка нормальности (Shapiro-Wilk)
    _, p_norm1 = shapiro(group1)
    _, p_norm2 = shapiro(group2)
    normal = p_norm1 > 0.05 and p_norm2 > 0.05
    
    # 2. Проверка равности дисперсий (Levene's test)
    _, p_var = levene(group1, group2)
    equal_var = p_var > 0.05
    
    print(f"Нормальность: {normal}, Равные дисперсии: {equal_var}")
    
    if normal and equal_var:
        print("→ Используй t-тест (Independent samples)")
        t_stat, p_val = stats.ttest_ind(group1, group2)
    elif normal and not equal_var:
        print("→ Используй Welch's t-тест")
        t_stat, p_val = stats.ttest_ind(group1, group2, equal_var=False)
    else:
        print("→ Используй Манна-Уитни (более робустен)")
        t_stat, p_val = stats.mannwhitneyu(group1, group2)
    
    return t_stat, p_val

Effect Size

P-value показывает значимость, но не величину эффекта. Используй Cohen's d:

def cohens_d(group1, group2):
    n1, n2 = len(group1), len(group2)
    var1, var2 = np.var(group1, ddof=1), np.var(group2, ddof=1)
    pooled_std = np.sqrt(((n1-1)*var1 + (n2-1)*var2) / (n1+n2-2))
    return (np.mean(group1) - np.mean(group2)) / pooled_std

effect = cohens_d(group1, group2)
print(f"Cohen's d: {effect:.3f}")
# Интерпретация: 0.2 (малый), 0.5 (средний), 0.8 (большой)

Практический совет для Data Scientist

  1. Всегда проверяй предположения перед выбором теста
  2. На маленьких выборках (n<30) предпочтитай Манна-Уитни
  3. С выбросами в данных используй Манна-Уитни
  4. На нормальных данных больших размеров t-тест имеет большую мощность
  5. Всегда репортируй effect size, не только p-value
  6. Визуализируй данные перед тестированием
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(12, 4))

# Box plot
axes[0].boxplot([group1, group2])
axes[0].set_title('Distribution')

# Histogram
axes[1].hist(group1, alpha=0.5, label='Group 1')
axes[1].hist(group2, alpha=0.5, label='Group 2')
axes[1].legend()
axes[1].set_title('Histograms')

# Q-Q plot (для проверки нормальности)
from scipy.stats import probplot
probplot(group1, dist="norm", plot=axes[2])
axes[2].set_title('Q-Q Plot (Group 1)')

plt.tight_layout()
plt.show()

Выбор между t-тестом и Манна-Уитни — это выбор между мощностью (t-тест при нормальности) и робустностью (Манна-Уитни при любых распределениях). Правильный выбор обеспечивает корректные статистические выводы.

В чем разница между t-тестом и тестом Манна-Уитни? | PrepBro