A/B-тест показанной функции: кто входит в анализ

Новая кнопка появляется только на странице оплаты. В тест назначили всех посетителей, но до этой страницы дошла лишь половина. Анализ всех назначенных покажет разбавленный эффект кнопки: для людей, которые её не видели, она ничего не могла изменить. Возникает соблазн оставить только тех, у кого в логе есть событие «увидел новую кнопку». Так выбирать нельзя: в контрольной группе самой новой кнопки нет, и условие получается разным для A и B.

Симметричный trigger должен описывать возможность увидеть изменение в обеих группах. Для кнопки это, например, запрос страницы оплаты до отрисовки варианта: у A и B это событие регистрируется одинаково. Тогда анализ достигших страницы отвечает на вопрос об эффекте для людей, которым функция могла быть показана. Анализ всех назначенных остаётся полезным для общей продуктовой популяции.

users = [
    ('A', True, 0), ('A', True, 1), ('A', False, 0), ('A', False, 0),
    ('B', True, 1), ('B', True, 1), ('B', False, 0), ('B', False, 0),
]
for group in ('A', 'B'):
    assigned = [paid for arm, eligible, paid in users if arm == group]
    triggered = [paid for arm, eligible, paid in users
                 if arm == group and eligible]
    print(group, 'assigned rate=', sum(assigned)/len(assigned),
          'triggered rate=', sum(triggered)/len(triggered))

В учебных данных четыре назначенных пользователя на группу, по два достигли страницы. Конверсия среди всех назначенных равна 25% у A и 50% у B; среди достигших страницы — 50% и 100%. Эти числа показывают разбавление при выборе более широкой популяции. Разница сама по себе не доказывает эффект: в настоящем тесте нужны размер выборки, интервал и проверка распределения.

Когда trigger создаёт смещение

Если изменение влияет на вероятность попасть на страницу оплаты, фильтр по фактическому посещению уже стоит после воздействия. Например, вариант B меняет навигацию к оплате; тогда среди дошедших до страницы в двух группах окажутся разные типы людей. Сравнение только этих людей может быть смещено. В таком тесте основным оставляют анализ всех назначенных либо ищут trigger, определяемый до влияния варианта.

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

Не смешивайте единицы счёта. Если рандомизация по пользователю, а посещений страницы несколько, в анализе должно оставаться одно наблюдение на пользователя с согласованным окном метрики. Иначе активные посетители получат больше веса, и сравнение перестанет отвечать на вопрос о среднем эффекте на человека.

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

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

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

В курсе «A/B тесты и анализ данных на Python» путь от выбора метрики и дизайна до интерпретации результата включает разбор искажений эксперимента. Вы практикуете расчёты в Python и SQL. Откройте программу, чтобы заранее определить аудиторию, на которую будет распространяться вывод.

После настройки trigger отдельно проверьте SRM в назначенных группах — ошибка распределения не исчезает от фильтрации событий.

Продолжить на практике

  • A/B тесты и анализ данных на Python ↗

    Практический курс по A/B-тестированию и продуктовым метрикам: формулируем гипотезы, считаем размер выборки, запускаем эксперименты и анализируем результаты. От первой идеи до внедрения изменений в продукт — без «воды» и лишней теории.