Семь типичных ошибок A/B-тестирования. Их объединяет
общий паттерн: каждая даёт правдоподобные на вид
результаты, проходит peer-review, и приводит к
решениям. И каждая из них — воспроизводимый
ложноположительный вердикт, который оборачивается
против команды через месяц-два после раскатки.
Каждая ошибка описана в трёх частях: как выглядит,
почему это проблема, что делать правильно. Распознать
ошибку важнее чем избежать — большинство аналитиков
сталкивается с большинством этих ошибок в первый год
работы. Цель этого модуля — научить видеть симптом
до того как pull request с результатами уже одобрен.
1. Ошибка единицы анализа
Одна из самых частых ловушек в продуктовой аналитике — считать метрику на одном уровне,
а рандомизацию проводить на другом. Особенно часто это проявляется в виде fan-out:
когда один пользователь генерирует много событий (сессий, заказов, показов) и получает
непропорционально большой вес в тесте.
Как выглядит ошибка
Допустим, вы запустили A/B-тест на уровне пользователей (рандомизация по user_id),
но используете метрику «конверсия сессии в покупку»: доля сессий, в которых была покупка.
Пользователь, который заходит 10 раз в день, даёт в выборку в 10 раз больше сессий,
чем пользователь с одной сессией. При этом treatment назначен обоим одинаково — как одному объекту.
Аналитик считает t-test по сессиям, получает N = 5 000 000 сессий и p = 0.02.
Вывод: «эффект значим, можно выкатывать». Но на уровне пользователей всё может быть совсем иначе.
Почему это проблема
Нарушается предпосылка независимых одинаково распределённых наблюдений: сессии одного пользователя
сильно скоррелированы.
Происходит искусственное раздувание выборки: кажется, что у нас миллионы наблюдений,
хотя реальное число независимых единиц — количество пользователей.
В результате стандартные ошибки занижаются, доверительные интервалы сжимаются,
а доля ложноположительных результатов резко растёт.
\(\text{SE}_{\text{event-level}} < \text{SE}_{\text{user-level}}\) при наличии fan-out
Мини-пример
Представьте двух пользователей:
Пользователь A: 1 сессия, 1 покупка.
Пользователь B: 50 сессий, 1 покупка.
На уровне пользователей конверсия в покупку: A = 100%, B = 100% → средняя конверсия = 100%.
На уровне сессий: всего 51 сессия и 2 покупки → конверсия сессии ≈ 3.9%.
Пользователь с 50 сессиями получил 50 голосов вместо одного.
Что делать правильно
Правило:единица анализа должна совпадать с единицей рандомизации.
Если рандомизируете по пользователям — агрегируйте данные до user-level
(одна строка на пользователя) и считайте метрики на этом уровне.
Если рандомизируете по кластерам (города, магазины, курьерские зоны) — агрегируйте
до уровня кластера или используйте cluster-robust стандартные ошибки.
Если по бизнес-причинам вы хотите метрику на другом уровне (например, по сессиям) —
всё равно обеспечьте, чтобы один пользователь не получал сверхвес (обрезка fan-out, взвешивание).
Опасный симптом: если N в отчёте измеряется миллионами событий, а эксперимент
запускался «на пользователях», почти наверняка у вас ошибка единицы анализа.
2. Ratio-метрики: «ratio of means» vs «mean of ratios»
Многие ключевые продуктовые и бизнес-метрики — это отношения двух величин:
AOV = GMV / Orders, RPM = Revenue / Impressions, ARPU = Revenue / Users.
Для них есть два принципиально разных способа оценки: «ratio of means» и «mean of ratios».
Как выглядит ошибка
Аналитик берёт данные на уровне пользователя и считает:
AOVi = GMVi / Ordersi
Затем берёт простой средний:
\(\text{mean of ratios} = \frac{1}{n}\sum_{i=1}^{n} AOV_i\)
В этом случае пользователь с 1 заказом и пользователь со 100 заказами получают
одинаковый вес в оценке AOV.
Разница почти в два раза, потому что heavy user B «размыт» при одинаковом весе с A.
Почему это проблема
Смещённая оценка. Mean of ratios отвечает на вопрос
«средний чек среднего пользователя», а ratio of means — «средний чек заказа».
В большинстве бизнес-кейсов вас интересует именно второй вариант.
Риск парадокса Симпсона. В разных сегментах (частота, категории)
mean of ratios и ratio of means могут вести себя в разные стороны.
Неправильный выбор теста. Наивный t-test по пользовательским AOVi
игнорирует сложную дисперсионную структуру ratio-метрики.
Что делать правильно
Для ratio-метрик используйте ratio of means:
агрегируйте числитель и знаменатель по группе и берите их отношение.
перестановочные тесты или bootstrap по пользователям, который учитывает зависимость GMV и Orders;
специализированные калькуляторы (например, симуляторы и metric_classifier), которые
подскажут тип метрики и допустимые тесты.
Связь с симуляторами: пропустите вашу метрику через
«Классификатор метрик» и «Карту выбора статкритерия»,
чтобы проверить, не применяете ли вы t-test к сложной ratio-метрике.
3. Выбор метрики после просмотра данных (p-hacking)
Соблазн «немного покопаться в данных» после того, как основная метрика не дала результата,
знаком почти каждому аналитику. Именно так рождаются красивые графики, которых не должно быть
в отчёте, и фичи, которые запускают по ложноположительным результатам.
Как выглядит ошибка
Сценарий:
Запускаем A/B-тест, главная метрика — конверсия в покупку (CR).
Через 21 день получаем p = 0.12 — незначимо.
PM спрашивает: «А что по другим метрикам?» — и аналитик смотрит ещё 19 показателей:
глубину, время до первой активности, ARPU, скроллинг и т.д.
Находит метрику «time to first action» с p = 0.04 и выносит её в слайды.
Формально p = 0.04 < 0.05, значит «статистически значимо». Но на самом деле мы сделали 20 независимых
проверок и выбрали минимальный p-value.
Почему это проблема
P(\text{хотя бы один ложноположительный}) =
1 - (1 - \alpha)^m
При m = 15 и α = 0.05:
1 - 0.95^{15} \approx 54\%
То есть вероятность найти хотя бы одну «значимую» метрику при отсутствии эффекта
больше половины. Это уже не наука, а p-hacking.
Что делать правильно
Фиксировать primary metric до запуска. В описании эксперимента явно укажите,
какая метрика является основной, и именно по ней принимайте решение.
Вторичные метрики разрешены, но:
их список должен быть зафиксирован до старта;
для них применяйте исправление на множественные сравнения:
Bonferroni, Holm, Benjamini–Hochberg (BH) и т.д.
Exploratory анализ можно делать, но его выводы должны быть явно помечены
как гипотезы для будущих тестов, а не как готовые решения.
Опасный сигнал: если в отчёте нет ни слова про предварительный план анализа,
а есть только одна «нашедшаяся» метрика с p ≈ 0.04, скорее всего вы видите результат p-hacking.
4. Multiple testing, peeking и ранняя остановка
В реальных продуктах редко удаётся «закрыть глаза на 21 день и посмотреть один раз».
PM-ам хочется знать результаты каждый день, и аналитики начинают смотреть на p-value
после каждого обновления данных. Это называется optional stopping и
приводит к тем же проблемам, что и множественные тесты.
Как выглядит ошибка
План: эксперимент на 21 день. Факты:
С первого дня аналитик строит CR и p-value по кумулятивным данным.
Формально p < 0.05, но было сделано 7 независимых «просмотров» (а часто и больше, если счёт ежедневно).
Эффективный α становится гораздо выше 5% — исследования показывают, что при ежедневном peeking
он может вырасти до 15–20%.
Опасный симптом: тест запланирован
на 21 день, но остановлен на 7-й потому что «уже
видно значимый эффект». Без пре-зарегистрированной
sequential-методологии (Pocock, alpha-spending,
Bayesian) — это ранняя остановка, false positive
rate в 2–3 раза выше заявленного α.
Почему это проблема
Каждый дополнительный просмотр — это ещё один тест гипотезы H0: effect = 0.
«p = 0.03 на 7-й день» не равно «значимо на уровне 5%»,
если вы не учли факт множественных проверок во времени.
Вероятность ложноположительного результата накапливается
по мере того, как вы ждёте «пока p станет красивым».
Что делать правильно
Фиксированный горизонт. Самый простой вариант — заранее выбрать длительность теста
и честно смотреть на данные один раз в конце. Любые промежуточные графики — только для мониторинга
аномалий, а не для принятия решений.
Sequential testing. Если хотите иметь право останавливаться раньше, используйте
последовательные методы:
классические схемы (O'Brien–Fleming, Pocock);
always-valid p-values и методы типа SPRT;
bayesian подходы с контролем FDR.
Жёсткое правило: если вы не спроектировали sequential-дизайн заранее,
не останавливайте тест раньше, даже если p временно стало < 0.05.
5. Sample Ratio Mismatch (SRM)
SRM — это ситуация, когда фактическое распределение трафика по группам A/B
существенно отличается от ожидаемого. Это ранний сигнал, что в эксперименте
что-то фундаментально сломано.
Как выглядит ошибка
Вы планируете сплит 50/50. Через несколько дней выгружаете данные:
Ожидалось: 500 000 / 500 000 пользователей.
Фактически: 503 000 в тесте и 497 000 в контроле.
Аналитик считает χ²-тест на пропорции и получает p = 0.001 — то есть отклонение
от 50/50 статистически значимо. Но говорит: «Ну, это же всего 0.3 процентного пункта,
давайте считать, что всё ок» — и продолжает анализ.
Почему это проблема
SRM почти всегда означает систематическую проблему:
некорректное кеширование, фильтрация ботов только в одной группе, баг в маршрутизации.
Если разные типы пользователей с разной вероятностью попадают в тест и контроль,
то оценка эффекта смещена — мы сравниваем неэквивалентные группы.
Чем больше выборка, тем легче обнаружить SRM — «маленькие» отклонения по процентам
могут быть статистически огромными.
Что делать правильно
Правило: прежде чем смотреть на метрики, всегда проверяйте SRM
по числу пользователей (или рандомизационных единиц) в группах.
Считайте χ²-тест на соответствие ожидаемому сплиту (50/50, 33/33/33 и т.п.).
При обнаружении SRM:
остановите интерпретацию результатов — нельзя доверять эффектам;
разоберите причины: кеширование, redirect, фильтры, баги в bucketing-системе;
после исправления проведите новый эксперимент.
Нельзя: «ну это всего 0.3%, давайте закроем глаза». SRM — это не про величину смещения,
а про факт, что рандомизация ведёт себя не так, как должна.
6. Interference / spillover / network effects — отметка на карте
Когда treatment одних пользователей влияет на outcome
других (двусторонние рынки, социальные сети, share
resources) — SUTVA нарушено, эффект смещён. Случается
часто на маркетплейсах (рандомизация покупателей
меняет аукцион для продавцов), в соцсетях (контрольная
группа видит контент тритмент-группы), при общих
ресурсах (один общий бюджет).
Опасный симптом: рандомизация пользователей при том
что продукт по природе двусторонний или сетевой —
почти всегда interference есть, вопрос только в её
масштабе.
Что делать: cluster-randomized дизайн (рандомизация
на уровне города, региона, времени), switchback-
тесты для ride-hailing-подобных платформ. Детали —
Модуль 6: Кластерные
эксперименты.
Большинство пропорций и rate-метрик имеют вид «события / экспозиция» — CTR, CR, RPM, retention.
Ключевая ошибка — когда treatment изменяет не только числитель (clicks), но и знаменатель (impressions),
а аналитик продолжает интерпретировать результат как «чистый» эффект на отношение.
Как выглядит ошибка
Тестируется новый алгоритм таргетинга рекламы:
В тесте на 30% больше показов на пользователя (алгоритм находит больше инвентаря).
Общее число кликов тоже растёт, но не пропорционально показам.
CTR = clicks / impressions падает с 2.1% до 1.8%.
PM смотрит только на CTR и говорит: «Алгоритм ухудшил эффективность, отменяем».
Почему это проблема
Знаменатель (impressions) теперь зависит от treatment,
поэтому CTR смешивает два эффекта: изменение стратегии показа и изменение отклика пользователей.
Может оказаться, что общее число кликов или revenue на пользователя выросло,
но CTR упал из-за роста низокачественных показов.
В таком случае говорить «фича ухудшила CTR, значит она плохая» — некорректно.
Что делать правильно
Проверять стабильность знаменателя между группами: impressions per user,
sessions per user, number of opportunities.
Если denominators существенно различаются:
перейти к per-user метрикам (клики на пользователя, выручка на пользователя,
время на пользователя);
использовать ITT-подход: считать эффект на всех рандомизированных пользователях,
включая тех, кто вовсе не получил экспозицию;
интерпретировать CTR/CR только как вспомогательные диагностические метрики.
Связь с симуляторами: в карте выбора статкритерия
можно задать метрику как ratio с treatment-affected denominator и посмотреть, какие тесты
рекомендуются, а какие приводят к смещению.