A/B-тестыЛовушки A/B-тестовMediumБесплатно~15 мин

Попап сработал. Но какой ценой?

// Условие

Тест агрессивного попапа подписки на рассылку: контроль A — без попапа, тест B — попап на входе. Целевая метрика — конверсия в подписку. Но у теста есть guardrail-метрика — конверсия в покупку: попап не должен мешать покупать.

Что нужно
Посчитай изменение и p-value по обеим метрикам. Сохрани в result — dict с ключами diff_sub, p_value_sub, diff_purchase, p_value_purchase (diff — в долях, B минус A).

// Данные

df: user_id, group (A/B), subscribed (0/1), purchased (0/1)
▶ Решить в A/B-тренажёре

// Решение

Подсказка

Считай каждую метрику независимо тем же z-тестом двух долей: сначала по subscribed, потом по purchased.

Удобно завести функцию ab_test(df, metric_col), возвращающую (diff, p_value), и вызвать её дважды.

Смотри на знак diff_purchase: подписки выросли, а покупки?

Сначала попробуй сам → Показать решение
df = load_data()
from scipy import stats

def ab_test(df, col):
    s = df.groupby('group')[col].agg(['sum', 'count'])
    pa = s.loc['A', 'sum'] / s.loc['A', 'count']
    pb = s.loc['B', 'sum'] / s.loc['B', 'count']
    p_pool = df[col].mean()
    se = (p_pool * (1 - p_pool) * (1 / s.loc['A', 'count'] + 1 / s.loc['B', 'count'])) ** 0.5
    z = (pb - pa) / se
    return pb - pa, 2 * (1 - stats.norm.cdf(abs(z)))

diff_sub, p_sub = ab_test(df, 'subscribed')
diff_pur, p_pur = ab_test(df, 'purchased')

result = {'diff_sub': diff_sub, 'p_value_sub': p_sub,
          'diff_purchase': diff_pur, 'p_value_purchase': p_pur}
print(result)
Подписка: 4.0% → 5.0% (p ≈ 10⁻⁶) — попап работает. Покупка: 12.0% → 11.0% (p ≈ 0.002) — и мешает покупать. Guardrail-метрики для того и нужны: целевая метрика почти всегда растёт, если жать на неё достаточно агрессивно — вопрос в том, что при этом ломается.

Целевая метрика выросла. Раскатываем попап?

  • ✓ Нет: подписки выросли (+1 п.п.), но покупки статзначимо упали (−1 п.п., p ≈ 0.002). Считаем net-эффект в деньгах: подписчик должен окупать потерянные покупки — и ищем менее агрессивный вариант
  • Да: целевая метрика выросла со значимостью p ≈ 10⁻⁶, тест успешен
  • Да, но покажем попап только новым юзерам — им терять нечего
  • Нет: падение покупок доказывает, что рассылки вообще не нужны

Тест «успешен» только если смотреть на одну метрику. Попап купил +200 подписчиков ценой −200 покупателей (на 20 000 юзеров). Решение — экономика: LTV подписки против маржи покупки, и почти наверняка выгоднее менее агрессивный формат (после покупки, по скроллу). «Показать только новым» — новая гипотеза, её тоже тестировать. Вывод про «рассылки не нужны» из этих данных не следует вовсе.

// Похожие задачи

// Разобраться в теме

→ Гайд по A/B-тестам