сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · A/B-тесты

Дизайн A/B-теста

Зачем это спрашивают

A/B - рабочая лошадь продуктового DS, и на собесе почти всегда просят продизайнить тест целиком - гипотезу, метрики, сплит, сроки. Валят стабильно на двух вещах - юнит рандомизации и расхождение фактического сплита с плановым. Обе всплывают только у тех, кто запускал тесты руками, поэтому их и спрашивают.

Типовые формулировки: «продизайнь тест новой кнопки», «как посчитаешь длительность?», «сплит вышел 48 на 52, это нормально?».

// Каркас ответа выучи как стихотворение: гипотеза, метрики, юнит рандомизации, минимальный эффект, размер выборки, длительность. Он закрывает вопрос почти в любой формулировке, надо только подставить детали задачи.

Всё решается до запуска

Гипотеза формулируется так, чтобы её можно было опровергнуть числом: «новая кнопка поднимет конверсию в оплату минимум на 3 процента», а не «улучшит пользовательский опыт». Второе нельзя ни подтвердить, ни опровергнуть, значит тестировать нечего.

Метрик две категории. Целевая - одна, названа заранее. Guardrail - метрики-предохранители, которые нельзя уронить ради целевой: время ответа, жалобы, отписки, отток. Их не улучшают, за ними следят.

MDE (minimum detectable effect) - минимальный эффект, который тест обязан заметить. Берётся из бизнеса: какой прирост вообще окупает разработку, поддержку и риск. Из MDE считают размер выборки, а не наоборот. Подход «сколько у нас трафика, такой MDE и запишем» - это способ договориться с собой, а не расчёт.

// После старта ничего из перечисленного не меняется. Поменял целевую метрику на середине - результат стал нечитаемым: теперь никто не отличит, что было решено до данных, а что подобрано под них.

guardrail
метрика-ограничитель. Выиграть целевую и уронить guardrail считается проигрышем, а не разменом

Юнит рандомизации: что именно ты делишь

Юнит рандомизации - то, что раскидывается по группам: юзер, сессия, устройство, город, водитель. Юнит анализа - то, по чему считается метрика. Правило: юнит рандомизации не может быть мельче юнита анализа.

Почему это не формальность. Делим юзеров, а метрику считаем по сессиям - и статистика ломается. Сессии одного человека похожи между собой, значит наблюдения зависимы, значит настоящей информации в выборке меньше, чем строк. Формула же считает дисперсию по числу строк, занижает её, и p-value выходит красивее, чем заслужено. Тест «прокрашивается» на пустом месте.

Если метрика всё-таки сессионная, дисперсию считают иначе: бутстрэпом по юзерам (пересэмплируем людей целиком, вместе со всеми их сессиями) или дельта-методом, который умеет считать разброс для метрик-отношений.

// Механика сплита: берётся хеш от пары «идентификатор юзера плюс соль эксперимента». Хеш детерминирован, поэтому человек видит свой вариант при каждом заходе. Соль у каждого теста своя - иначе попавшие в группу A в одном эксперименте окажутся в A и в следующем, и параллельные тесты начнут просачиваться друг в друга.

соль
строка, подмешиваемая в хеш, чтобы одно и то же значение давало разный результат в разных экспериментах

A/A-тест и разъехавшийся сплит

A/A-тест: обе группы получают одно и то же. Прокраситься не должно ничего. Если прокрасилось - сломана инструментация, сплит или сама процедура анализа, и хорошо, что ты узнал об этом до решения на миллион, а не после.

SRM (sample ratio mismatch) - расхождение фактического соотношения групп с плановым. Планировали 50 на 50, получили 48 на 52. Выглядит мелочью, проверяется тестом хи-квадрат, и вот честные числа: на тысяче юзеров такой перекос легко объясняется случайностью, p около 0.21. На десяти тысячах уже нет, p около 0.00006. На ста тысячах вероятность случайно получить такое расхождение исчезающе мала.

Хи-квадрат тут делает простую вещь: сравнивает наблюдаемые количества с ожидаемыми и отвечает, насколько удивительно такое расхождение при честном сплите. Читается как обычный p-value.

