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

Когда использовал Mann-Whitney вместо Т-теста?

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

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

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

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

Mann-Whitney vs T-тест: когда и почему я выбираю Mann-Whitney

Это отличный вопрос, который показывает, что интервьюер ожидает понимания не просто статистики, а контекста её применения. Разберу, когда я использую Mann-Whitney вместо T-теста, и почему это критично.

Быстрое напоминание

T-тест (параметрический):

  • Предполагает нормальное распределение данных
  • Чувствителен к выбросам
  • Более мощный, если данные действительно нормальны
  • Проверяет среднее значение (mean)

Mann-Whitney (непараметрический):

  • Не предполагает нормальное распределение
  • Устойчив к выбросам
  • Менее мощный в идеальных условиях
  • Проверяет медиану (median)

Когда я выбираю Mann-Whitney в аналитике

Сценарий 1: Данные явно ненормальны

Пример: Распределение ценн заказов в e-commerce

У 80% заказов чек $20-100
У 15% заказов чек $100-500
У 5% заказов чек $500-5000

Это классическое логнормальное распределение (очень распространено в финансах и e-commerce).

T-тест предполагает:

Мean = $150
Std = $200
→ Очень большие выбросы доминируют в расчётах

Mann-Whitney проверяет:

Median = $50
→ Более репрезентативно для типичного пользователя

Когда я это использовал: Тестировал новый ценовой алгоритм. T-тест показал +10% в среднем чеке (p=0.02), но это было только из-за нескольких больших заказов (выбросы). Mann-Whitney показал +2% в медиане (p=0.25), что более честно. Развернул ограниченно, не полностью.


Сценарий 2: Много нулей в данных

Пример: Количество покупок на пользователя

У 70% пользователей: 0 покупок (не заказывали в период теста)
У 20% пользователей: 1-3 покупки
У 10% пользователей: 4-10+ покупок

Распределение с много нулями = zero-inflated distribution.

T-тест:

  • Предполагает нормальность, которой нет
  • Может дать ложно значимый результат
  • Mean = 0.3 (в основном нули искажают результат)

Mann-Whitney:

  • Проверяет: изменилась ли медиана?
  • Медиана может быть 0 и для control, и для variant
  • Лучше находит реальный эффект на активных пользователей

Когда я это использовал: Тестировал новый способ ввода данных в форме (он должен был увеличить conversion). T-тест показал p=0.12 (не значимо). Mann-Whitney показал p=0.04 (значимо). Более глубокий анализ показал: число покупок не выросло, но среди тех, кто купил, покупали чаще. Mann-Whitney это поймал, T-тест упустил.


Сценарий 3: Экстремальные выбросы

Пример: Время, проведённое в приложении

Типичный пользователь: 10-30 минут в день
Один пользователь: забыл закрыть приложение, 48 часов

T-тест:

Mean (control) = 25 минут
Mean (variant) = 180 минут (потому что одного выброса достаточно)
p-value = 0.04 (кажется, победа)
На самом деле: ложный результат

Mann-Whitney:

Median (control) = 25 минут
Median (variant) = 26 минут
p-value = 0.8 (нет эффекта)
Правда

Когда я это использовал: Тестировал новый фич, который должен был увеличить engagement. T-тест показал p=0.03 (победа). Mann-Whitney показал p=0.64 (нет победы). После очистки выбросов (боты, забытые сессии) выяснилось, что Mann-Whitney был прав. Нет эффекта.


Сценарий 4: Ранжированные/порядковые данные

Пример: NPS Score (от 0 до 10)

Это не совсем непрерывные данные
Ranging: 0, 1, 2, 3, ..., 10
Есть некоторая дискретность

T-тест: Работает, но не идеален Mann-Whitney: Лучше, потому что работает с рангами

Когда я это использовал: Тестировал новую версию приложения, сравнивал NPS. T-тест: p=0.08. Mann-Whitney: p=0.02. Mann-Whitney нашёл сигнал, который T-тест пропустил (потому что NPS не совсем нормально распределён).

Как я выбираю между ними на практике

Шаг 1: Проверю распределение визуально

import numpy as np
import matplotlib.pyplot as plt

# Histogramma
plt.hist(control_data, bins=30, alpha=0.5)
plt.hist(variant_data, bins=30, alpha=0.5)
plt.show()

Если гистограмма не похожа на колокол (normal curve), использую Mann-Whitney.

