Слишком красивый рост: проверь сплит
// Условие
Тест нового онбординга: дизайн 50/50, метрика — конверсия в первую покупку. Через неделю в дашборде +0.9 п.п. и «звёздочка значимости». Продакт готов раскатывать. Но опытный аналитик сначала проверяет сам сплит.
result — dict с ключами n_a, n_b, p_value_srm.// Данные
user_id, group (A/B), converted (0/1) — одна строка на юзера// Решение
Подсказка
Размеры групп: df['group'].value_counts().
SRM-чек — хи-квадрат на соответствие наблюдаемых размеров ожидаемым: stats.chisquare([n_a, n_b], f_exp=[total/2, total/2]).
Если p_value_srm крошечный (например, < 0.001) — сплит сломан: трафик делился не 50/50, и любые различия метрик могут быть артефактом.
Сначала попробуй сам → Показать решение
df = load_data()
from scipy import stats
vc = df['group'].value_counts()
n_a, n_b = int(vc['A']), int(vc['B'])
total = n_a + n_b
# SRM: соответствуют ли наблюдаемые размеры дизайну 50/50
srm = stats.chisquare([n_a, n_b], f_exp=[total / 2, total / 2])
result = {'n_a': n_a, 'n_b': n_b, 'p_value_srm': srm.pvalue}
print(result)
Продакт ждёт раскатки. Твой вердикт?
При дизайне 50/50 отклонение 21 000 vs 24 000 невозможно объяснить случайностью (p ≈ 10⁻⁴⁵). Значит, юзеры попадали в группы не случайно — и группы могут различаться систематически (платформа, гео, боты). «Подрезать» группу B нельзя: неизвестно, какие юзеры лишние, — это маскирует баг вместо починки. Время тоже не выровняет сломанную рандомизацию. Единственный честный ход: найти причину SRM, починить, перезапустить.