Когда использовал Mann-Whitney вместо Т-теста?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
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 по умолчанию.
Почему?
- Он работает хорошо в оба случая (нормальные и ненормальные данные)
- Он робастен к выбросам
- В аналитике продуктов данные редко нормальны
- Потеря мощности небольшая (~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 показывает, что я понимаю не просто механику тестов, а контекст их применения.