Поправка на множественное сравнение

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

Вы запустили A/B тест, зафиксировали одну метрику и получили результат. Один тест при alpha = 0.05 даёт 5% вероятность ложного срабатывания. Это приемлемо.

Но на практике вы смотрите не одну метрику. Конверсия, средний чек, количество сессий, bounce rate, время на сайте, retention — и так далее. Допустим, вы проверяете 20 метрик. Каждая — отдельная проверка гипотезы. Вероятность того, что хотя бы одна из них «выстрелит» по чистой случайности:

P(хотя бы 1 ложное срабатывание) = 1 - (1 - 0.05)^20 = 1 - 0.358 = 0.642

64%. Почти две трети. Проверяя 20 метрик при alpha = 0.05, вы с вероятностью 64% найдёте хотя бы один «значимый» результат при полном отсутствии реальных эффектов.

Это и есть проблема множественных сравнений (multiple comparisons problem). Она возникает всякий раз, когда вы проверяете несколько гипотез одновременно: несколько метрик в одном тесте, один тест по нескольким сегментам, несколько вариантов (A/B/C/D), post-hoc нарезка данных.

Решение — поправка на множественное сравнение. Она ужесточает порог значимости, чтобы общая вероятность ложного срабатывания осталась контролируемой.

FWER и FDR — два подхода к контролю ошибок

Прежде чем выбирать метод коррекции, нужно определить, что именно вы хотите контролировать. Есть два принципиально разных подхода.

FWER (Family-Wise Error Rate) — вероятность допустить хотя бы одно ложное срабатывание среди всех проверяемых гипотез. FWER = P(хотя бы один false positive). Контроль FWER гарантирует: с вероятностью не менее 1 - alpha среди всех отклонённых гипотез не будет ни одной ложной. Это строгий подход. Методы: Бонферрони, Холм.

FDR (False Discovery Rate) — ожидаемая доля ложных срабатываний среди всех отклонённых гипотез. Если из 10 отклонённых гипотез в среднем одна ложная — FDR = 10%. Контроль FDR мягче: он допускает отдельные ложные результаты, но контролирует их долю. Метод: Benjamini-Hochberg.

Выбор между FWER и FDR зависит от цены ошибки. Если каждое ложное «открытие» ведёт к дорогостоящему действию (раскатка фичи, изменение ценовой модели) — контролируйте FWER. Если вы исследуете десятки метрик и готовы к тому, что часть находок не подтвердится — достаточно FDR.

Бонферрони — простой и консервативный

Метод Бонферрони — самый известный и самый простой. Правило: разделите alpha на количество тестов.

alpha_corrected = alpha / m

где m — число проверяемых гипотез. При 5 метриках и alpha = 0.05 порог для каждой гипотезы — 0.01. При 20 метриках — 0.0025.

Эквивалентная формулировка: умножьте каждое p-value на m и сравните с исходным alpha. Скорректированное p-value = min(p * m, 1).

Плюсы: прост в применении, не требует предположений о зависимости между тестами, контролирует FWER.

Минусы: консервативен. Чем больше тестов, тем строже порог. При 100 гипотезах порог падает до 0.0005 — обнаружить реальный эффект становится крайне сложно. Мощность теста резко снижается. Если из 100 гипотез 10 реальных, Бонферрони пропустит большинство из них.

Бонферрони подходит, когда тестов немного (2–5), и вы хотите быть уверены в каждом результате.

Холм (Holm) — пошаговая коррекция

Метод Холма (Holm–Bonferroni) — улучшение Бонферрони. Он тоже контролирует FWER, но менее консервативен, потому что корректирует пороги пошагово.

Алгоритм:

  1. Отсортируйте p-value по возрастанию: p(1) <= p(2) <= ... <= p(m).
  2. Для i-го p-value сравните с alpha / (m - i + 1).
  3. Идите от наименьшего p-value. Первый тест, который не прошёл порог, — всё, дальше ничего не отклоняете.

Конкретнее: p(1) сравнивается с alpha / m (как у Бонферрони), p(2) — с alpha / (m - 1), p(3) — с alpha / (m - 2) и так далее. Каждый следующий порог чуть мягче.

Пример. Три метрики, p-value: 0.008, 0.030, 0.042. Alpha = 0.05.

Шаг p-value Порог (alpha / (m - i + 1)) Решение
1 0.008 0.05 / 3 = 0.0167 0.008 < 0.0167 — отклоняем
2 0.030 0.05 / 2 = 0.025 0.030 > 0.025 — не отклоняем, СТОП
3 0.042 0.05 / 1 = 0.05 не проверяем (стоп на шаге 2)

