Sample Ratio Mismatch (SRM) в A/B-тестах

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

Что такое 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.

В web-A/B юзер может удалить cookie и попасть в другую группу. Если в treatment больше юзеров «без cookie» — будет SRM.

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

Что делать при 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 юзеров может быть случайным.

Связанные темы

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 и анализ. Не интерпретировать результат. Если возможно — запустить снова после фикса.