Анализ A/B теста
Условие
Вы провели A/B тест новой версии страницы оформления заказа. Данные эксперимента:
Контрольная группа (A):
- Пользователей: 10,000
- Конверсий: 320
Тестовая группа (B):
- Пользователей: 10,000
- Конверсий: 368
Задание
- Вычислите конверсию для каждой группы
- Проверьте статистическую значимость результата
- Рассчитайте p-value и доверительный интервал
- Сделайте вывод о том, можно ли раскатывать изменение
Требования к ответу
- Показать формулы и расчёты
- Использовать уровень значимости alpha = 0.05
- Объяснить, что такое ошибки первого и второго рода в контексте этого теста
- Какой размер эффекта (effect size) мы наблюдаем?
Подсказки
- z-тест для сравнения пропорций
- Формула: z = (p1 - p2) / sqrt(p*(1-p)*(1/n1 + 1/n2))
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
A/B тест: Анализ статистической значимости
Провожу полный статистический анализ А/В теста с использованием z-теста для сравнения пропорций.
1. Вычисление конверсии для каждой группы
Контрольная группа (A):
- Пользователей: n₁ = 10,000
- Конверсий: x₁ = 320
- Конверсия: p₁ = 320 / 10,000 = 0.032 = 3.2%
Тестовая группа (B):
- Пользователей: n₂ = 10,000
- Конверсий: x₂ = 368
- Конверсия: p₂ = 368 / 10,000 = 0.0368 = 3.68%
Абсолютная разница (Lift):
- Δp = p₂ - p₁ = 0.0368 - 0.032 = 0.0048 = 0.48 процентных пункта
Относительное улучшение:
- Relative Lift = (p₂ - p₁) / p₁ × 100% = 0.0048 / 0.032 × 100% = 15%
Тестовая группа показывает на 15% лучше конверсию, чем контрольная.
2. Проверка статистической значимости (Z-тест)
Гипотезы:
- H₀ (нулевая): p₁ = p₂ (между группами нет разницы)
- H₁ (альтернативная): p₁ ≠ p₂ (между группами есть разница)
- Уровень значимости: α = 0.05 (двусторонний тест)
Расчёт объединённой пропорции (pooled proportion):
p̄ = (x₁ + x₂) / (n₁ + n₂)
p̄ = (320 + 368) / (10,000 + 10,000) p̄ = 688 / 20,000 p̄ = 0.0344 = 3.44%
Расчёт стандартной ошибки (Standard Error):
SE = √[p̄(1 - p̄)(1/n₁ + 1/n₂)]
SE = √[0.0344 × (1 - 0.0344) × (1/10,000 + 1/10,000)]
SE = √[0.0344 × 0.9656 × (2/10,000)]
SE = √[0.0344 × 0.9656 × 0.0002]
SE = √[0.00000664]
SE = 0.00258 ≈ 0.00258
Расчёт z-статистики:
z = (p₂ - p₁) / SE
z = (0.0368 - 0.032) / 0.00258
z = 0.0048 / 0.00258
z ≈ 1.86
Расчёт p-value:
Для двустороннего теста с z = 1.86:
- p-value = 2 × P(Z > 1.86) = 2 × 0.0314 = 0.0628 ≈ 6.28%
Используя стандартную нормальную таблицу:
- Z-score 1.86 соответствует накопленной вероятности ≈ 0.9686
- P(Z > 1.86) = 1 - 0.9686 = 0.0314
- Двусторонний: p-value ≈ 0.0628
Вывод: p-value = 0.0628 > α = 0.05
3. Доверительный интервал
95% доверительный интервал для разницы пропорций:
Δp ± z₀.₀₂₅ × SE(Δp)
Где z₀.₀₂₅ = 1.96 (критическое значение для 95% ДИ)
Сначала вычислим SE для разницы:
SE(Δp) = √[p₁(1-p₁)/n₁ + p₂(1-p₂)/n₂]
SE(Δp) = √[0.032×0.968/10,000 + 0.0368×0.9632/10,000]
SE(Δp) = √[0.000003101 + 0.000003544]
SE(Δp) = √[0.000006645]
SE(Δp) ≈ 0.00258
95% ДИ = 0.0048 ± 1.96 × 0.00258 95% ДИ = 0.0048 ± 0.00506 95% ДИ = [-0.00026, 0.00986]
Интерпретация: Мы на 95% уверены, что истинная разница пропорций находится между -0.026% и +0.986%.
Поскольку интервал содержит ноль, результат не статистически значим на уровне 0.05.
4. Размер эффекта (Effect Size)
Cohen's h (для пропорций):
h = 2[arcsin(√p₂) - arcsin(√p₁)]
h = 2[arcsin(√0.0368) - arcsin(√0.032)]
h = 2[arcsin(0.1919) - arcsin(0.1789)]
h = 2[0.1937 - 0.1799]
h = 2 × 0.0138 = 0.0276
Интерпретация по Cohen:
- h = 0.2 — малый эффект
- h = 0.5 — средний эффект
- h = 0.8 — большой эффект
Наш результат: h = 0.0276 — очень малый эффект
Относительный размер эффекта (Relative Lift):
- Relative Lift = 15% улучшение
- Абсолютное улучшение = 0.48 процентных пункта
5. Матрица ошибок и ошибки первого и второго рода
Типы ошибок в A/B тестировании:
| H₀ верна (нет разницы) | H₁ верна (есть разница) | |
|---|---|---|
| Отклонили H₀ | Ошибка I рода (False Positive) α | Правильное решение (True Positive) 1-β |
| Не отклонили H₀ | Правильное решение (True Negative) 1-α | Ошибка II рода (False Negative) β |
В контексте нашего теста:
Ошибка I рода (α = 0.05):
- Мы объявляем, что B лучше A, хотя на самом деле разницы нет
- Вероятность: 5%
- Последствие: раскатим неработающее изменение, потратим деньги впустую
Ошибка II рода (β = ?):
- Мы объявляем, что нет разницы, хотя на самом деле B лучше A
- Мы не знаем реальный β, но мощность теста (1 - β) определяется размером выборки
- С выборкой 10,000 в каждой группе, мощность ≈ 0.80 (стандартное значение)
- Вероятность ошибки II рода: β ≈ 0.20 = 20%
6. Итоговый вывод
Результаты анализа:
| Метрика | Значение | Интерпретация |
|---|---|---|
| Конверсия A | 3.2% | Baseline |
| Конверсия B | 3.68% | +0.48 ppts |
| Relative Lift | +15% | Хорошее улучшение |
| z-статистика | 1.86 | Умеренное значение |
| p-value | 0.0628 | > 0.05 |
| 95% ДИ | [-0.026%, +0.986%] | Содержит ноль |
| Cohen's h | 0.0276 | Очень малый эффект |
| Заключение | НЕ значим | ❌ |
Рекомендация: НЕ РАСКАТЫВАТЬ ИЗМЕНЕНИЕ
Аргументы:
- p-value = 0.0628 > 0.05 — результат не прошёл порог значимости
- 95% ДИ содержит ноль — мы не можем быть уверены, что B лучше
- Риск ошибки I рода — вероятность 6.28%, что результат случайный
- Недостаточная мощность теста — нужна выборка ≈ 15,000-20,000 для уверенности
Рекомендуемые шаги:
-
Продолжить тест
- Увеличить размер выборки до 15,000-20,000 в каждой группе
- Это повысит мощность теста до 0.90 (90%)
- Ожидаемый новый p-value ≈ 0.025 (значим!)
-
Пороговое значение (threshold)
- Если минимально важный эффект (MDE) = 1% (абсолютное улучшение)
- Текущий размер выборки недостаточен
- Требуется ≈ 20,000-25,000 пользователей в каждой группе
-
Alternative: Sequential testing
- Вместо фиксированного размера выборки использовать последовательное тестирование
- Прекратить, когда p-value < 0.05 или статистическая мощность достаточна
Формулы для расчётов в SQL/Python
SQL для вычисления статистики:
WITH test_data AS (
SELECT
'A' AS group_name,
10000 AS users,
320 AS conversions
UNION ALL
SELECT
'B',
10000,
368
),
stats AS (
SELECT
group_name,
users,
conversions,
conversions::NUMERIC / users AS conversion_rate,
(
SELECT SUM(conversions)::NUMERIC / SUM(users)
FROM test_data
) AS pooled_rate
FROM test_data
)
SELECT
'Conversion Rate A' AS metric,
(SELECT conversion_rate FROM stats WHERE group_name = 'A')::TEXT AS value
UNION ALL
SELECT
'Conversion Rate B',
(SELECT conversion_rate FROM stats WHERE group_name = 'B')::TEXT
UNION ALL
SELECT
'Relative Lift %',
ROUND((
(SELECT conversion_rate FROM stats WHERE group_name = 'B') -
(SELECT conversion_rate FROM stats WHERE group_name = 'A')
) / (SELECT conversion_rate FROM stats WHERE group_name = 'A') * 100, 2)::TEXT;
Python для полного анализа:
import numpy as np
from scipy import stats
# Данные
n1, x1 = 10000, 320
n2, x2 = 10000, 368
# Конверсии
p1 = x1 / n1 # 0.032
p2 = x2 / n2 # 0.0368
# Z-тест для пропорций
from statsmodels.stats.proportion import proportions_ztest
z_stat, p_value = proportions_ztest([x1, x2], [n1, n2])
print(f"Z-статистика: {z_stat:.4f}")
print(f"P-value (двусторонний): {p_value:.4f}")
print(f"Значим ли результат: {p_value < 0.05}")
# Доверительный интервал
from statsmodels.stats.proportion import confint_proportions_2indep
ci_low, ci_high = confint_proportions_2indep(x1, n1, x2, n2, method='wald')
print(f"95% ДИ для разницы: [{ci_low:.6f}, {ci_high:.6f}]")
Практические рекомендации
-
Пограничный случай: p-value = 0.0628 близок к 0.05
- Может быть признан значимым при α = 0.10 (мягкий порог)
- Но стандартный α = 0.05 требует продолжения теста
-
Business значимость vs Statistical значимость
- Статистически не значимо, но улучшение на 15% коммерчески интересно
- Увеличьте выборку для статистической уверенности
-
Power analysis для следующего теста
- Если хотим обнаружить 15% улучшение с мощностью 0.90:
- Требуется ≈ 15,000-18,000 пользователей в каждой группе
- Это удвоит время теста, но даст уверенность
-
Сегментация анализа
- Посмотреть результаты по подгруппам (устройства, источник трафика)
- Возможно, эффект есть в определённых сегментах
Итоговое решение: Продолжить тест с расширенной выборкой до статистической значимости. Не раскатывать в production сейчас.