Сколько юзеров нужно в A/B-тесте чтобы поймать эффект? Этот вопрос на собесе аналитика — гарантированный. Без правильного sample size тест либо слишком короткий (не увидим эффект, ложный негатив), либо слишком длинный (тратим время и юзеров впустую).
Ниже — калькулятор. Он считает по стандартной формуле для двух пропорций и для непрерывных метрик. Меняй параметры и сразу видишь сколько юзеров нужно.
Что вообще такое sample size
Это минимальное количество пользователей в каждой группе (контроль и тест), при котором ты сможешь:
- Увидеть реальный эффект если он есть (вероятность = power, обычно 80%)
- Не ошибиться ложным выводом если эффекта нет (вероятность ошибки = alpha, обычно 5%)
Если возьмёшь меньше — пропустишь эффект (false negative). Возьмёшь больше — переплатишь временем и трафиком.
Параметры калькулятора — что они значат
Baseline conversion (для пропорций)
Текущая конверсия твоей метрики. Например, CR покупки = 10% значит из 100 зашедших покупают 10.
Где взять: посчитай по своим данным за последние 4 недели. Стабильное среднее — твой baseline.
MDE — Minimum Detectable Effect
Минимальный эффект, который тебе важно увидеть. Если CR baseline = 10%, и MDE = 2 п.п. — значит ты хочешь увидеть улучшение до 12%. Меньше — тебе уже неинтересно.
Правило: меньше MDE → больше нужно юзеров. Чтобы увидеть +0.5% — нужны сотни тысяч пользователей. Чтобы +5% — десятки тысяч.
Как выбрать MDE: оцени business impact. «Если CR вырастет на 2 п.п. — это +X выручки в месяц. Это того стоит?». Если да — ставь MDE = 2 п.п.
Alpha (значимость)
Вероятность ошибки первого рода — ты сказал «эффект есть» когда его на самом деле нет.
Стандарт: 5%. Это значит «из 100 экспериментов где эффекта НЕТ — в 5 ты ошибочно скажешь что он есть».
Жёстче (1%) — для критичных решений (юридические, медицинские). Слабее (10%) — для гипотез на ранней стадии.
Power (мощность)
Вероятность увидеть реальный эффект если он есть. Стандарт 80% значит «из 100 экспериментов где эффект ЕСТЬ — в 80 ты его поймаешь, в 20 пропустишь».
Хочешь меньше пропусков (90% power) — нужно больше юзеров. Готов на 70% — нужно меньше.
Двусторонний vs односторонний
- Двусторонний (стандарт): «эффект есть, неважно в какую сторону». Используй всегда — на собесе если не уверен, выбирай этот.
- Односторонний: «эффект только в плюс» (или только в минус). Даёт меньший sample size, но ТОЛЬКО если ты уверен что эффект не может быть в обратную сторону.
Формула — для тех кому интересно
Для пропорций (бинарная метрика)
n = (z_{α/2}·√(2·p̄·(1-p̄)) + z_β·√(p₁(1-p₁) + p₂(1-p₂)))² / (p₂ - p₁)²
где:
p₁— baseline conversionp₂= p₁ + MDE — ожидаемая конверсия в тестеp̄= (p₁ + p₂) / 2 — средняяz_{α/2}— критическое значение нормального распределения для alpha (для 5% двустороннего = 1.96)z_β— критическое значение для power (для 80% = 0.8416)
Для непрерывных (среднее)
n = 2 · (z_{α/2} + z_β)² · σ² / Δ²
где σ — стандартное отклонение метрики, Δ — минимальная разница средних которую хотим увидеть.
В Python это делает statsmodels.stats.power.NormalIndPower().solve_power(...). Реализация в этом калькуляторе совпадает с ней до округления.
Типичные ошибки джунов
Использовать sample size «по ощущению»
«Раскатим на 1000 юзеров» — слишком абстрактно. Если baseline 5% и MDE 1 п.п. — нужно ~13 тысяч на группу. На 1000 ты ничего не увидишь — кроме шума.
Запускать тест без расчёта вообще
Получишь p-value, увидишь 0.07, скажешь «не значимо» и закроешь. Хотя на самом деле sample size был просто маленький — мощности не хватило.
«Подсматривать» — peeking
Запустил тест, через 3 дня посмотрел: «p=0.04, ура, статзначимо!». Закрыл тест.
Это баг. Если ты считаешь p-value несколько раз во время теста — фактический alpha растёт в разы. Ты получишь ложно-положительный результат намного чаще чем 5%.
Правило: считаем sample size заранее, ждём пока наберём → ТОЛЬКО потом смотрим.
Игнорировать sequential testing
Если очень нужно подсматривать — есть sequential testing (alpha spending functions, mSPRT). Они корректно учитывают «подглядывания». Но сложнее в реализации — для джуна обычно достаточно «жди пока соберём».
Использовать t-test для пропорций
t-test предполагает нормально распределённые данные. Конверсия (0/1) — биномиальная. Используй chi-square или z-test для пропорций — они корректны для бинарных метрик.
Не учитывать множественность тестов
Запускаешь 10 экспериментов с alpha = 5%. Ожидаемое число ложно-значимых = 10 × 0.05 = 0.5. Каждый второй «значимый» эксперимент в среднем — шум.
Лечение: Bonferroni (alpha делим на N тестов) или Benjamini-Hochberg (FDR control).
Когда стандартного калькулятора недостаточно
Это базовый калькулятор. В реальности бывают сложнее ситуации:
Ratio metrics
Метрики типа revenue / users или clicks / impressions. Распределение НЕ нормальное (heavy tails, ratio of two random variables). Используй delta method или bootstrap.
Cluster randomization
Когда юзеры в группах не независимы (один автор пишет много постов, юзеры из одной семьи смотрят один Netflix). Эффективный sample size меньше из-за intra-cluster correlation.
CUPED — variance reduction
Если у тебя есть pre-experiment data — можешь снизить variance метрики на 30-50%. Это значит меньше нужно юзеров при том же MDE. Подробнее в статье на Habr.
Stratification
Разбиение тест/контроль по сегментам (страна, тип девайса). Снижает variance, ускоряет тест.
Чек-лист перед запуском A/B-теста
- [ ] Посчитал sample size до запуска
- [ ] Выбрал alpha = 5%, power = 80%, тест двусторонний (если нет причин для другого)
- [ ] Знаю главную метрику — одна, не пять (иначе нужен Bonferroni)
- [ ] Запланировал длительность = sample_size / daily_traffic + 1 цикл бизнеса (день недели важен)
- [ ] Делаю A/A-test перед A/B чтобы убедиться что система рандомизации работает
- [ ] Запретил себе «подсматривать» — буду смотреть только когда соберу sample size
- [ ] Знаю как буду интерпретировать каждый из исходов (significant + / significant − / not significant)
Связанные материалы
- A/B-тесты в Python (scipy.stats) — практика на коде
- Конспект: A/B-тестирование на Python — теория с задачами
- Конспект: NumPy для аналитика — основа scipy.stats
- Когортный анализ retention в SQL — другой важный продуктовый анализ
Используй калькулятор выше каждый раз перед запуском теста. Это обязательная процедура, как пристёгивание ремня в машине.