Как устроен A/B-тест: от гипотезы до решения

«Расскажите, как вы запустили бы A/B-тест новой кнопки» — вопрос, который проверяет не статистику, а дисциплину.

A/B-тест — это контролируемый эксперимент, в котором пользователей случайно делят на группы, показывают им разные версии продукта и сравнивают целевую метрику. Случайность деления — единственное, что превращает наблюдаемую разницу в вывод о причине.

Вопрос 1. Из чего состоит A/B-тест?

Что проверяет интервьюер. Назовёте ли вы шаги до запуска. Кандидат, который начинает с «делим пополам и смотрим конверсию», сразу выдаёт отсутствие практики: половина работы делается до того, как эксперимент включили.

  1. Гипотеза. Формулируется как «изменение X приведёт к изменению метрики Y на Z% у сегмента S, потому что …». Без «потому что» это не гипотеза, а догадка.
  2. Целевая метрика — одна. Плюс метрики-гардрейлы, которые не должны просесть, и диагностические метрики для объяснения результата.
  3. MDE (minimum detectable effect) — минимальный эффект, который бизнесу важно заметить. Задаётся до теста и определяет размер выборки.
  4. Размер выборки и длительность — считаются заранее, фиксируются письменно.
  5. Единица рандомизации — пользователь, сессия, устройство, город.
  6. Запуск и A/A-проверка — убедиться, что до изменения группы неразличимы.
  7. Анализ ровно в срок и решение: катим, откатываем, повторяем.

Вопрос 2. Что выбрать единицей рандомизации?

Ошибка здесь ломает эксперимент целиком, поэтому вопрос любят.

ЕдиницаКогда подходитРиск
Пользователь (user_id)стандарт: изменения интерфейса, ценынужен стабильный идентификатор между устройствами
Сессиятолько для изменений в рамках одного визитаодин человек увидит обе версии — опыт «скачет», метрики удержания невалидны
Устройство (cookie)анонимные пользователи, лендингиодин человек = несколько устройств → «протечка» между группами
Кластер (город, магазин, компания)когда есть сетевой эффект или общий контекстэффективный размер выборки — число кластеров, а не пользователей

Главное правило: единица рандомизации должна совпадать с единицей анализа. Если делите по пользователям, а считаете конверсию по сессиям, дисперсия окажется занижена и p-value — оптимистичным. Формально это называется нарушением независимости наблюдений.

Вопрос 3. Зачем нужен A/A-тест?

A/A — это тот же эксперимент, но обе группы получают одну и ту же версию. Разницы быть не должно, и именно поэтому он ценен: он проверяет инфраструктуру, а не продукт.

  • Работает ли сплитование: 50/50 ли реально делятся пользователи и стабильно ли назначение группы.
  • Нет ли SRM (sample ratio mismatch) — расхождения ожидаемой и фактической пропорции групп. Если ждали 50/50, а получили 50.8/49.2 на сотнях тысяч пользователей, это не случайность, а баг: часть трафика теряется, боты попадают в одну группу, редирект ломает сессии. Тест с SRM интерпретировать нельзя — его чинят и перезапускают.
  • Совпадают ли предэкспериментальные метрики: если группы уже до изменения различаются по среднему чеку, рандомизация сломана.

Проверка SRM делается критерием хи-квадрат, но на собеседовании достаточно показать логику: считаем, насколько маловероятно получить такое расхождение при честном делении.

import math

def srm_check(n_a, n_b, expected=0.5):
    n = n_a + n_b
    exp_a, exp_b = n * expected, n * (1 - expected)
    chi2 = (n_a - exp_a) ** 2 / exp_a + (n_b - exp_b) ** 2 / exp_b
    z = math.sqrt(chi2)
    p = 2 * (1 - 0.5 * (1 + math.erf(z / math.sqrt(2))))
    return round(chi2, 2), round(p, 5)

print("50 100 / 49 900:", srm_check(50100, 49900))
print("50 800 / 49 200:", srm_check(50800, 49200))

Вывод:

50 100 / 49 900: (0.4, 0.52709)
50 800 / 49 200: (25.6, 0.0)

Первое расхождение объясняется случайностью, второе — нет: p-value фактически ноль, значит в сплитовании баг. Разница между группами при этом составляет меньше процента — на глаз её не заметить, и в этом ценность формальной проверки.

Вопрос 4. Сколько держать тест?

Минимум — полные недельные циклы. Поведение в понедельник и в субботу разное, и тест длиной в четыре дня измерит не эффект, а день недели. Останавливать тест раньше запланированного срока нельзя (об этом — отдельный урок про подглядывание), а тянуть его месяцами тоже плохо: накапливаются посторонние изменения продукта, сезонность и эффект новизны.

Эффект новизны — отдельная ловушка: первые дни пользователи реагируют на сам факт изменения, а не на его пользу. Поэтому у долгоживущих фич смотрят динамику эффекта по неделям, а не только итоговую цифру.

Типичные ошибки кандидатов

  • Начинают с «поделим трафик пополам», пропуская гипотезу, метрику и расчёт выборки.
  • Называют пять целевых метрик — тогда какая-нибудь «выстрелит» случайно.
  • Рандомизируют по сессиям при тесте, влияющем на возвращаемость.
  • Не знают про SRM и не проверяют размеры групп перед анализом.
  • Останавливают тест через три дня «потому что уже видно».

Как ответить кратко

«Начинаю с гипотезы вида "изменение приведёт к росту метрики на столько-то, потому что…". Выбираю одну целевую метрику и набор гардрейлов, задаю MDE и по нему считаю нужный размер выборки и длительность — обязательно кратно неделям. Рандомизирую по пользователю, а не по сессии, и слежу, чтобы единица рандомизации совпадала с единицей анализа. Перед анализом проверяю SRM: если фактическое деление отличается от 50/50 сильнее, чем допускает случайность, в сплитовании баг и тест надо перезапускать. Останавливаю ровно в запланированный срок и смотрю не только целевую метрику, но и гардрейлы».

Проверьте себя
1. Почему нельзя рандомизировать по сессии тест, который влияет на возвращаемость пользователей?
AСессии сложнее считать технически
BОдин и тот же человек попадёт в обе версии, опыт будет непоследовательным, а метрики удержания — невалидными
CПо сессиям невозможно посчитать конверсию
DРандомизация по сессии всегда даёт SRM
2. В тесте ожидалось деление 50/50, а фактически группы получились 50 800 и 49 200. О чём это говорит?
AЭто нормальная случайная флуктуация — расхождение меньше 1%
BЭто SRM: такое расхождение практически невозможно при честном делении, значит в сплитовании баг и тест надо чинить и перезапускать
CНужно просто взвесить группы при анализе
DЭто признак того, что тестируемая версия работает
3. Зачем A/B-тест держат целое число недель?
AТак требуют статистические формулы
BЧтобы охватить полные недельные циклы поведения — иначе измеряется день недели, а не эффект
CЧтобы успел сработать эффект новизны
DЧтобы набрать ровно расчётный размер выборки