Собесов

InterviewQuery Stats — почему у ratio-метрики «своя» дисперсия (delta method)

Статистика и теорверДисперсия ratio-метрикСложнаяSenior

Условие

В A/B-тесте мы хотим сравнить CTR = clicks / impressions. Если просто посчитать var(CTR) = sum_clicks / sum_impressions и применить обычную формулу для пропорций, получим неверный CI.

Почему? И что использовать вместо?

Решение

Почему обычная формула не работает

Формула SE(p) = sqrt(p(1-p)/n) работает для биномиальной случайной величины — где n это число независимых бернулли-испытаний. В A/B на user-уровне:

  • один user может иметь много impressions,
  • impressions внутри одного user коррелируют (один и тот же контекст),
  • единицы рандомизации — юзеры, не показы.

sum_clicks / sum_impressions — это ratio двух случайных величин, не одна биномиальная. Его дисперсия по простой формуле занижается → CI узкий → ложные positive.

Решение — delta method

Если X = sum_clicks per user, Y = sum_impressions per user:

CTR ≈ E[X] / E[Y] = X̄ / Ȳ

Дисперсия отношения через delta method (первый порядок Taylor):

Var(X̄/Ȳ) ≈ (1/Ȳ²) * Var(X̄) − 2 * (X̄/Ȳ³) * Cov(X̄, Ȳ) + (X̄²/Ȳ⁴) * Var(Ȳ)

Или эквивалентно через формулу для отношения:

Var(X̄/Ȳ) ≈ (X̄/Ȳ)² * (Var(X̄)/X̄² − 2*Cov(X̄,Ȳ)/(X̄*Ȳ) + Var(Ȳ)/Ȳ²) / n

На SQL уровне

WITH user_stats AS (
  SELECT user_id, variant,
         SUM(clicks) AS x,
         SUM(impressions) AS y
  FROM events
  GROUP BY user_id, variant
),
agg AS (
  SELECT variant,
         AVG(x) AS x_bar, AVG(y) AS y_bar,
         VAR_SAMP(x) AS vx, VAR_SAMP(y) AS vy,
         COVAR_SAMP(x, y) AS cxy,
         COUNT(*) AS n
  FROM user_stats GROUP BY variant
)
SELECT variant,
       x_bar / y_bar AS ctr,
       SQRT(
         (vx / (y_bar * y_bar)
          - 2 * x_bar * cxy / POWER(y_bar, 3)
          + x_bar * x_bar * vy / POWER(y_bar, 4)
         ) / n
       ) AS se_ctr
FROM agg;

Альтернатива — bootstrap

Если delta method кажется сложным или распределение скошено — bootstrap по юзерам:

  1. Семплируем юзеров с возвратом N раз.
  2. Считаем CTR на каждом семпле.
  3. Распределение CTR из бутстрапа → CI как 2.5–97.5 перцентили.

В A/B это сейчас стандарт у Meta / Booking — bootstrap дешевле, корректнее, не требует delta-математики.

Подводные камни

  1. «n» путаница. В формуле n — число юзеров, не impressions. Сильно влияет на величину SE.
  2. Cov(X, Y). Часто > 0 (юзер с многими impressions имеет и много clicks). Игнорируя её — переоцениваем variance.
  3. Длинный хвост. Если 1% пользователей дают 50% impressions — bootstrap намного устойчивее, чем delta-method-Wald.
  4. Tarpaulin shifting. Если меняется состав юзеров между группами (mix shift), даже корректная вариативность не спасёт от bias оценки.

Эталонный ответ

CTR в A/B — это ratio с корреляцией внутри юзера. Обычная биномиальная SE неверна (занижена). Использовать delta method для SE или bootstrap по юзерам для CI. Это caveat одного из самых частых сценариев в продуктовых A/B-тестах.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти