Как посчитать delta method в SQL

Закрепи формулу delta method в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать delta method в Telegram

Зачем delta method

Ratio-метрики (CTR = clicks/views, AOV = revenue/orders, sessions per user) — головная боль A/B. Стандартный t-test ломается: знаменатель тоже случайный, ему нельзя считать дисперсию как «сумма поделить на n». Delta method (он же linearization) даёт правильную формулу для variance ratio-метрики.

Идея линеаризации

Метрика R = X/Y. Если разложить вокруг среднего:

R ≈ μ_X/μ_Y + (1/μ_Y) × (X − μ_X) − (μ_X/μ_Y²) × (Y − μ_Y)

Это «линеаризованный» ratio: каждое наблюдение i даёт single число r_i. После этого работаете с r_i как с обычной метрикой (Welch's t-test и т.д.).

Формула для ratio

Для каждого user_id с числителем x_i и знаменателем y_i:

r_i_linearized = (x_i − μ_X × y_i / μ_Y) / μ_Y

Дисперсия = VAR(r_i_linearized) / n.

Delta method в SQL

CTR в A/B-тесте: numerator = clicks, denominator = views. По user_id:

WITH per_user AS (
    SELECT
        user_id,
        variant,
        SUM(CASE WHEN event = 'click' THEN 1 ELSE 0 END) AS clicks,
        SUM(CASE WHEN event = 'view'  THEN 1 ELSE 0 END) AS views
    FROM ab_events
    WHERE experiment_id = 'feed_v3'
    GROUP BY user_id, variant
),
group_means AS (
    SELECT
        variant,
        AVG(clicks) AS mean_x,
        AVG(views)  AS mean_y,
        COUNT(*) AS n
    FROM per_user
    GROUP BY variant
),
linearized AS (
    SELECT
        u.variant,
        (u.clicks - gm.mean_x * u.views / NULLIF(gm.mean_y, 0))
        / NULLIF(gm.mean_y, 0) AS r_i
    FROM per_user u
    JOIN group_means gm USING (variant)
)
SELECT
    variant,
    gm.mean_x / NULLIF(gm.mean_y, 0) AS ratio_point_estimate,
    VAR_SAMP(l.r_i) / NULLIF(gm.n, 0) AS variance_of_ratio,
    SQRT(VAR_SAMP(l.r_i) / NULLIF(gm.n, 0)) AS se_of_ratio
FROM linearized l
JOIN group_means gm USING (variant)
GROUP BY variant, gm.mean_x, gm.mean_y, gm.n;
Закрепи формулу delta method в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать delta method в Telegram

CI и t-statistic

Для разницы ratio между A и B используют стандартный Welch на r_i:

WITH a_stats AS (
    SELECT
        AVG(r_i) AS mean_r,
        VAR_SAMP(r_i) AS var_r,
        COUNT(*) AS n
    FROM linearized
    WHERE variant = 'A'
),
b_stats AS (
    SELECT
        AVG(r_i) AS mean_r,
        VAR_SAMP(r_i) AS var_r,
        COUNT(*) AS n
    FROM linearized
    WHERE variant = 'B'
)
SELECT
    b.mean_r - a.mean_r AS diff_ratio,
    (b.mean_r - a.mean_r)
    / NULLIF(SQRT(a.var_r / a.n + b.var_r / b.n), 0) AS t_statistic
FROM a_stats a, b_stats b;

r_i имеет mean = 0 в каждой группе (центрирован вокруг group mean), но diff между mean_r двух групп — это разница ratio. Можно работать без префикса «mean — общий ratio группы».

Частые ошибки

Ошибка 1. Считать CTR = SUM(clicks) / SUM(views) без дисперсии. Точечная оценка верна, но без variance тест невалиден. Delta method решает.

Ошибка 2. Считать AVG(clicks_per_view). Это другая метрика — micro-average по строкам. Сильно искажается, если у части юзеров нет views.

Ошибка 3. Линеаризация на event-level вместо user-level. Если знаменатель variates по юзерам — линеаризуем на уровне рандомизации (обычно user). Не на уровне session, если бакетируете по user.

Ошибка 4. Не учитывать что μ_Y оценивается из тех же данных. В строгой теории μ_X, μ_Y фиксированы. Использование выборочных средних — стандартная аппроксимация, но даёт оценку чуть смещённой при маленьких n.

Ошибка 5. Использовать μ_Y = 0. Деление на 0. Если у юзера нет views — он не имеет смысла для CTR, либо исключайте, либо корректируйте определение.

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

FAQ

Когда нужен delta method?

Метрика-отношение, рандомизация выше уровня события (CTR при per-user, ARPV при per-user, conversion per session при per-user).

Альтернатива?

Bootstrap: тоже даёт CI без формул, но дороже компьют.

Что если знаменатель = 0?

Исключают юзера или меняют определение (например, CTR определён только для тех, кто видел хотя бы 1 раз).

Delta method для трёх ratio?

Усложняется, но та же логика — линеаризация через градиент.

Совместим с CUPED?

Да: сначала линеаризуете, потом применяете CUPED к r_i как к обычной метрике.