Бонферрони отклонил бы только первую гипотезу (порог 0.0167 для всех). Холм — тоже только первую, но при других данных разница может быть существенной. Холм никогда не хуже Бонферрони и иногда лучше.

Когда использовать: вместо Бонферрони, если нужен контроль FWER — Холм строго лучше.

Benjamini-Hochberg (FDR)

Метод Benjamini-Hochberg (BH) контролирует FDR — долю ложных открытий. Он значительно мощнее, чем FWER-методы, особенно при большом числе тестов.

Алгоритм:

  1. Отсортируйте p-value по возрастанию: p(1) <= p(2) <= ... <= p(m).
  2. Для i-го p-value вычислите порог: alpha * i / m.
  3. Найдите наибольшее i, при котором p(i) <= alpha * i / m.
  4. Отклоните все гипотезы от 1 до i.

Пример. Пять метрик, p-value: 0.001, 0.008, 0.030, 0.042, 0.120. Alpha = 0.05.

Ранг (i) p-value Порог (alpha * i / m) p <= порог?
1 0.001 0.05 * 1/5 = 0.010 да
2 0.008 0.05 * 2/5 = 0.020 да
3 0.030 0.05 * 3/5 = 0.030 да
4 0.042 0.05 * 4/5 = 0.040 нет
5 0.120 0.05 * 5/5 = 0.050 нет

Наибольшее i с p(i) <= порог — это i = 3. Отклоняем гипотезы 1, 2, 3. Бонферрони при тех же данных отклонил бы только гипотезу 1 (порог 0.01). Холм — гипотезы 1 и 2. BH — три гипотезы. Мощность выше.

Интерпретация FDR: при alpha = 0.05 метод гарантирует, что среди всех отклонённых гипотез ожидаемая доля ложных — не более 5%. Если отклонили 10 гипотез, в среднем не более 0.5 из них ложные.

Сравнение методов

Метод Контролирует Строгость Мощность Когда применять
Бонферрони FWER Высокая Низкая 2–5 тестов, цена ошибки высока
Холм FWER Средняя Средняя Вместо Бонферрони — всегда лучше или равен
Benjamini-Hochberg FDR Низкая Высокая Много тестов (10+), допустима небольшая доля ложных
Без поправки Ничего Максимальная Одна заранее определённая метрика

На практике в продуктовой аналитике чаще всего используют BH (FDR). Он даёт хороший баланс между контролем ошибок и способностью обнаруживать реальные эффекты. Бонферрони и Холм — для ситуаций, когда каждое ложное срабатывание критично.

Python: multipletests из statsmodels

В statsmodels все три метода доступны через одну функцию.

from statsmodels.stats.multitest import multipletests

p_values = [0.001, 0.008, 0.030, 0.042, 0.120]

# Бонферрони
rejected_b, corrected_b, _, _ = multipletests(p_values, alpha=0.05, method='bonferroni')
print("Бонферрони")
print("  Скорректированные p:", [round(p, 4) for p in corrected_b])
print("  Отклонить H0:      ", rejected_b.tolist())
# Скорректированные p: [0.005, 0.04, 0.15, 0.21, 0.6]
# Отклонить H0:       [True, True, False, False, False]

# Холм
rejected_h, corrected_h, _, _ = multipletests(p_values, alpha=0.05, method='holm')
print("\nХолм")
print("  Скорректированные p:", [round(p, 4) for p in corrected_h])
print("  Отклонить H0:      ", rejected_h.tolist())
# Скорректированные p: [0.005, 0.032, 0.09, 0.084, 0.12]
# Отклонить H0:       [True, True, False, False, False]

# Benjamini-Hochberg (FDR)
rejected_fdr, corrected_fdr, _, _ = multipletests(p_values, alpha=0.05, method='fdr_bh')
print("\nBenjamini-Hochberg (FDR)")
print("  Скорректированные p:", [round(p, 4) for p in corrected_fdr])
print("  Отклонить H0:      ", rejected_fdr.tolist())
# Скорректированные p: [0.005, 0.02, 0.05, 0.0525, 0.12]
# Отклонить H0:       [True, True, True, False, False]

Обратите внимание: Бонферрони отклонил 2 гипотезы, Холм — 2, BH — 3. Разница в мощности очевидна. Скорректированные p-value — это минимальный alpha, при котором гипотеза была бы отклонена. Их можно интерпретировать как обычные p-value, но уже с учётом поправки.