// Живой SRM означает, что рандомизация или сбор данных сломаны: бот попал в одну группу, часть событий потерялась на одном из вариантов, редирект отвалился. Такой тест выбрасывается целиком - починить его анализом нельзя, потому что неизвестно, кто именно потерялся и чем он отличался от оставшихся.

Сколько держать тест

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

Второе - эффект новизны. Первые дни люди тыкают в новое просто потому, что оно новое; всплеск потом спадает. Решение принимают по стабилизировавшемуся хвосту, а не по пику первого дня.

Если срок выходит неприемлемым, честных рычагов ровно два: поднять MDE до реального бизнес-порога либо снизить дисперсию метрики - CUPED (controlled experiment using pre-experiment data), стратификация, более чувствительная метрика. Нечестный рычаг - ослабить уровень значимости или мощность; он ускоряет тест ровно настолько же, насколько делает вывод ненадёжным.

// Отдельная категория, требующая специальной обработки: метрики-отношения вроде CTR (click-through rate) и метрики с тяжёлым хвостом вроде выручки на пользователя. Обычная формула дисперсии для них не годится, нужен дельта-метод или бутстрэп.

Как отвечать: «Как посчитаешь длительность A/B-теста?»

Из четырёх входов. MDE - минимальный эффект, который окупает внедрение, его беру у продакта, а не из головы. Базовое значение метрики и её дисперсия - из исторических данных. Уровень значимости обычно 0.05, мощность 0.8. Отсюда получается размер выборки на группу; делю на дневной приток пользователей и получаю дни. Дальше два округления из практики: вверх до полных недель, потому что будни и выходные ведут себя по-разному, и запас на эффект новизны, чтобы решать по стабилизировавшемуся хвосту. Порядок величин полезно держать в голове: при базовой конверсии 5 процентов ловить относительный прирост в 10 процентов - это примерно тридцать тысяч человек на группу. И считать длительность задним числом, по факту прокраса, нельзя - это подгонка под желаемое.

Названы все входы формулы, оба округления и живой порядок величин. Последняя фраза закрывает встречный вопрос про раннюю остановку до того, как его успели задать.

