Один тест на уровне 5% ошибается в 5% случаев, если эффекта нет. А если смотреть 20 метрик, 10 сегментов и три варианта дизайна сразу? Почти наверняка что-то «прокрасится» случайно. Это проблема множественных проверок, и на собесе аналитика её ждут почти всегда.
Масштаб проблемы
При m независимых проверках, где эффектов нет, вероятность хотя бы одного ложного срабатывания:
FWER = 1 - (1 - α)^m
Для α = 0.05 и m = 20 это 1 - 0.95^20 ≈ 0.64. В двух случаях из трёх найдётся «значимая» метрика, которой на самом деле нет.
Две цели: FWER и FDR
- FWER (family-wise error rate): вероятность хотя бы одной ложной находки среди всех проверок. Строго, нужен, когда любая ложная находка дорого стоит: ключевая метрика решения, медицина.
- FDR (false discovery rate): ожидаемая доля ложных среди всех найденных. Мягче и мощнее, подходит для разведки: много метрик, много сегментов, скрининг идей.
Бонферрони
Каждый тест проверяют на уровне α / m. Или, что то же самое, умножают p-value на m (и обрезают единицей). Просто и гарантирует FWER ≤ α при любой зависимости тестов. Минус: при многих тестах сильно теряет мощность.
Холм (Holm-Bonferroni)
Пошаговая версия, всегда не хуже Бонферрони и тоже контролирует FWER:
- Отсортировать p-value по возрастанию:
p(1) ≤ p(2) ≤ ... ≤ p(m). - Сравнить
p(1)сα / m,p(2)сα / (m - 1), и так далее:p(k)сα / (m - k + 1). - Остановиться на первом p-value, которое не прошло. Все до него отвергаем, его и все после нет.
Скорректированные p-value по Холму: p̃(k) = max_{j ≤ k} min(1, (m - j + 1) · p(j)). Максимум нужен, чтобы скорректированные значения не убывали.
Бенджамини-Хохберг (BH)
Контролирует FDR:
- Отсортировать p-value по возрастанию.
- Найти наибольшее k, для которого
p(k) ≤ k / m · q(q, например, 0.05 или 0.1). - Отвергнуть гипотезы с 1-й по k-ю.
Скорректированные значения: p̃(k) = min_{j ≥ k} min(1, p(j) · m / j). Минимум идёт справа налево, чтобы значения не убывали. BH формально требует независимости или положительной зависимости тестов, что для метрик A/B обычно приемлемо.
Пример
p-value: 0.001, 0.012, 0.03, 0.04, 0.2 (m = 5, α = 0.05).
- Бонферрони: порог 0.01, проходит только 0.001.
- Холм: 0.001 ≤ 0.01 да, 0.012 ≤ 0.0125 да, 0.03 ≤ 0.0167 нет: стоп. Отвергаем две.
- BH: пороги 0.01, 0.02, 0.03, 0.04, 0.05. Наибольшее k с
p(k) ≤ порог: k = 4 (0.04 ≤ 0.04). Отвергаем четыре.
Как это выглядит в A/B
- Одна главная метрика. Решение принимают по ней, остальные метрики вспомогательные или guardrail. Тогда поправка нужна в основном на число вариантов.
- Несколько вариантов (A/B/C/D). Сравнения каждого с контролем это несколько проверок: нужна поправка (часто Холм или Даннет).
- Сегменты после теста. «В целом эффекта нет, но на Android в Казани +12%» почти всегда шум от перебора. Такие находки оформляют как гипотезу для нового теста.
- Подглядывание за одним тестом каждый день это тоже множественные проверки во времени. Лечится последовательными методами, а не Бонферрони.
Частые ошибки
- Смотреть 30 метрик и докладывать единственную значимую.
- Применять Бонферрони к сотням метрик и терять всю мощность, когда хватило бы FDR.
- Делать поправку, но выбирать набор метрик уже после того, как увидели результаты.
- Путать FDR и FWER: «BH гарантирует, что ложных нет».
Что спросят на собесе
- Почему нельзя проверять 20 метрик на уровне 0.05 и брать значимые?
- Чем FWER отличается от FDR?
- Как работают поправки Бонферрони, Холма и Бенджамини-Хохберга?
- Что делать с эффектом, найденным в одном сегменте после теста?
- Как учитывать несколько тестовых групп против одного контроля?