Шаг 2: Статистический тест нормальности

from scipy.stats import shapiro

# Shapiro-Wilk test
stat, p_value = shapiro(control_data)
if p_value < 0.05:
    print("Данные NOT нормальные, используй Mann-Whitney")
else:
    print("Данные похожи на нормальные, можно T-тест")

Шаг 3: Проверю выбросы

# IQR method
Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)
IQR = Q3 - Q1

outliers = (data < Q1 - 1.5*IQR) | (data > Q3 + 1.5*IQR)
if outliers.sum() > 0.05 * len(data):  # Более 5% выбросов
    print("Много выбросов, используй Mann-Whitney")

Шаг 4: Выбор

Если нормально + нет выбросов → T-тест (более мощный)
Если ненормально ИЛИ много выбросов → Mann-Whitney (более надёжный)
Если сомневаюсь → Mann-Whitney (безопаснее)

Практический пример из реальной аналитики

Ситуация: A/B тест на Москве. Тестируем дизайн кнопки "Купить".

Метрика: Revenue per user

Данные:

Control Group: N=5000
- Mean = $45
- Median = $30
- 95% CI = $38-52
- Distribution: очень right-skewed (длинный хвост)

Variant Group: N=5000
- Mean = $48
- Median = $32
- 95% CI = $40-56
- Distribution: также right-skewed

T-тест:

from scipy.stats import ttest_ind

t_stat, p_value = ttest_ind(control, variant)
print(f"T-test p-value: {p_value}")  # p = 0.045 (значимо!)

Mann-Whitney:

from scipy.stats import mannwhitneyu

u_stat, p_value = mannwhitneyu(control, variant)
print(f"Mann-Whitney p-value: {p_value}")  # p = 0.32 (не значимо)

Интерпретация:

  • T-тест: p=0.045 → развернуть (неправильно)
  • Mann-Whitney: p=0.32 → не развёртывать (правильно)

Глубокий анализ:

Контроль: 500 больших заказов в $200+ (высокие выбросы)
Вариант: 400 больших заказов в $200+ (низкие выбросы)
→ Медиана одинаковая, но high-end заказов в control больше
→ T-тест ловился на выбросы, Mann-Whitney более объективен

Правильное решение: Не развёртывать. Дизайн кнопки не повлиял на типичного пользователя (медиана одинаковая).

Когда я ВСЕГДА использую Mann-Whitney

AOV (Average Order Value) — логнормальное распределение ✓ Time-to-event — экспоненциальное распределение ✓ Количество действий — часто zero-inflated ✓ Рейтинги/NPS — порядковые данные ✓ Редкие события (например, количество рефералов) — очень ненормальные ✓ Bounce rate — бинарное + агрегированное = часто ненормально

Когда я ВСЕГДА использую T-тест

Click-through rate — при большом sample size (CLT спасает) ✓ Conversion rate — при N > 1000 по группе ✓ Средний рейтинг (не распределение рейтингов) — нормально ✓ Если распределение явно нормально (например, результаты теста IQ)

Мой совет Product Analyst

Просто используй Mann-Whitney по умолчанию.

Почему?

  1. Он работает хорошо в оба случая (нормальные и ненормальные данные)
  2. Он робастен к выбросам
  3. В аналитике продуктов данные редко нормальны
  4. Потеря мощности небольшая (~95% от T-теста)
# Один, универсальный выбор
def test_ab_result(control, variant):
    from scipy.stats import mannwhitneyu
    u_stat, p_value = mannwhitneyu(control, variant, alternative='two-sided')
    return p_value < 0.05  # Значимо ли?

Частая ошибка

❌ Неправильно:

Я посчитал T-test, p=0.03, давайте развёртывать!

✓ Правильно:

Я посчитал T-test, но сначала проверил распределение (right-skewed).
Потом посчитал Mann-Whitney, p=0.45.
Это противоречие. Нужен более глубокий анализ.

Вывод

Mann-Whitney — это не альтернатива, это необходимость в аналитике. T-тест работает в лабораторных условиях с нормальными данными. Но реальные продуктовые данные — это чаще всего логнормальные распределения с выбросами. Mann-Whitney это понимает, а T-тест часто ошибается. Выбор Mann-Whitney показывает, что я понимаю не просто механику тестов, а контекст их применения.

Когда использовал Mann-Whitney вместо Т-теста? | PrepBro