Практические советы

Фиксируйте метрики до эксперимента. Главная защита от множественных сравнений — не статистическая коррекция, а дисциплина. Определите одну первичную метрику и несколько вторичных до запуска теста. Поправку применяйте только к тем метрикам, которые заявлены заранее. Post-hoc анализ по незапланированным метрикам — это генерация гипотез, а не проверка.

Разделяйте первичные и вторичные метрики. Первичная метрика — та, по которой принимается решение. Если она одна — поправка не нужна. Вторичные метрики — для диагностики и контроля. Если вторичных 5+ — применяйте BH.

Не корректируйте guardrail-метрики. Guardrail-метрики проверяют, что тест не навредил. Для них работает другая логика: вы не ищете эффект, а контролируете риск. Поправка здесь неуместна.

Ограничивайте число тестов. Лучшая поправка — та, которая не нужна. Чем меньше метрик проверяете, тем меньше потери мощности. Три чётко сформулированные гипотезы лучше, чем двадцать «на всякий случай».

Учитывайте поправку при расчёте размера выборки. Если планируете проверять 5 метрик с поправкой Бонферрони, эффективный alpha = 0.01. Это требует большей выборки, чем при alpha = 0.05. Закладывайте это в расчёт длительности теста.

Вопросы с собеседований

«Вы проверяете 10 метрик в A/B-тесте. Одна показала p = 0.03. Что скажете?»

Без поправки этот результат кажется значимым. Но при 10 тестах и alpha = 0.05 вероятность хотя бы одного ложного срабатывания — 40%. Нужна поправка. По Бонферрони порог — 0.005, по Холму первый порог — тоже 0.005. Результат p = 0.03 не пройдёт ни один FWER-метод. По BH (FDR) — зависит от остальных p-value, но скорее всего тоже нет. Вывод: одиночный результат p = 0.03 из десяти — скорее ложное срабатывание.

«Чем Бонферрони отличается от FDR?»

Бонферрони контролирует FWER — вероятность хотя бы одного ложного срабатывания. FDR (Benjamini-Hochberg) контролирует долю ложных среди отклонённых. Бонферрони строже и консервативнее — при большом числе тестов теряет мощность. FDR мягче, сохраняет мощность, но допускает небольшую долю ложных находок. В продуктовой аналитике обычно используют FDR.

«Когда поправка на множественные сравнения не нужна?»

Когда проверяется ровно одна заранее зафиксированная гипотеза. Если вы до эксперимента определили одну первичную метрику — коррекция не требуется. Также поправка не нужна для guardrail-метрик и для exploratory-анализа, результаты которого будут проверены в отдельном эксперименте.

«Как метод Холма улучшает Бонферрони?»

Холм использует пошаговую процедуру: самый маленький p-value сравнивается с alpha/m (как у Бонферрони), но каждый следующий — с чуть более мягким порогом. Холм контролирует ту же FWER, но отклоняет больше гипотез. Он строго не хуже Бонферрони — нет ни одной причины использовать Бонферрони вместо Холма, кроме простоты объяснения.


Потренируйтесь решать задачи по A/B-тестам и статистике в Карьернике — тренажёре для подготовки к собеседованиям аналитиков.

FAQ

Что такое поправка на множественное сравнение?

Это ужесточение порога статистической значимости при проверке нескольких гипотез одновременно. Без поправки при 20 метриках и alpha = 0.05 вероятность хотя бы одного ложного срабатывания — 64%. Поправка (Бонферрони, Холм, FDR) контролирует эту вероятность.

Чем Бонферрони отличается от Benjamini-Hochberg (FDR)?

Бонферрони контролирует FWER — вероятность хотя бы одного ложного срабатывания среди всех тестов. FDR контролирует долю ложных среди отклонённых гипотез. Бонферрони строже и теряет мощность при большом числе тестов, FDR мягче и сохраняет способность находить реальные эффекты.

Когда поправка на множественные сравнения не нужна?

Когда проверяется ровно одна заранее зафиксированная гипотеза. Также поправка не нужна для guardrail-метрик и для exploratory-анализа, результаты которого будут проверены в отдельном эксперименте.

Из 20 метрик в A/B-тесте одна показала p = 0.03. Что это значит?

Скорее всего, это ложное срабатывание. При 20 тестах и alpha = 0.05 вероятность хотя бы одного случайного «значимого» результата — 64%. После поправки Бонферрони (порог 0.0025) или FDR результат p = 0.03 перестанет быть значимым.