Sample Ratio Mismatch в A/B-тесте: как найти сломанное распределение

Что такое Sample Ratio Mismatch и как диагностировать SRM: chi-square проверка, единица рандомизации, логирование экспозиции, сегментация и причины перекоса.

Оглавление10 разделов

Sample Ratio Mismatch, или SRM, возникает, когда фактическая доля единиц в вариантах A/B-теста существенно расходится с запланированной. При split 50/50 небольшая случайная разница нормальна; систематически большой перекос указывает, что рандомизация, экспозиция или сбор данных работают не так, как предполагает анализ.

Главное правило

SRM проверяется до метрик эффекта. Если тест не доставил сопоставимые выборки, красивый uplift нельзя интерпретировать, пока причина перекоса не установлена.

Выберите единицу подсчёта

Если рандомизация идёт по user_id, SRM считают по уникальным user_id первой валидной экспозиции, а не по сессиям, кликам или событиям. Часто активные пользователи создают больше строк, и event-level count изображает перекос даже при корректном assignment.

Assignment и exposure — разные события

Assignment сообщает назначенный вариант. Exposure фиксирует, что пользователь действительно получил изменяемый опыт. Между ними может сломаться загрузка, eligibility или редирект. Храните оба события с experiment_id, variant_id, unit_id_hash, timestamp и allocation_version.

Минимальная схема экспозиции
CREATE TABLE experiment_exposures (
  experiment_id text NOT NULL,
  allocation_version text NOT NULL,
  unit_id_hash text NOT NULL,
  assigned_variant text NOT NULL,
  exposed_variant text NOT NULL,
  assigned_at timestamptz NOT NULL,
  exposed_at timestamptz NOT NULL,
  eligibility_version text NOT NULL,
  PRIMARY KEY (experiment_id, allocation_version, unit_id_hash)
);

Chi-square проверка

Для двух и более вариантов сравнивают observed count Oᵢ с expected count Eᵢ = total × planned share. Статистика χ² суммирует (Oᵢ−Eᵢ)²/Eᵢ. Полученный p-value сравнивают с заранее заданным порогом контроля качества, а не выбирают после просмотра результата.

Формула SRM
expected_i = total_units * planned_share_i
chi_square = sum((observed_i - expected_i)^2 / expected_i)
degrees_of_freedom = number_of_variants - 1

Малый p-value сигнализирует несовместимость с плановым split,
но не называет техническую причину.

SQL для входных чисел

Первая экспозиция каждой единицы
WITH first_exposure AS (
  SELECT DISTINCT ON (unit_id_hash)
         unit_id_hash, exposed_variant, exposed_at,
         allocation_version, eligibility_version
  FROM experiment_exposures
  WHERE experiment_id=:experiment_id
  ORDER BY unit_id_hash, exposed_at
)
SELECT exposed_variant,
       count(*) AS observed_units
FROM first_exposure
GROUP BY exposed_variant
ORDER BY exposed_variant;

Где искать причину

  • Нестабильный hash или salt меняет assignment между запросами
  • Один вариант загружается медленнее и теряет exposure
  • Eligibility применяется после assignment только в одной ветке
  • Логирующий скрипт отсутствует или блокируется в варианте
  • Bot/filter удаляет строки несимметрично
  • Пользователь попадает в варианты с разных устройств
  • Allocation изменён без новой версии
  • Join теряет один вариант из-за nullable ключа

Локализация по слоям

Сравните planned allocation → assignment log → server response → client exposure → first funnel event. Первый слой, где появляется перекос, ограничивает поиск. Затем сегментируйте по времени, browser, device, GEO, app version и источнику, но учитывайте множественные проверки: сегменты используются для диагностики, не для объявления эффекта.

Почасовой сигнал появления перекоса
SELECT date_trunc('hour', exposed_at) AS hour,
       exposed_variant,
       count(DISTINCT unit_id_hash) AS units
FROM experiment_exposures
WHERE experiment_id=:experiment_id
GROUP BY 1,2
ORDER BY hour, exposed_variant;

Почему reweighting обычно не спасает

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

Ложная тревога

При множестве параллельных экспериментов часть p-value случайно окажется малой. Порог и политика повторной проверки задаются централизованно. Однако не следует повышать порог постфактум ради сохранения удобного результата. Microsoft Research рассматривает SRM как симптом широкого класса проблем качества данных, а не как косметическую статистику.

Защита до запуска

  1. Закрепить unit и deterministic assignment.
  2. Версионировать allocation и eligibility.
  3. Протестировать одинаковое логирование вариантов.
  4. Запустить A/A или canary на малой доле.
  5. Проверять SRM автоматически на assignment и exposure.
  6. Остановить интерпретацию при сигнале.
  7. Хранить расследование и решение о перезапуске.
Не исправляйте split удалением лишних строк

Ручное усечение большей ветки делает размер одинаковым, но не восстанавливает случайность выборки и скрывает источник дефекта.

Источники и границы применимости

Microsoft Research: diagnosing Sample Ratio Mismatch

Вывод

SRM — ранний тест доверия к A/B-эксперименту. Правильная единица, отдельные assignment и exposure, chi-square контроль и послойная диагностика помогают найти механизм перекоса. Пока он не объяснён, uplift остаётся числом из несопоставимых выборок, а не доказательством эффекта.

Станьте партнёром и начните работать

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

СТАТЬ ПАРТНЁРОМ

Связанные материалы

Все статьи
Аналитика

Бюджет первого теста: как рассчитать сумму, которой хватит для решения

Как рассчитать бюджет теста рекламы через частоту события, MDE, power, стоимость трафика, зрелость, технический этап, лимит потерь и оборотный капитал.

Аналитика

Витрина данных для арбитражной команды: схема от клика до выплаты

Как построить аналитическую витрину арбитража: grain, факты, измерения, click ID, статусы, валюты, ревизии, late events, тесты и воспроизводимые отчёты.

Аналитика

Statistical power и MDE: как планировать тест конверсии до запуска

Подробный разбор statistical power, MDE и размера выборки для конверсии: baseline, alpha, beta, абсолютный эффект, кластеры, лаг и симуляция дизайна.