Почему "запустим тест и посмотрим" — плохая идея

Это типичный диалог продакта и аналитика:

PM: Я хочу запустить A/B-тест нового onboarding. Аналитик: Сколько юзеров в каждой группе? PM: Ну, запустим, неделю посмотрим, чтобы хватило. Аналитик: глубокий вздох

Проблема: если выборка слишком маленькая — даже реальный эффект +5% ты не заметишь (high false negative). Если слишком большая — заметишь даже мизерные различия которые бизнесу неинтересны (over-power).

Идеальная выборка — минимальная такая, чтобы:

  • С вероятностью β (мощность, обычно 80%) поймать эффект MDE (минимальный интересный)
  • С вероятностью α (обычно 5%) НЕ дать ложное срабатывание

4 параметра

1. Базовая конверсия (p)

Текущая конверсия в основной метрике до теста. Например, paid signup = 5%.

2. MDE — Minimum Detectable Effect

Самый важный параметр. Какой минимальный размер эффекта тебе интересен?

«Я хочу поймать рост конверсии с 5% до 5.5%» → MDE = +0.5 п.п. (или +10% relative).

Чем меньше MDE тебе интересен — тем больше выборка нужна. Квадратичная зависимость!

MDE (relative)Выборка на группу
10%30 000
5%120 000
2%750 000
1%3 000 000

Урок: никогда не пытайся ловить эффекты < 2% на одной кампании. Слишком дорого по сэмплу.

3. α — Significance level

Уровень значимости. Стандарт = 0.05 = 5% шанс false positive.

Можно ужесточить до 0.01 (1%) для высокорискованных решений (миграция архитектуры).

4. β — Statistical power (мощность)

Способность теста реально поймать эффект, если он есть. Стандарт = 80%.

Если выборку нельзя увеличить — оставь power 70% (всё ещё прилично, не fail-pass).

Формула для биномиальной метрики

Конверсия (paid signup, click rate) — биномиальная (0/1). Для неё:

$$n_{per_group} = \frac{(z_{\alpha/2} + z_\beta)^2 \cdot \left[p_1(1-p_1) + p_2(1-p_2)\right]}{(p_1 - p_2)^2}$$

Где:

  • p1 — базовая конверсия
  • p2 = p1 × (1 + MDE) — конверсия которую хотим обнаружить
  • z_α/2 ≈ 1.96 для α=0.05
  • z_β ≈ 0.84 для β=0.80

Пример

Базовая конверсия 5%, MDE = 10% relative (хотим увидеть рост до 5.5%):

  • p1 = 0.05, p2 = 0.055
  • z_0.025 = 1.96, z_0.20 = 0.84
  • (1.96 + 0.84)^2 = 7.84
  • 0.05 × 0.95 + 0.055 × 0.945 = 0.0475 + 0.052 = 0.0995
  • (0.055 - 0.05)^2 = 0.0000025
  • n = 7.84 × 0.0995 / 0.0000025 ≈ 312 000

Каждой группе нужно ~312k юзеров. На 50/50 трафик и 100 уников/день — это 17 лет теста. 😬

Вывод: MDE = 10% при базовой конверсии 5% — мало кто потянет. Реально продакты тестируют MDE 20–30% (искать большие эффекты) или работают над увеличением conversion базы.

Continuous метрики (revenue, time, count)

Для метрик типа AOV (средний чек), time on site — формула другая:

$$n = \frac{2 \sigma^2 (z_{\alpha/2} + z_\beta)^2}{\Delta^2}$$

Где σ — стандартное отклонение метрики, Δ — абсолютная разница которую хотим поймать.

Главная сложность: надо знать σ. Берётся из исторических данных. Если метрика очень разбросана (как revenue с длинным правым хвостом) — выборка может быть огромной.

Калькуляторы которые имеют смысл

  • Evan Millerhttps://www.evanmiller.org/ab-testing/sample-size.html — золотой стандарт. Для биномиальных и continuous.
  • Optimizely — встроен в их платформу, считает с учётом ваших исторических данных.
  • Statsig — у них есть открытый калькулятор + хорошие документации.

Чек-лист перед запуском теста

  1. ✅ Зафиксирована основная метрика (один primary KPI, не 10)
  2. ✅ Посчитан MDE который имеет бизнес-смысл (а не "посмотрим что найдём")
  3. ✅ Посчитан sample size заранее
  4. ✅ Известна длительность теста (n / daily_traffic)
  5. ✅ Не peeking — смотрим p-value только когда выборка достигнута
  6. ✅ Готов план на случай "тест не достоверен" (не катаем)

Sequential testing — спасение от long tests

Если базовая конверсия низкая (1–2%), классический фикс-sample тест может идти 3+ месяцев. Решение — sequential testing (mSPRT, Always-Valid p-values, Bayesian).

Эти методы позволяют смотреть на результаты в любой момент и принимать решение «остановить рано» если эффект очевиден, без накопления false positive rate.

Минусы: сложнее в реализации, требуют поддержки в платформе (нужны библиотеки типа statsmodels, pyAB, или Optimizely SaaS).

TL;DR

  • Не запускай тест "на глаз" — посчитай sample size заранее
  • 4 параметра: базовая конверсия, MDE, α=0.05, β=0.80
  • Биномиальная: ~8 × p(1-p) / MDE^2 за группу
  • MDE 10% от низкой базы (1–2%) = огромный sample. Целься в 20%+ MDE или ищи большие изменения
  • Evan Miller / Optimizely калькуляторы — твои друзья