«Мы запустили A/B тест, конверсия выросла на 15%, раскатываем!» — стоп. А выборка достаточная? P-value посчитали? Проверили на sample ratio mismatch? 80% A/B тестов в продуктовых командах проводятся неправильно: либо недостаточный размер выборки, либо «подглядывание» в результаты раньше времени, либо ошибки в интерпретации. Результат — неверные решения, откат фичей, потеря времени. Эта статья — практическое руководство для аналитика: как правильно спланировать эксперимент, рассчитать выборку, запустить тест, интерпретировать результаты и не попасть в типичные ловушки статистики.
1. Основы A/B тестирования
Что такое A/B тест
A/B тест (сплит-тест) — это контролируемый эксперимент, в котором две версии продукта (A — контроль, B — тест) показываются разным группам пользователей одновременно. Цель — понять, какая версия лучше влияет на целевую метрику.
| Компонент | Описание |
|---|---|
Контрольная группа (A) | Текущая версия продукта, baseline |
Тестовая группа (B) | Новая версия с изменением |
Метрика | Показатель, который измеряем (CTR, конверсия, revenue) |
Выборка | Количество пользователей в эксперименте |
Длительность | Время проведения теста (дни/недели) |
Зачем нужны A/B тесты
| Цель | Описание | Пример |
|---|---|---|
Принятие решений на данных | Не гадаем, а проверяем гипотезы | «Зелёная кнопка лучше синей» → тестируем |
Снижение рисков | Проверяем на части трафика, не на всех | Новый дизайн может ухудшить метрики — тестируем на 10% |
Оптимизация метрик | Непрерывное улучшение продукта | +5% к конверсии каждый квартал через тесты |
Валидация гипотез | Проверка идей перед полным запуском | «Персонализация увеличит engagement» — проверяем |
Типы A/B тестов
| Тип | Описание | Когда использовать |
|---|---|---|
A/B тест (2 варианта) | Контроль vs 1 изменение | Самый частый случай |
A/B/C тест (3+ вариантов) | Контроль vs несколько изменений | Тестируем разные версии кнопки |
Multivariate (MVT) | Несколько элементов одновременно | Заголовок × цвет кнопки × текст CTA |
Sequential тест | Можно останавливать раньше при явном эффекте | Когда нужна скорость |
Статистика: ключевые понятия
| Термин | Определение | Типичное значение |
|---|---|---|
P-value | Вероятность получить такой результат случайно | < 0.05 = значимо |
Confidence Level | Уровень уверенности в результате | 95% (реже 90% или 99%) |
Statistical Power | Вероятность обнаружить эффект, если он есть | 80% (иногда 90%) |
MDE (Minimum Detectable Effect) | Минимальный эффект, который можем детектировать | 5–10% от baseline |
Type I Error (α) | Ложноположительный: сказали «работает», но это случайность | α = 0.05 (5%) |
Type II Error (β) | Ложноотрицательный: сказали «не работает», но работает | β = 0.20 (20%) |
Золотое правило: P-value < 0.05 при 95% confidence level = статистически значимый результат. Но это не гарантия, что эффект реальный — нужно проверять и другие условия.
2. Формулирование гипотезы
Структура гипотезы
Хорошая гипотеза отвечает на вопросы: Что? Кто? Почему? Какой эффект?
Формула гипотезы:
«Если мы [ИЗМЕНЕНИЕ] для [АУДИТОРИЯ], то [МЕТРИКА] изменится на [ЭФФЕКТ], потому что [ПРИЧИНА]»
Примеры гипотез
| Плохая гипотеза | Хорошая гипотеза | Почему хорошо |
|---|---|---|
| «Зелёная кнопка лучше» | «Если мы изменим цвет кнопки "Купить" с синего на зелёный для всех пользователей главной страницы, то CTR кнопки вырастет на 5–10%, потому что зелёный цвет ассоциируется с действием» | Конкретика: что, кто, метрика, ожидаемый эффект, причина |
| «Персонализация увеличит конверсию» | «Если мы покажем персонализированные рекомендации на странице товара для пользователей с > 3 визитов, то конверсия в покупку вырастет на 7–12%, потому что релевантные товары снижают время поиска» | Указана аудитория (> 3 визитов), метрика (конверсия), диапазон эффекта |
| «Новый дизайн круче» | «Если мы упростим форму регистрации с 5 полей до 3 для всех новых пользователей, то конверсия регистрации вырастет на 10–15%, потому что меньше полей = меньше трения» | Конкретное изменение (5→3 поля), аудитория (новые), метрика, причина |
Чек-лист хорошей гипотезы
✅ Конкретное изменение (не «улучшим UX», а «добавим подсказку под полем email»)
✅ Чётко определённая аудитория (все пользователи / новые / мобильные)
✅ Измеримая метрика (CTR, конверсия, time on page)
✅ Ожидаемый эффект (диапазон: 5–10%, не точное число)
✅ Причина / механика (почему изменение должно повлиять)
✅ Тестируемая (можно запустить A/B тест)
3. Выбор метрик
Типы метрик в A/B тесте
| Тип метрики | Описание | Пример |
|---|---|---|
Primary (основная) | Главная метрика, ради которой запускаем тест | Конверсия в покупку, CTR кнопки, revenue per user |
Secondary (вторичная) | Дополнительные метрики для контекста | Time on page, bounce rate, session duration |
Guardrail (защитная) | Метрики, которые не должны ухудшиться | Page load time, error rate, user satisfaction |
Требования к Primary метрике
| Требование | Описание | Пример |
|---|---|---|
Измеримость | Можем точно измерить | ✅ CTR, ❌ «Пользователь доволен» |
Чувствительность | Реагирует на изменения | ✅ Клики, ❌ Регистрации (если их мало) |
Бизнес-ценность | Связана с целями компании | ✅ Revenue, ❌ Просмотры страницы 404 |
Временной горизонт | Можем измерить за разумное время | ✅ CTR за неделю, ❌ LTV за год |
Примеры метрик по целям
| Цель теста | Primary метрика | Secondary | Guardrail |
|---|---|---|---|
Увеличить продажи | Конверсия в покупку | AOV, items per order | Bounce rate, page load time |
Повысить engagement | DAU, session duration | Pages per session, return rate | Churn rate, app crashes |
Улучшить регистрацию | Registration rate | Time to register, drop-off rate | Email verification rate |
Оптимизировать контент | CTR заголовка | Time on page, scroll depth | Bounce rate |
Распространённые ошибки в выборе метрик
| Ошибка | Почему плохо | Что делать |
|---|---|---|
| Слишком много primary метрик | Увеличивает риск ложноположительного результата (multiple testing problem) | 1 primary метрика, остальные — secondary |
| Метрика с низкой конверсией | Нужна огромная выборка | Использовать proxy-метрику (например, add to cart вместо purchase) |
| Метрика не связана с гипотезой | Тестируем не то | Метрика должна напрямую измерять эффект изменения |
| Игнорирование guardrail метрик | Можем улучшить одно, сломав другое | Всегда проверять page load, errors, user experience |
4. Расчёт размера выборки и длительности
Формула расчёта размера выборки
Размер выборки зависит от:
Baseline метрики (текущая конверсия, например 10%)
MDE (минимальный детектируемый эффект, например +1%)
Confidence level (обычно 95%)
Statistical power (обычно 80%)
Упрощённая формула (для конверсии):
n = 2 × (Z_α/2 + Z_β)² × p × (1 − p) / (MDE)²
Где:
• n = размер выборки на группу
• Z_α/2 = 1.96 (для 95% confidence)
• Z_β = 0.84 (для 80% power)
• p = baseline конверсия
• MDE = минимальный эффект (в долях, не %)
Примеры расчёта
| Baseline конверсия | MDE | Confidence | Power | Размер выборки (на группу) |
|---|---|---|---|---|
| 10% | +1% (относительно +10%) | 95% | 80% | ~15 000 пользователей |
| 10% | +2% (относительно +20%) | 95% | 80% | ~3 800 пользователей |
| 5% | +1% (относительно +20%) | 95% | 80% | ~7 400 пользователей |
| 20% | +2% (относительно +10%) | 95% | 80% | ~19 000 пользователей |
Важно: Чем меньше MDE (минимальный эффект), тем больше нужна выборка. Детектировать +1% сложнее, чем +10%.
Калькуляторы размера выборки
| Инструмент | URL | Особенности |
|---|---|---|
| Evan Miller's Calculator | evanmiller.org/ab-testing | Простой, для конверсии |
| Optimizely Sample Size | optimizely.com/sample-size-calculator | Учитывает sequential тесты |
| AB Tasty Calculator | abtasty.com/sample-size-calculator | Русский интерфейс |
| Statsig Calculator | statsig.com/calculator | Для continuous метрик тоже |
Расчёт длительности теста
Длительность = Размер выборки (обе группы) / Дневной трафик × Доля в эксперименте
Пример:
• Нужно 30 000 пользователей (15к на группу × 2)
• Дневной трафик = 10 000 пользователей
• Доля в эксперименте = 50%
• Длительность = 30 000 / (10 000 × 0.5) = 6 дней
Факторы, влияющие на длительность
| Фактор | Влияние |
|---|---|
Недельная сезонность | Минимум 1 полная неделя (Mon–Sun), лучше 2 недели |
Праздники | Не запускать тесты перед/во время праздников (аномальное поведение) |
Novelty effect | Первые 2–3 дня пользователи могут кликать на новое из любопытства |
Тип метрики | Revenue может меняться медленнее, чем CTR → дольше тест |
Правила длительности
✅ Минимум 1 неделя (чтобы покрыть все дни недели)
✅ Лучше 2 недели (для стабильности результатов)
❌ Не останавливать раньше, даже если p-value < 0.05 (peeking problem)
✅ Дождаться нужного размера выборки
5. Сплитование: как разделить пользователей
Методы разделения на группы
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Random (случайный) | Каждый пользователь случайно попадает в A или B | Простота, равные группы | Риск дисбаланса при малой выборке |
Hash-based (по user_id) | hash(user_id) % 100, если < 50 → A, иначе → B | Стабильность (один user всегда в одной группе) | Требует уникальный ID |
Cookie-based | На основе cookie | Работает для незалогиненных | Cookie могут удаляться |
Session-based | Разделение по сессии | Для краткосрочных тестов | Один user может попасть в разные группы |
Критерии хорошего сплитования
| Критерий | Описание |
|---|---|
Рандомизация | Группы A и B должны быть случайными и равными по характеристикам |
Стабильность | Один пользователь всегда в одной группе (не прыгает между A и B) |
Независимость | Группы не влияют друг на друга (нет network effects) |
Sample Ratio Match | Размеры групп соответствуют плану (50/50 или 90/10) |
Sample Ratio Mismatch (SRM)
SRM — одна из самых частых проблем: группы A и B не равны по размеру, хотя должны быть.
| Причина SRM | Как обнаружить | Как исправить |
|---|---|---|
| Баг в коде сплитования | χ² тест: сравнить ожидаемые и фактические размеры групп | Проверить логику hash/random |
| Разное поведение ботов | Боты попадают больше в одну группу | Фильтровать ботов до сплитования |
| Технические ошибки (JS не загрузился) | В группе B больше отвалов из-за бага | Проверить error rate в группах |
Проверка SRM: Если планировали 50/50, а получили 48/52, это нормально? Используй χ² тест. Если p-value < 0.01 → есть проблема, результатам теста нельзя доверять.
Пример кода сплитования (Python)
import hashlib
def assign_variant(user_id, experiment_name, split=50):
"""
Назначить пользователя в группу A или B
Args:
user_id: уникальный ID пользователя
experiment_name: название эксперимента
split: % в группе B (default 50)
Returns:
'A' или 'B'
"""
# Хешируем user_id + experiment_name для стабильности
hash_input = f"{user_id}_{experiment_name}".encode('utf-8')
hash_value = int(hashlib.md5(hash_input).hexdigest(), 16)
# Берём модуль 100 для получения числа 0-99
bucket = hash_value % 100
# Если bucket < split → группа B, иначе A
return 'B' if bucket < split else 'A'
# Пример
user_id = '12345'
variant = assign_variant(user_id, 'button_color_test', split=50)
print(f"User {user_id} → Variant {variant}") # User 12345 → Variant A
6. Запуск эксперимента: чек-лист
Перед запуском (Pre-launch)
| Шаг | Что проверить |
|---|---|
1. Гипотеза | ✅ Чётко сформулирована: что, кто, метрика, эффект, причина |
2. Метрики | ✅ Primary метрика определена ✅ Secondary и guardrail выбраны |
3. Размер выборки | ✅ Рассчитан через калькулятор ✅ Достаточный трафик для набора за 1–2 недели |
4. Длительность | ✅ Минимум 1 неделя ✅ Не пересекается с праздниками |
5. Сплитование | ✅ Код сплитования протестирован ✅ Проверили на Sample Ratio Mismatch |
6. Трекинг | ✅ События логируются корректно ✅ Данные попадают в аналитику |
7. QA | ✅ Протестировали обе версии (A и B) ✅ Нет багов в UI/функциональности |
8. Документация | ✅ Записали гипотезу, метрики, параметры в трекере (Jira, Notion) |
В момент запуска (Launch)
✅ Запустить тест в начале недели (Monday), не в пятницу
✅ Проверить первые часы: данные идут, нет ошибок
✅ Убедиться, что сплит 50/50 (или согласно плану)
✅ Проверить guardrail метрики: нет резких падений
Первые 24 часа после запуска
| Проверка | Что смотреть | Что делать при проблеме |
|---|---|---|
Sample Ratio | Группы A и B примерно равны по размеру | Если нет — остановить, искать баг |
Трекинг метрик | События логируются, данные в дашборде | Проверить код трекинга |
Error rate | Нет резкого роста ошибок в группе B | Откатить тест, фиксить баги |
Page load time | Не выросло время загрузки | Оптимизировать или откатить |
User complaints | Нет массовых жалоб от пользователей | Проверить UX, возможно откатить |
Документирование эксперимента
Создать документ (Notion / Confluence) с:
Название эксперимента
Гипотеза (полная формулировка)
Primary / Secondary / Guardrail метрики
Размер выборки, MDE, confidence, power
Даты запуска и планируемого завершения
Ссылка на дашборд с результатами
Ownership (кто отвечает: аналитик, PM, разработчик)
7. Мониторинг во время теста
Что НЕ делать: peeking problem
Peeking Problem — самая частая ошибка: смотреть результаты теста раньше времени и принимать решение, когда p-value случайно упал ниже 0.05.
| Что происходит | Почему плохо |
|---|---|
| День 2: p-value = 0.03 → «Ура, работает!» | Это может быть случайность, выборка мала |
| День 5: p-value = 0.08 → «Упс, не работает» | Колебания нормальны, надо ждать |
| День 10: p-value = 0.04 → «Раскатываем!» | Но запланировали 14 дней — рано останавливать |
Правило: Не принимать решения до окончания запланированного срока, даже если p-value < 0.05.
Что можно мониторить
| Метрика | Зачем | Как часто |
|---|---|---|
Sample Ratio | Проверить, что сплит корректный | Ежедневно |
Guardrail метрики | Убедиться, что ничего не сломалось | Ежедневно |
Error rate, crashes | Детектировать критичные баги | Ежедневно |
Размер выборки | Понять, когда наберём нужное количество | Раз в 2-3 дня |
Primary метрика (без выводов) | Просто наблюдать динамику | Раз в 2-3 дня (не принимать решений!) |
Когда можно остановить тест раньше
| Ситуация | Действие |
|---|---|
Критичный баг в группе B | Остановить немедленно, фиксить |
Резкое падение guardrail метрик | Остановить, разбираться |
Sample Ratio Mismatch | Остановить, искать баг в сплитовании |
Внешние факторы (праздник, аномалия) | Остановить, перезапустить позже |
Просто p-value < 0.05 | ❌ НЕ останавливать, ждать планового срока |
8. Статистическая значимость: как считать
P-value: что это такое
P-value — вероятность получить наблюдаемый результат (или более экстремальный), если на самом деле разницы между A и B нет (null hypothesis верна).
| P-value | Интерпретация | Решение |
|---|---|---|
| < 0.01 | Очень сильная значимость | ✅ Результат скорее всего реальный |
| 0.01 – 0.05 | Значимый результат | ✅ Можно принимать решение |
| 0.05 – 0.10 | Пограничный случай | ⚠️ Осторожно, может быть случайность |
| > 0.10 | Нет значимости | ❌ Разницы нет или выборка мала |
Частая ошибка: P-value = 0.03 НЕ значит «шанс, что B лучше A = 97%». Это значит «шанс увидеть такую разницу случайно = 3%, если на самом деле разницы нет».
Доверительные интервалы (Confidence Intervals)
CI показывает диапазон, в котором с 95% вероятностью находится истинный эффект.
| Результат | Конверсия A | Конверсия B | Uplift | 95% CI | Интерпретация |
|---|---|---|---|---|---|
Пример 1 | 10.0% | 11.5% | +15% | [+8%, +22%] | ✅ Значимо: CI не включает 0 |
Пример 2 | 10.0% | 10.3% | +3% | [-2%, +8%] | ❌ Не значимо: CI включает 0 |
Пример 3 | 10.0% | 9.5% | -5% | [-10%, -1%] | ⚠️ Негативный эффект, значимо |
Правило: Если 95% CI не включает 0 → результат статистически значимый.
Расчёт p-value для конверсии (Z-test)
Z-статистика:
Z = (p_B − p_A) / sqrt(p_pooled × (1 − p_pooled) × (1/n_A + 1/n_B))
Где:
• p_A = конверсия в группе A
• p_B = конверсия в группе B
• p_pooled = (conversions_A + conversions_B) / (n_A + n_B)
• n_A, n_B = размеры групп
P-value = 2 × (1 − CDF(|Z|)) // для two-tailed теста
Пример расчёта (Python)
from scipy.stats import norm
import math
def ab_test_ztest(conversions_a, n_a, conversions_b, n_b):
"""
Z-test для сравнения двух конверсий
"""
p_a = conversions_a / n_a
p_b = conversions_b / n_b
# Pooled proportion
p_pooled = (conversions_a + conversions_b) / (n_a + n_b)
# Standard error
se = math.sqrt(p_pooled * (1 - p_pooled) * (1/n_a + 1/n_b))
# Z-statistic
z = (p_b - p_a) / se
# P-value (two-tailed)
p_value = 2 * (1 - norm.cdf(abs(z)))
# Uplift
uplift = (p_b - p_a) / p_a * 100
return {
'p_a': p_a,
'p_b': p_b,
'uplift': uplift,
'z_score': z,
'p_value': p_value,
'significant': p_value < 0.05
}
# Пример
result = ab_test_ztest(
conversions_a=1500, n_a=15000, # A: 10% конверсия
conversions_b=1725, n_b=15000 # B: 11.5% конверсия
)
print(f"Конверсия A: {result['p_a']:.2%}")
print(f"Конверсия B: {result['p_b']:.2%}")
print(f"Uplift: {result['uplift']:.1f}%")
print(f"P-value: {result['p_value']:.4f}")
print(f"Значимо: {result['significant']}")
# Output:
# Конверсия A: 10.00%
# Конверсия B: 11.50%
# Uplift: 15.0%
# P-value: 0.0001
# Значимо: True
9. Интерпретация результатов
Матрица решений
| P-value | Uplift Primary | Guardrail метрики | Решение |
|---|---|---|---|
| < 0.05 | Положительный (+5%+) | ✅ Норма | 🟢 Раскатывать на всех |
| < 0.05 | Положительный (+2–5%) | ✅ Норма | 🟡 Раскатывать, но мониторить |
| < 0.05 | Положительный | ❌ Упала guardrail | 🔴 НЕ раскатывать, искать компромисс |
| < 0.05 | Отрицательный (-5%+) | — | 🔴 Отклонить, B хуже A |
| 0.05 – 0.10 | Положительный | ✅ Норма | 🟡 Пограничный случай: либо увеличить выборку, либо не раскатывать |
| > 0.10 | Любой | — | ⚪ Нет эффекта, не раскатывать |
Проверка результатов: чек-лист
| Проверка | Что смотреть |
|---|---|
1. Размер выборки | ✅ Набрали запланированное количество? |
2. Длительность | ✅ Тест шёл минимум 1 неделю (лучше 2)? |
3. P-value | ✅ P-value < 0.05 для primary метрики? |
4. Uplift | ✅ Uplift > MDE (минимального детектируемого эффекта)? |
5. Доверительный интервал | ✅ 95% CI не включает 0? |
6. Secondary метрики | ✅ Движутся в ожидаемом направлении? |
7. Guardrail метрики | ✅ Не ухудшились (page load, errors, satisfaction)? |
8. Sample Ratio Mismatch | ✅ Группы A и B равны по размеру (χ² test)? |
9. Сегментация | ✅ Эффект одинаков в разных сегментах (mobile/desktop, новые/старые)? |
10. Novelty effect | ✅ Эффект не падает к концу теста? |
Когда НЕ раскатывать, даже если p-value < 0.05
| Ситуация | Почему |
|---|---|
| Guardrail метрики ухудшились | Улучшили конверсию, но сломали UX / performance |
| Sample Ratio Mismatch | Баг в сплитовании → результатам нельзя доверять |
| Эффект только в одном сегменте | Например, работает только на mobile, на desktop хуже |
| Novelty effect | Эффект был в первые 3 дня, потом пропал |
| Uplift слишком мал (< 1%) | Статистически значимо, но практически бесполезно |
| Тест шёл во время аномалии | Праздники, маркетинговая кампания — данные искажены |
Сегментный анализ
Проверить эффект в разных сегментах:
| Сегмент | Зачем проверять |
|---|---|
Mobile vs Desktop | Эффект может быть только на одной платформе |
Новые vs Returning | Новички реагируют иначе, чем постоянные |
География | Разные страны/регионы → разное поведение |
Время суток / День недели | Эффект может быть только в пиковые часы |
Важно: Сегментацию нужно планировать ДО теста, а не искать сегменты «где сработало» после. Иначе — multiple testing problem.
10. Типичные ошибки в A/B тестах
ТОП-10 ошибок
| Ошибка | Описание | Как избежать |
|---|---|---|
1. Peeking Problem | Смотреть результаты раньше времени и останавливать тест | Ждать запланированного срока, не принимать решений раньше |
2. Малая выборка | Тест на 100 пользователях → нет статистической мощности | Рассчитать размер выборки через калькулятор |
3. Короткий тест | Запустили на 2 дня → не покрыли недельную сезонность | Минимум 1 неделя, лучше 2 |
4. Sample Ratio Mismatch | Группы A и B не равны → баг в сплитовании | Проверить χ² тест, если SRM → искать баг |
5. Множественное тестирование | 10 метрик, хоть одна будет p < 0.05 случайно | 1 primary метрика, остальные — secondary |
6. Игнорирование guardrail | Конверсия выросла, но page load упал на 50% | Всегда проверять UX, performance, errors |
7. Novelty Effect | Пользователи кликают на новое из любопытства, потом эффект пропадает | Тест минимум 2 недели, смотреть динамику по дням |
8. Selection Bias | В группу B попали более активные пользователи → результат искажён | Рандомизация, проверка баланса групп |
9. Сегментация после теста | «Ищем где сработало» → находим случайные сегменты | Планировать сегменты ДО теста |
10. Неправильная интерпретация p-value | «P = 0.03 значит B лучше с вероятностью 97%» (НЕТ!) | Понимать, что p-value = шанс увидеть эффект случайно при null hypothesis |
Simpson's Paradox
Simpson's Paradox — ситуация, когда общий эффект положительный, но в каждом сегменте отдельно — отрицательный (или наоборот).
| Сегмент | Конверсия A | Конверсия B | Результат |
|---|---|---|---|
Mobile | 15% (300/2000) | 14% (280/2000) | ❌ B хуже |
Desktop | 10% (200/2000) | 9% (180/2000) | ❌ B хуже |
Общий | 12.5% (500/4000) | 13% (520/4000) | ✅ B лучше (!) |
Причина: Разное распределение по сегментам может искажать общий результат. Всегда проверяй сегменты.
11. Инструменты для A/B тестирования
Платформы для экспериментов
| Инструмент | Тип | Плюсы | Минусы |
|---|---|---|---|
Optimizely | SaaS | Простота, visual editor, статистика из коробки | Дорого (от $50k/год) |
VWO | SaaS | Дешевле Optimizely, хороший UI | Меньше возможностей для сложных экспериментов |
Google Optimize | SaaS | Бесплатный (был), интеграция с GA | ⚠️ Закрылся в 2023, альтернативы: GA4 experiments |
Statsig | SaaS | Бесплатный tier, современный стек, feature flags | Относительно новый |
LaunchDarkly | SaaS (feature flags) | Feature flags + эксперименты | Дорого, больше про feature flags чем A/B |
Самописное решение | In-house | Полный контроль, гибкость | Нужны ресурсы на разработку и поддержку |
Калькуляторы и статистические инструменты
| Инструмент | URL | Что умеет |
|---|---|---|
Evan Miller's Calculator | evanmiller.org/ab-testing | Размер выборки, значимость, Chi-square |
AB Tasty Calculator | abtasty.com/sample-size-calculator | Русский интерфейс, размер выборки |
Statsig Calculator | statsig.com/calculator | Размер выборки для continuous метрик |
CXL AB Test Calculator | cxl.com/ab-test-calculator | Размер выборки + анализ результатов |
Python-библиотеки
| Библиотека | Установка | Что умеет |
|---|---|---|
scipy.stats |
| Z-test, t-test, chi-square, p-value |
statsmodels |
| Продвинутая статистика, regression |
abtest |
| Готовые функции для A/B тестов |
pymc3 |
| Bayesian A/B testing |
Дашборды и визуализация
Tableau / Power BI: для построения дашбордов результатов
Amplitude / Mixpanel: product analytics с built-in A/B testing
Google Data Studio: бесплатный, интеграция с BigQuery
Metabase / Redash: open-source BI для SQL-запросов
12. Чек-лист идеального A/B теста
Планирование (перед запуском)
✅ Гипотеза сформулирована по формуле: «Если [что] для [кого], то [метрика] [эффект], потому что [причина]»
✅ Primary метрика выбрана (1 штука)
✅ Secondary и guardrail метрики определены
✅ Рассчитан размер выборки (калькулятор, MDE, confidence 95%, power 80%)
✅ Определена длительность теста (минимум 1 неделя)
✅ Метод сплитования выбран (hash-based, стабильный)
✅ Трекинг событий настроен и протестирован
✅ QA проведено для обеих версий (A и B)
✅ Документация создана (гипотеза, метрики, параметры)
Запуск
✅ Тест запущен в начале недели (Monday)
✅ Первые 24 часа: проверен Sample Ratio (группы равны)
✅ Проверены guardrail метрики (нет резких падений)
✅ Error rate в норме
✅ Данные идут в аналитику корректно
Во время теста
✅ НЕ подглядываем в primary метрику раньше времени (peeking problem)
✅ Мониторим guardrail метрики ежедневно
✅ Проверяем Sample Ratio Match (χ² test)
✅ Не останавливаем тест раньше, даже если p < 0.05
✅ Если критичный баг — останавливаем, фиксим, перезапускаем
Анализ результатов
✅ Набрана запланированная выборка
✅ Тест шёл минимум 1 неделю (лучше 2)
✅ P-value < 0.05 для primary метрики
✅ 95% CI не включает 0
✅ Uplift > MDE (минимальный детектируемый эффект)
✅ Secondary метрики движутся в ожидаемом направлении
✅ Guardrail метрики НЕ ухудшились
✅ Sample Ratio Match (нет SRM)
✅ Проверен сегментный анализ (mobile/desktop, новые/старые)
✅ Нет Novelty Effect (эффект стабилен по дням)
Решение
| Условие | Решение |
|---|---|
| ✅ Все проверки пройдены + p < 0.05 + положительный uplift | 🟢 Раскатывать на 100% |
| ✅ P < 0.05, но guardrail метрики упали | 🔴 НЕ раскатывать, искать компромисс |
| ⚠️ P = 0.05–0.10 (пограничный) | 🟡 Увеличить выборку или не раскатывать |
| ❌ P > 0.10 | ⚪ Нет эффекта, отклонить гипотезу |
| ❌ SRM обнаружен | 🔴 Результатам нельзя доверять, искать баг |
Документирование итогов
✅ Записать результаты: primary метрика, uplift, p-value, CI
✅ Описать решение: раскатывать / не раскатывать / доработать
✅ Learnings: что узнали, что сработало/не сработало
✅ Next steps: следующие гипотезы для тестирования
Итоги
A/B тестирование — мощный инструмент для принятия решений на данных, но только если использовать его правильно. 80% ошибок — это peeking problem, малая выборка, игнорирование guardrail метрик и неправильная интерпретация p-value. Следуя чек-листам и правилам из этой статьи, ты избежишь типичных ловушек и будешь запускать эксперименты, которым можно доверять.
Ключевые правила:
Формулируй чёткую гипотезу (что, кто, метрика, эффект, причина)
Рассчитывай размер выборки ДО запуска (калькуляторы в помощь)
1 primary метрика, остальные — secondary/guardrail
Минимум 1 неделя теста, лучше 2
НЕ подглядывай в результаты раньше времени (peeking problem)
Проверяй Sample Ratio Match (χ² test)
P-value < 0.05 + guardrail метрики в норме = можно раскатывать
Всегда проверяй сегменты (mobile/desktop, новые/старые)
Документируй всё: гипотезу, параметры, результаты, learnings
A/B тестирование — это не магия, а статистика. Понимай инструменты, следуй процессу, не торопись с выводами. И твои эксперименты будут приносить реальную пользу продукту.
А лучшие вакансии для аналитиков ищите на hirehi.ru