На чём валят

  • Считать размер выборки после запуска, «по факту» - это подгонка, а не планирование.
  • Рандомизировать юзеров, а считать по сессиям как по независимым наблюдениям: p-value занижен, тест прокрашивается сам собой.
  • Одна соль хеша на все эксперименты - группы коррелируют между тестами, результаты перетекают.
  • Отмахнуться от сплита 48 на 52: на большом трафике это сломанная рандомизация, а не округление.
  • Менять целевую метрику по ходу теста и потом объяснять, почему так и было задумано.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 18, остальные разбираются в тренажёре.

  1. #ab_design1 / 5
    Что такое MDE (minimum detectable effect) в дизайне A/B-теста?
    A)Максимально возможный эффект, который тест способен зафиксировать при выборке
    B)Наименьший эффект, который тест надёжно поймает при данных n, α и мощности
    C)Минимальное число дней, которое обязан длиться эксперимент
    D)Минимально допустимый уровень значимости p-value для приёмки результата
    показать ответ и разбор
    +B)Наименьший эффект, который тест надёжно поймает при данных n, α и мощности

    // разбор: MDE — наименьший истинный эффект, который тест способен обнаружить с заданной мощностью при выбранных α и размере выборки. Он задаётся до старта из бизнес-соображений (какой аплифт вообще стоит ловить) и через power analysis определяет нужный размер выборки: меньше MDE — кратно больше n.

  2. #ab_design2 / 5
    Хотим ловить эффект вдвое меньше прежнего (MDE снизили в 2 раза) при той же значимости и мощности. Что с размером выборки?
    A)Размер выборки останется примерно прежним, ведь минимальный детектируемый эффект почти не влияет на его расчёт на практике
    B)Нужно примерно вчетверо больше: размер выборки растёт как 1/MDE², так что половинный эффект учетверяет выборку
    C)Достаточно увеличить выборку ровно вдвое, поскольку минимальный детектируемый эффект и объём выборки строго обратно пропорциональны
    D)Выборку, наоборот, можно уменьшить вдвое, потому что для меньшего эффекта по определению требуется меньше данных для обнаружения
    показать ответ и разбор
    +B)Нужно примерно вчетверо больше: размер выборки растёт как 1/MDE², так что половинный эффект учетверяет выборку

    // разбор: Размер выборки на группу при фиксированных α и мощности растёт обратно квадрату детектируемого эффекта: n ∝ σ²/MDE². Значит, чтобы поймать вдвое меньший эффект, нужно примерно в четыре раза больше наблюдений (и, соответственно, дольше тест). Отсюда практический вывод: гоняться за крошечными эффектами дорого — либо снижают дисперсию (CUPED, стратификация), либо принимают больший MDE.

  3. #ab_design3 / 5
    В A/B берут двусторонний критерий, хотя «мы же хотим только рост». Почему не односторонний?
    A)Односторонний критерий запрещён в статистике и не применяется на практике в экспериментах
    B)Двусторонний ловит и неожиданное падение метрики; односторонний удваивает риск проглядеть значимый вред от изменения
    C)Разницы между ними нет: односторонний и двусторонний тесты на данных дают идентичный p-value
    D)Односторонний критерий требует ровно вдвое большей выборки, чем двусторонний, поэтому его на практике и избегают из экономии
    показать ответ и разбор
    +B)Двусторонний ловит и неожиданное падение метрики; односторонний удваивает риск проглядеть значимый вред от изменения

    // разбор: Односторонний тест смотрит только в одну сторону (рост), и если изменение неожиданно НАВРЕДИЛО, он это упустит — а в проде важно поймать и вред (guardrail). Двусторонний контролирует ошибку в обе стороны и потому по умолчанию безопаснее для продуктовых решений. Односторонний даёт чуть больше мощности при меньшей выборке, но ценой слепоты к вреду и соблазна «подкрутить» гипотезу постфактум. Он не запрещён, но применяют его осознанно.

  4. #ab_design4 / 5
    A/B на выходных дал +5%, в будни эффект пропадает. Как избежать ложных выводов из-за времени?
    A)Просто останавливать тест в тот самый момент, когда p-value впервые опустился ниже 0.05, вообще не глядя на дни недели
    B)Запускать тест ровно на 3 дня — этого срока достаточно для продуктовой метрики и аудитории
    C)Гонять тест в будни, исключив выходные как аномальные и нерепрезентативные дни для оценки эффекта
    D)Прогонять тест целым числом недель, чтобы охватить недельную сезонность (будни/выходные) поровну в обеих группах
    показать ответ и разбор
    +D)Прогонять тест целым числом недель, чтобы охватить недельную сезонность (будни/выходные) поровну в обеих группах

    // разбор: Поведение пользователей сильно завязано на день недели (будни vs выходные) и события; тест на неполной неделе или с перекосом дней смешивает эффект изменения с недельной сезонностью. Поэтому эксперимент гоняют целым числом недель (обычно ≥1-2), чтобы обе группы одинаково захватили все дни. Ранняя остановка по первому «значимому» p-value ломает гарантии, фиксированные «3 дня» произвольны, а выкидывать выходные — терять часть аудитории.

  5. #ab_design5 / 5
    Тестируем сразу 5 вариантов против контроля и берём лучший значимый. Что с этим не так?
    A)Множественные сравнения: с ростом числа вариантов растёт шанс ложного «победителя» — нужна поправка (Bonferroni и др.)
    B)Ничего страшного: чем больше вариантов протестировать за один раз, тем в итоге надёжнее и точнее оказывается выбор лучшего из них
    C)Проблема лишь в том, что 5 вариантов требуют ровно в 5 раз МЕНЬШЕЙ выборки на каждый вариант, а не большей, как многие думают
    D)Не получится тестировать больше двух вариантов сразу — статистически корректные A/B/n-тесты попросту не выходят в природе
    показать ответ и разбор
    +A)Множественные сравнения: с ростом числа вариантов растёт шанс ложного «победителя» — нужна поправка (Bonferroni и др.)

    // разбор: Сравнивая 5 вариантов с контролем на уровне 0.05 каждый, вы делаете 5 проверок, и вероятность хотя бы одного ложноположительного заметно выше 5% — «лучший значимый» может выиграть случайно (множественные сравнения, как при подглядывании). Нужна поправка на множественность (Bonferroni, Holm, контроль FDR) или заранее большая выборка на вариант. A/B/n-тесты возможны, но выборки требуют больше, а не меньше.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.