Условие
Как вы спроектируете A/B-тест на главной странице LinkedIn? Команда дизайнеров предложила новый layout. Опишите всю процедуру: цели, метрики, дизайн эксперимента, размер выборки, риски.
Решение
Подход
1. Цель и гипотеза.
Гипотеза: «Новый layout главной страницы увеличивает вовлечённость (engagement) пользователей и не ухудшает посещаемость профиля». Цель — измеримая, проверяемая, привязана к одной основной метрике.
2. Метрики.
- Primary:
% DAU, кто совершил минимум 1 engagement-действие на главной(лайк, репост, коммент, клик на пост). - Secondary: время на главной, число просмотренных постов, конверсия в просмотр профиля.
- Guardrail (контр-): посещаемость поиска, доход от premium-подписок, доля «отчётов о проблеме».
3. Юнит рандомизации.
user_id, а не сессия — иначе один пользователь увидит обе версии и эксперимент шумит.
4. Сплит.
- 50/50 при большом трафике LinkedIn.
- Pre-experiment power-анализ: при MDE 1% от baseline (
p₀ ≈ 0.6,MDE = 0.6%абс) нужно ~30-50k пользователей на группу — что для LinkedIn неделя.
5. Длительность.
- Минимум 1 неделя — захватить недельную сезонность.
- 2 недели — желательно, чтобы дать новинке отыграть novelty effect.
6. Сегментация для анализа.
- Новые vs возвращающиеся (разные паттерны поведения).
- Платформа (web / mobile).
- Гео.
7. Анализ.
- Z-test или t-test для разницы средних / долей.
- CUPED для снижения дисперсии (использовать предэкспериментальную метрику пользователя как ковариату).
- Проверка SRM (sample ratio mismatch) — соотношение групп должно быть 50/50; отклонение = баг рандомизации.
8. Рисках и mitigation.
- Novelty effect: первые дни всё новое поднимает метрики, потом откат. Смотрим тренд.
- Network effect: если контент пользователя видят другие, разные группы могут влиять друг на друга. На LinkedIn — слабо, но в DM-фичах это критично; помогает cluster-randomization.
- Сезонность: запускайте не на праздниках.
- Peeking: фиксируйте длительность заранее.
Реализация (псевдокод анализа)
import statsmodels.stats.proportion as smp
# Сравниваем долю engaged-пользователей
z, p = smp.proportions_ztest(
count=[engaged_treatment, engaged_control],
nobs=[n_treatment, n_control],
)
print(p)Подводные камни
- Множественные метрики без поправки — гарантированно найдёте «значимый» эффект случайно. Используйте Bonferroni или фиксируйте 1 primary.
- Tests on the same users — повторное использование группы для разных экспериментов даёт interaction effect.
- Cookie-based рандомизация ломается при logged-out → logged-in. Используйте user_id, когда он есть.
- «Слили дизайн» только на 5% долго — если эксперимент-инструмент не балансирует выборку, можете получить ассиметричную сегментацию.
- Стат-значимость ≠ бизнес-значимость. Эффект 0.1% значим на 10M юзерах, но не стоит релиза.
Эталонный ответ
Гипотеза → primary engagement + secondary + guardrails → рандомизация по user_id, 50/50, неделя минимум → power-анализ под MDE → анализ через z-test/CUPED + SRM check → mitigation: novelty, network, сезонность. Без primary метрики и guardrails A/B превращается в data dredging.