CUPED простыми словами
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Зачем это знать
CUPED — один из самых мощных инструментов в современных A/B-тестах. Microsoft, Netflix, Booking используют. Снижает variance на 30-70% → нужно в 2-3 раза меньше выборки для того же effect detection.
На middle+ собесах в FAANG спрашивают CUPED. Без знания — минус очки.
Короткое объяснение
CUPED (Controlled-experiment Using Pre-Experiment Data) использует pre-experiment behavior юзеров, чтобы уменьшить шум в метрике.
Идея: если user был heavy user до эксперимента, он и в эксперименте будет. Учитываем это — variance падает.
Формула
Y_CUPED = Y - θ × (X - mean(X))Где:
- Y — метрика в эксперименте
- X — та же метрика в pre-experiment period (covariate)
- θ — коэффициент:
Cov(Y, X) / Var(X)(OLS slope)
Интерпретация: «очистить» Y от variance, объяснённой X.
Пример
Метрика: revenue per user за эксперимент (2 недели).
Covariate: revenue per user за предыдущие 4 недели.
Сильная корреляция → θ высокий → большая reduction variance.
Reduction variance
Var(Y_CUPED) = Var(Y) × (1 - ρ²)Где ρ — корреляция Y и X.
Если ρ = 0.7 → variance падает на 49%. Если ρ = 0.9 → на 81%.
Когда CUPED эффективен
- User-level метрики с pre-experiment data
- Стабильные users (revenue, sessions, time-on-site)
- Не new users — нет pre-experiment history
Когда НЕ работает
- Новые пользователи (нет pre-experiment data)
- Новые features (нет аналога в прошлом)
- Discrete метрики вроде conversion — меньше gain
Как реализовать в SQL
WITH user_data AS (
SELECT
user_id,
SUM(CASE WHEN DATE BETWEEN '2026-04-01' AND '2026-04-14' THEN revenue END) AS y,
SUM(CASE WHEN DATE BETWEEN '2026-03-01' AND '2026-03-31' THEN revenue END) AS x
FROM transactions
GROUP BY user_id
),
theta AS (
SELECT covar_pop(y, x) / NULLIF(var_pop(x), 0) AS theta, avg(x) AS mean_x
FROM user_data
)
SELECT
u.user_id,
u.y - t.theta * (u.x - t.mean_x) AS y_cuped
FROM user_data u, theta t;Потом t-test на y_cuped между группами.
В Python
import numpy as np
def cuped(y, x):
theta = np.cov(y, x)[0, 1] / np.var(x)
return y - theta * (x - np.mean(x))
y_adjusted = cuped(y, x_pre_experiment)
# t-test на y_adjusted вместо yВажные детали
Рассчитывать θ на всей выборке
НЕ отдельно по control и treatment. Иначе bias.
Random assignment
CUPED работает только с randomized treatment (обычный A/B).
Check balance
Pre-experiment X должен быть balanced между группами (ожидаем, т.к. random assignment).
Gains в выборке
Если variance упал в 2 раза → можно в 2 раза меньше выборки для той же statistical power. Или сократить тест вдвое по времени.
В компаниях со многими экспериментами — огромный выигрыш.
Альтернативы
- Stratification: разделить на страты, агрегировать
- Regression adjustment: линейная модель с features
- Double machine learning: для complex covariates
CUPED — простейший, часто работает хорошо.
На собесе
«Что такое CUPED?» Метод уменьшения variance через pre-experiment covariate.
«Почему работает?» Убирает шум, объяснённый covariate.
«Какое условие?» Correlation между Y и X должна быть.
«Gain в практике?» 30-70% reduction variance для revenue-like метрик.
Частые ошибки
Считать θ отдельно по группам
Bias. Только на общей выборке.
Применять на новых users
Pre-experiment data нет → X = 0 → no gain и potentially misleading.
Correlation с treatment
Если X коррелирует с assignment (что не должно быть при random) — результат biased.
Связанные темы
- A/B-тест простыми словами
- Stratification простыми словами
- Размер выборки для A/B
- p-value простыми словами
FAQ
Работает на conversion?
Да, но gain меньше, чем на continuous.
Нужна регрессия?
CUPED — простейшая form of regression adjustment.
Сложно внедрить?
Нет, пара строк кода. Требует только pre-experiment data.
Тренируйте A/B — откройте тренажёр с 1500+ вопросами для собесов.