Новый поиск: доверительный интервал
// Условие
Тестировали новый поисковый движок: контроль A — старый, тест B — новый. Метрика — конверсия в добавление товара в корзину. Продакт просит не просто «значимо/незначимо», а вилку: на сколько вырастет метрика в худшем и лучшем случае.
result — dict с ключами diff, ci_low, ci_high.// Данные
user_id, group (A/B), converted (0/1) — одна строка на юзера// Решение
Подсказка
Разница долей: diff = conv_b - conv_a. Для CI нужна непулированная стандартная ошибка: se = (pa*(1-pa)/na + pb*(1-pb)/nb)**0.5.
95%-ный CI: diff ± 1.96 * se. Можно точнее: stats.norm.ppf(0.975) вместо 1.96 — обе версии принимаются.
Если интервал не содержит 0 — на уровне 5% эффект статзначим. Смотри и на нижнюю границу: это «худший правдоподобный» сценарий.
Сначала попробуй сам → Показать решение
df = load_data()
from scipy import stats
s = df.groupby('group')['converted'].agg(['sum', 'count'])
pa = s.loc['A', 'sum'] / s.loc['A', 'count']
pb = s.loc['B', 'sum'] / s.loc['B', 'count']
diff = pb - pa
# Непулированная SE — стандарт для доверительного интервала разницы
se = (pa * (1 - pa) / s.loc['A', 'count'] + pb * (1 - pb) / s.loc['B', 'count']) ** 0.5
z = stats.norm.ppf(0.975) # ≈ 1.96
result = {'diff': diff, 'ci_low': diff - z * se, 'ci_high': diff + z * se}
print(result)
Что сказать продакту про «вилку»?
CI95 ≈ [+0.3 п.п.; +2.1 п.п.]: ноль вне интервала — это то же самое, что p < 0.05. Ширина интервала — не приговор, а честная мера неопределённости: даже нижняя граница даёт рост. «Пересчитать на 80%, чтобы сузить» — подгонка отчётности: уровень доверия фиксируется до теста, а не подбирается под красивую картинку.