← Назад к вопросам

Как определить необходимый размер выборки для A/B-теста?

1.8 Middle🔥 141 комментариев
#Аналитика и метрики

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Определение размера выборки для A/B-теста

Размер выборки в A/B-тестировании — критический параметр, определяющий статистическую мощность теста. Неправильный расчёт может привести к неверным выводам или излишним затратам времени и ресурсов.

Основные концепции

Статистическая мощность (Power) — вероятность обнаружить эффект, если он действительно существует. Обычно используется значение 0.80 или 0.90.

Уровень значимости (Alpha) — вероятность ошибки первого рода (false positive). Стандартное значение α = 0.05.

Размер эффекта (Effect Size) — минимальное изменение метрики, которое мы хотим обнаружить. Например, увеличение conversion rate на 2%.

Формула для пропорций

Для тестирования пропорций (conversion rate):

from scipy import stats
import math

def sample_size_proportion(baseline, effect_size, alpha=0.05, power=0.80):
    p1 = baseline
    p2 = baseline + effect_size
    
    z_alpha = stats.norm.ppf(1 - alpha/2)
    z_beta = stats.norm.ppf(power)
    
    numerator = (z_alpha + z_beta) ** 2
    variance = p1 * (1 - p1) + p2 * (1 - p2)
    
    n = 2 * numerator * variance / (p2 - p1) ** 2
    
    return math.ceil(n)

# Базовая конверсия 10%, хотим обнаружить +2%
baseline_conversion = 0.10
desired_effect = 0.02
n = sample_size_proportion(baseline_conversion, desired_effect)
print(f"Размер выборки (на группу): {n:,}")

Таблица критических значений

PowerAlpha=0.05Описание
0.802.80Стандартный выбор
0.903.24Более консервативный

Расчёт времени тестирования

def test_duration_days(daily_traffic, sample_size_per_group):
    total_sample = sample_size_per_group * 2
    days = total_sample / daily_traffic
    return days

traffic = 100_000
sample = 1_000_000
days = test_duration_days(traffic, sample)
print(f"Длительность теста: {days:.1f} дней")

Последовательное тестирование

Вместо фиксированного размера, останавливаем тест при достаточной статистической уверенности:

from scipy.stats import chi2_contingency

def sequential_test(control_conv, control_trials, treat_conv, treat_trials):
    table = [[control_conv, control_trials - control_conv],
             [treat_conv, treat_trials - treat_conv]]
    
    chi2, p_value, dof, expected = chi2_contingency(table)
    return p_value < 0.05

Полный калькулятор

class ABTestCalculator:
    def __init__(self, baseline, min_effect, alpha=0.05, power=0.80):
        self.baseline = baseline
        self.min_effect = min_effect
        self.alpha = alpha
        self.power = power
    
    def calculate_sample_size(self):
        z_alpha = stats.norm.ppf(1 - self.alpha/2)
        z_beta = stats.norm.ppf(self.power)
        
        p1 = self.baseline
        p2 = self.baseline + self.min_effect
        
        numerator = (z_alpha + z_beta) ** 2
        variance = p1 * (1 - p1) + p2 * (1 - p2)
        
        n = 2 * numerator * variance / (p2 - p1) ** 2
        return math.ceil(n)
    
    def calculate_test_duration(self, daily_traffic):
        n = self.calculate_sample_size()
        return n / daily_traffic
    
    def report(self, daily_traffic):
        n = self.calculate_sample_size()
        days = self.calculate_test_duration(daily_traffic)
        
        print(f"На группу: {n:,}")
        print(f"Всего: {n*2:,}")
        print(f"Дней при {daily_traffic:,}/день: {days:.1f}")

calc = ABTestCalculator(baseline=0.10, min_effect=0.02)
calc.report(daily_traffic=100_000)

Практические рекомендации

Определение минимального эффекта:

  • E-commerce: базовая конверсия 3%, эффект +0.1%
  • Subscription: baseline churn 5%, минимум -1%

Типичные ошибки:

  • Игнорирование сезонности и временных факторов
  • Множественные тесты без коррекции
  • Остановка теста при благоприятных результатах
  • Неправильная оценка базовой метрики

Заключение

Размер выборки зависит от силы эффекта, требуемой мощности и уровня значимости. Правильный расчёт гарантирует, что тест имеет достаточно данных для принятия обоснованного решения.