Три ошибки в планировании A/B-теста, которые убивают результат до запуска
Команда планирует A/B-тест нового checkout-флоу. Аналитик открывает калькулятор sample size — нужно 90 000 пользователей на группу. Делят 50/50, запускают тест на 2 недели. Через неделю PM спрашивает «как там результаты», аналитик показывает: разница между группами +1.2%, p = 0.08. PM говорит «давайте подождём ещё неделю». Через вторую неделю — +0.9%, p = 0.04. Раскатывают. Через 3 месяца после раскатки метрики не показывают эффекта от нового флоу. Кто-то открывает старый A/B-отчёт и спрашивает «а почему мы остановились на p = 0.04 после двух недель наблюдения, если изначально планировали 4?»
Эта статья — про три ошибки на этапе планирования теста, которые убивают результат до того как тест запущен. Аналитик в момент проектирования может сломать тест так, что никакой сложный анализ потом не починит. Все три ошибки выглядят как «технические нюансы», но каждая из них систематически отправляет команды принимать решения по данным которые не значат то что кажется.
Угроза 1: Power analysis без variance reduction
Стандартный sample size: N = 16·σ²/Δ² (грубая формула для метрик-долей и 80% мощность, 5% уровень значимости). σ² — дисперсия метрики на пользователе, Δ — minimum detectable effect. Аналитик берёт σ² из исторических данных, подставляет желаемое Δ, получает N, делит на дневной трафик — получает длительность теста.
Что пропущено: σ² не фиксированная величина. Её можно снизить без изменения самой метрики, через техники variance reduction. Самые распространённые:
CUPED — корректировка outcome с использованием pre-period данных. Если у пользователя есть метрика за период до эксперимента (revenue, sessions, conversion), и эта pre-метрика коррелирует с post-метрикой (что почти всегда так) — вычисляется adjusted outcome, который снимает базовую дисперсию. Эффект: σ² падает на 30-50% для типичных продуктовых метрик.
Стратификация — разбиение пользователей на страты по pre-период признакам (категория покупателя, частота заходов, geo) и рандомизация внутри каждой страты. Эффект: убирает variance между стратами.
Trimming / winsorization для метрик с long tail — обрезка top 1% значений. Для revenue per user с heavy tail может снизить σ² на 50-70%.
Численно: N линейно пропорционально σ². Если CUPED режет σ² на 40%, sample size падает на 40%. Тест который требовал 6 недель, требует 3.5. Разница для команды — месяц трафика который мог пойти на следующий тест.
Команды которые пропускают шаг variance reduction — запускают тесты в 1.5-2 раза длиннее чем нужно. За год это 4-6 «потерянных» тестов которые не были запущены, потому что текущий ещё идёт.
Решение — variance reduction всегда включён в чеклист планирования. До расчёта sample size: (1) посмотреть какие pre-период данные есть; (2) посмотреть корреляции pre/post для целевой метрики; (3) если корреляция > 0.3 — включать CUPED; (4) если метрика с long tail — обсудить winsorization. Для подсчёта реальной σ² с учётом variance reduction — small calibration на исторических данных, не default σ² из стандартного отчёта.
Угроза 2: MDE взят с потолка
Второй вопрос планирования: какой размер эффекта мы хотим обнаружить? Стандартный ответ — «1% lift» или «5% lift». Откуда эти числа? Чаще всего — круглое число, привычка, «у нас обычно так». Это значит MDE подобран под удобный sample size, а не под бизнес-impact изменения.
Это переворачивает логику A/B-тестирования с ног на голову. В правильной модели MDE — это минимальный эффект который имеет смысл раскатывать: ниже него выигрыш не окупает издержки (operational, attention, regression risk). Команда должна знать до теста: «если эффект 0.5% — не раскатываем (выгода не оправдывает издержки), 1% — раскатываем». MDE = 1% тогда обоснован.
В реальности это считается так: бизнес-impact = размер эффекта × метрика × масштаб. Например: +1% conversion при annual revenue 100M USD — это +1M USD. Издержки запуска: нагрузка на поддержку, сопровождение, альтернативные издержки — допустим 200K USD. Точка окупаемости: 0.2% эффекта. MDE должен быть выше точки окупаемости с запасом прочности — например, MDE = 0.5%.
Когда команда берёт «1% effect для красоты», получается один из двух типичных сценариев:
(а) MDE слишком оптимистичный (1% при реальном effect 0.4%). Тест не достигает значимости, команда говорит «фича не работает», откатывает. Истина — фича работала, но эффект ниже MDE.
(б) MDE слишком пессимистичный (1% при реальном effect 3%). Тест достигает значимости очень быстро, можно было запустить на меньшей выборке. Не катастрофа, но потеря эффективности.
Решение — обосновать MDE через бизнес-impact до расчёта sample size, не после. Шаги: (1) посчитать impact at scale для разных effect sizes (0.5%, 1%, 2%); (2) посчитать издержки запуска изменения; (3) найти точку окупаемости; (4) MDE = точка окупаемости × запас (1.5-2x). Если получившийся MDE требует нереалистичный sample size — это сигнал что фича не должна тестироваться вообще на текущем масштабе.
Угроза 3: Stop-rule не зафиксирован до запуска
Третья ошибка — самая частая и самая разрушительная для validity теста. Команда запустила A/B на 6 недель, через 2 недели p-value стало 0.04, кто-то предлагает «давайте раскатывать, не ждать». Или: через 4 недели p = 0.07, «давайте подождём ещё». Или: на 3-й неделе разница 5%, на 5-й неделе разница 2%, «может откатить?»
Все три — варианты peeking (заглядывания в данные с адаптивным решением). Если решение про продолжение/остановку теста принимается на основе промежуточных p-values без коррекции, доля ложноположительных взлетает. Стандартный 5% превращается в 20-25% при еженедельном peeking на 6-недельном тесте. Это значит каждый четвёртый-пятый «значимый» результат — статистический шум.
Команды часто оправдывают peeking аргументами «но мы же видим что разница большая» или «но это ускоряет принятие решений». Это не работает: «большая разница» при peeking — это ровно тот случай когда вы видите случайный pattern, зафиксированный на промежуточной точке, который выровняется при полном sample size.
Решение — stop-rule фиксируется в design document до запуска теста. Три варианта:
(а) Тест с фиксированным горизонтом: тест длится ровно N дней, анализ только в конце. Самый простой. Минус — нельзя остановить раньше при сильном эффекте.
(б) Sequential testing с заранее зафиксированным правилом остановки (pre-registered): проверки на промежуточных точках с скорректированными α (например O'Brien-Fleming или mSPRT bounds). Сложнее имплементировать, но позволяет легитимно остановить раньше при сильном эффекте без раздувания FPR.
(в) Групповой последовательный с одной промежуточной проверкой (например на 50% sample): одна промежуточная проверка с скорректированным α (типично 0.005 вместо 0.025). Компромисс между простотой и flexibility.
Что не работает: «посмотрим как пойдёт» — без формального stop-rule, с решением принимаемым ad-hoc. Это peeking.
Дополнительный сигнал: если команда обсуждает «может остановить раньше / продолжить дольше» во время теста — это значит stop-rule не был зафиксирован. Тест уже инвалидирован этой дискуссией, даже если решение в итоге будет «дождаться».
Что общего у этих трёх
Три ошибки выглядят разными — variance reduction, калибровка MDE, дисциплина stop-rule. Но у них один тип проблемы: тест убивается на этапе планирования, не анализа.
В каждом случае команда фокусируется на красивой стороне работы — запуск, наблюдение, анализ, интерпретация — и пропускает скучную: дизайн до старта. Variance reduction кажется «технической оптимизацией», MDE — «округлим до красивого числа», stop-rule — «договоримся по ходу». Все три ощущаются как детали, но каждая из них определяет валидность всего теста.
Это перекликается с темами предыдущих статей в этом разделе. В AI-evals: измеряемые числа были не теми что нужны в продакшене. В retention vs revenue: точечный revenue uplift был не той метрикой что определяет долгосрочный результат. Здесь: тест валидно отвечает на вопрос «какой эффект» только если дизайн теста обеспечивает валидность. Без мощности, без обоснованного MDE, без stop-rule — числа в финальном отчёте формально существуют, но не значат того что кажется.
Главное правило A/B-планирования: дизайн теста — это 40-60% его ценности, не «техническая прелюдия» к интересной части. Команда которая тратит 2 часа на полноценный design document экономит 6 недель на бессмысленный тест.
Чеклист для команды
Семь правил которые закрывают большую часть проблем на этапе планирования A/B:
- Variance reduction в чеклисте планирования. До расчёта sample size: посмотреть pre-период данные, оценить корреляции, включить CUPED при корреляции > 0.3.
- Калибровка σ² не из стандартного отчёта, а на репрезентативной исторической выборке с применёнными reduction техниками.
- MDE обоснован через бизнес-impact, не «1% круглое число». Расчёт: точка окупаемости × запас прочности.
- Sample size согласован с командой до запуска. Если итоговый N требует 12 недель — это часть планирования, не сюрприз через месяц после старта.
- Stop-rule фиксирован в design document. Один из трёх: с фиксированным горизонтом, sequential с заранее зафиксированными bounds (pre-registered), групповой последовательный с одной промежуточной проверкой. Не «посмотрим как пойдёт».
- Дисциплина peeking. Если в команде есть дискуссия «может остановить раньше / продолжить дольше» — это признак того что stop-rule не был зафиксирован. Тест на грани инвалидации.
- Post-mortem на каждый тест который дал «незначим». В 30-40% случаев настоящая причина — недостаточный sample size или плохо выбранный MDE, не отсутствие эффекта. Без анализа причины команда отбрасывает работающие фичи.
Это не academic точность. Это разница между «20 тестов в год, 3 правильных, 17 потерянных» и «12 тестов в год, 8 правильных, 4 потерянных». Меньше тестов, лучше дизайн, больше шиповых решений.