Sample Ratio Mismatch (SRM) в A/B-тестах
Содержание:
Что такое Sample Ratio Mismatch
Sample Ratio Mismatch (SRM) — несоответствие реального распределения юзеров запланированному.
Если запланировали 50/50, а получилось 47/53 — это SRM. Даже если разница кажется небольшой, на больших выборках это статистически значимое отклонение, которое означает: что-то в эксперименте сломано.
SRM — это guardrail-метрика, не просто метрика. Если SRM нарушен, эксперимент не интерпретируется. Никакие p-value на primary не имеют смысла, пока SRM не разрешён.
Почему SRM критично
Главная идея A/B — рандомизация юзеров между группами. Если группы изначально не равны (даже на 1-2%), различия в primary могут быть следствием bias, а не treatment.
Пример: запланировали 50/50, получили 49/51. Treatment-группа на 2% больше. Если в треатменте больше «продвинутых» юзеров (которые случайно попали в большую группу) — primary в треатменте выше, но не из-за фичи.
В реальности на больших экспериментах (10M+ юзеров) даже 0.5% SRM — это сигнал bug-а в рандомизации, потому что random случайно даёт такое отклонение крайне редко.
Как обнаружить
Chi-square test на ожидаемое vs реальное распределение:
Expected: 50% T, 50% C → 5M T, 5M C
Observed: 4.97M T, 5.03M C
H0: реальное распределение = ожидаемому
H1: они различаются
chi^2 = sum((observed - expected)^2 / expected)Если p-value < 0.001 (часто такой strict threshold) — SRM присутствует, эксперимент инвалиден.
В большинстве A/B-платформ (включая внутренние в Yandex, Avito, Ozon) — SRM check автоматический. Если есть SRM, эксперимент помечается и не пускается в decision-making.
Threshold: обычно p < 0.001 (не 0.05), потому что random случайно даёт значимые отклонения редко на больших выборках.
Главные причины SRM
1. Bug в распределении
Самая частая. Bug в коде, который должен случайно делить юзеров. Например:
hash(user_id) % 2 == 0— но distribution не равномерное из-за свойств hash- Юзеры с определённым свойством (admin, paid) проходят assignment-логику
- Cache не очищается между экспериментами
2. Потерянные события
В B попадает меньше юзеров, потому что:
- Клиент в B не получает корректную версию фичи и не логирует events
- Network issues бьют только определённую platform
- Bug в трекинге treatment-группы
3. Выживание юзеров
Если в треатменте есть push / email, который юзеры дольше открывают — больше юзеров «дожили» до триггера событий. Контрольная группа без push — меньше открытых, меньше events, кажется что меньше юзеров.
4. Несбалансированная аудитория
Если эксперимент запущен только для определённых юзеров (например, premium-сегмент), а они не равномерно распределены по device / browser / region — может появиться SRM.
5. Cookie deletion
В web-A/B юзер может удалить cookie и попасть в другую группу. Если в treatment больше юзеров «без cookie» — будет SRM.
Что делать при SRM
Шаг 1: Не интерпретировать результаты. Primary-метрика с SRM ничего не значит.
Шаг 2: Найти причину.
- Логи: где в pipeline сломалось assignment?
- Сегменты: SRM есть везде или только в каком-то сегменте (web vs mobile, RU vs EU)?
- Hash funcион: проверить, что random действительно random
Шаг 3: Исправить и перезапустить. Не пытайся фиксить уже идущий эксперимент. Переподними после фикса.
Шаг 4: Документация. В после-experiment review зафиксируй SRM как incident — что нашли, как исправили. Это part of test infrastructure quality.
Частые ошибки
- Игнорировать SRM, потому что разница «маленькая». На больших объёмах даже 0.5% — сигнал bug.
- Использовать p < 0.05 для SRM-теста. На больших выборках это too strict. Standard — p < 0.001.
- Фиксить SRM «постфактум» через reweighting. Это работает в observational studies, но не в A/B — bias может быть нелинейным.
- Не дифференцировать SRM по сегментам. Глобальный 49/51 может скрывать 40/60 на одном сегменте.
- Запускать тест на маленькой выборке. SRM на 1000 юзеров может быть случайным.
Связанные темы
- A/B-тестирование на собесе
- Размер выборки A/B
- Guardrail-метрики
- Switchback-эксперименты
- Peeking problem в A/B-тестах
FAQ
Какое допустимое отклонение?
Зависит от размера выборки. На 10M юзеров — даже 1% это много. На 1K юзеров — 3-4% может быть случайно. Использовать chi-square test с p < 0.001.
Можно ли продолжить эксперимент при SRM?
Нет. Лучше пожертвовать неделей и исправить, чем сделать неправильный вывод. Любые primary-метрики при SRM не интерпретируются.
Почему p < 0.001 а не 0.05 для SRM?
Если использовать p < 0.05, на больших выборках случайные отклонения будут давать «значимый» SRM в 5% случаев. На 10M юзеров это слишком много false positives.
SRM в Yandex / Avito / Ozon — реально проверяют?
Да. В платформах есть автоматический SRM check, и эксперименты с SRM не пускаются в decision-making.
Что делать, если SRM нашёлся в production эксперименте, который уже катился?
Roll back и анализ. Не интерпретировать результат. Если возможно — запустить снова после фикса.