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

Какие знаешь методы снижения дисперсии?

2.7 Senior🔥 81 комментариев
#A/B тестирование#Статистика и математика

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

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

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

Методы снижения дисперсии в A/B тестировании

Дисперсия (variance) в контексте A/B тестирования — это естественная вариативность результатов из-за случайности. Высокая дисперсия означает, что нужно больше пользователей для получения статистически значимого результата, что требует больше времени и денег. Рассмотрю методы для её снижения.

1. Стратификация (Stratification)

Суть: разделить аудиторию на подгруппы (страты) до распределения в тест и контроль, чтобы каждая страта была представлена в обоих группах поровну.

Пример:

Общая аудитория:
├─ New users (зарегистрировались < 7 дней): 20%
├─ Active users (использовали > 5 раз в неделю): 30%
├─ At-risk users (не активны 2+ недели): 20%
└─ Dormant users (не активны 1+ месяца): 30%

Без стратификации:
Тест группа может случайно получить 25% new users, контроль 15%
→ Это увеличивает дисперсию

Со стратификацией:
Каждая группа получит ровно 20% new users, 30% active и т.д.
→ Это снижает дисперсию на ~10-30%

Реализация:

WITH user_strata AS (
  SELECT 
    user_id,
    CASE 
      WHEN DATEDIFF(day, created_at, GETDATE()) < 7 THEN 'new'
      WHEN last_activity_date >= DATEADD(day, -7, GETDATE()) THEN 'active'
      WHEN last_activity_date >= DATEADD(day, -30, GETDATE()) THEN 'at_risk'
      ELSE 'dormant'
    END AS user_stratum
  FROM users
),
stratified_assignment AS (
  SELECT 
    user_id,
    user_stratum,
    CASE 
      WHEN RAND() < 0.5 THEN 'test' 
      ELSE 'control' 
    END AS group_assignment
  FROM user_strata
)
SELECT * FROM stratified_assignment;

2. CUPED (Controlled Experiment Using Pre-Experiment Data)

Суть: использовать исторические данные пользователя до эксперимента как контрольную переменную, чтобы уменьшить шум.

Как это работает:

Обычный расчёт:

metric_diff = avg(test_group) - avg(control_group)
Variance = Var(test) + Var(control)  [высокая]

С CUPED:

adjusted_metric = current_metric - historical_metric * correlation_coefficient
Variance снижается на (1 - r²), где r = корреляция

Пример:

Есть гипотеза, что новый алгоритм рекомендаций увеличит engagement (likes/day).

Пользователь в тесте:

  • Historical avg (последние 30 дней): 5 лайков/день
  • During test: 6.5 лайков/день
  • Raw lift: 1.5 лайка/день

Пользователь в контроле:

  • Historical avg: 5 лайков/день
  • During test: 5.8 лайков/день
  • Raw lift: 0.8 лайка/день

Сырая разница: 1.5 - 0.8 = 0.7 лайка/день

С CUPED (если исторические данные сильно коррелируют с текущими, r=0.9):

  • CUPED metric test = 6.5 - 5 * 0.9 = 1.6
  • CUPED metric control = 5.8 - 5 * 0.9 = 1.3
  • Adjusted diff = 1.6 - 1.3 = 0.3 (меньше дисперсия!)
import numpy as np

def cuped_metric(current, historical, correlation):
    """Adjust metric using CUPED method"""
    return current - historical * correlation

# Example data
current_test = np.array([6.5, 7.2, 5.8, 6.9])
historical_test = np.array([5.0, 5.5, 5.2, 5.8])
corr = 0.85

adjusted = cuped_metric(current_test, historical_test, corr)
print(f"Variance reduced by {1 - corr**2:.1%}")

3. Variance Reduction по метрикам (Choosing the Right Metric)

Суть: некоторые метрики имеют низкую дисперсию, некоторые высокую. Выбор правильной метрики снизит время теста.

Пример:

Гипотеза: новый CTA "Купить сейчас" увеличит конверсии.

Вариант A (высокая дисперсия):

  • Метрика: Revenue ($)
  • Дисперсия высокая (клиенты платят по-разному)
  • Needed sample: 50,000 юзеров

Вариант B (низкая дисперсия):

  • Метрика: Click Rate (% кликнув на CTA)
  • Дисперсия низкая (клик либо есть, либо нет)
  • Needed sample: 5,000 юзеров

Вариант C (баланс):

  • Метрика: Orders per user (не revenue, а количество заказов)
  • Средняя дисперсия
  • Needed sample: 10,000 юзеров

Вывод: выбирать метрику, которая:

  1. Релевантна бизнесу
  2. Имеет низкую дисперсию
  3. Может быть собрана быстро

4. Увеличение размера выборки (Power Analysis)

Суть: рассчитать минимально необходимый размер выборки заранее.

from scipy.stats import norm

def required_sample_size(baseline_rate, min_detectable_effect, alpha=0.05, power=0.8):
    """
    Рассчитать размер выборки для A/B теста
    baseline_rate: текущий率 конверсии
    min_detectable_effect: минимальный lift, который хотим обнаружить (e.g., 0.05 = 5%)
    alpha: вероятность Type I error (false positive) - обычно 0.05
    power: вероятность обнаружить эффект, если он есть - обычно 0.8
    """
    
    z_alpha = norm.ppf(1 - alpha/2)  # Two-tailed
    z_beta = norm.ppf(power)
    
    # Effect size (Cohen's h)
    h = 2 * (np.arcsin(np.sqrt(baseline_rate)) - 
             np.arcsin(np.sqrt(baseline_rate + min_detectable_effect)))
    
    # Required sample per group
    n_per_group = 2 * ((z_alpha + z_beta) / h) ** 2
    
    return n_per_group

# Example: baseline CR 10%, want to detect 15% lift (1.5% absolute)
baseline = 0.10
effect = 0.015
n = required_sample_size(baseline, effect)
print(f"Required {n:,.0f} users per group")
print(f"Total: {2*n:,.0f} users")
print(f"If 10k users/day, need ~{2*n/10000:.1f} days")

5. Sequential Testing (Peek-able Designs)

Суть: вместо фиксированного размера выборки, смотреть на результаты во время теста и остановить, когда достигли статистической значимости.

Преимущество: можешь остановить тест раньше, если результат очевидный.

Процесс:

День 1: 1,000 юзеров - недостаточно данных
День 2: 2,000 юзеров - всё ещё не значимо
День 3: 3,000 юзеров - p-value = 0.04 ✓ СТОП!
(вместо планируемых 5,000 юзеров)

Предупреждение: нужно правильно рассчитать alpha level, чтобы избежать false positives. Используй Bonferroni correction или другие методы.

6. Matching (Propensity Score Matching)

Суть: для каждого пользователя в тесте найти подобного пользователя в контроле, чтобы уменьшить confounding variables.

Пример:

Тестируем новый UI для платёжной формы. Но есть confound: более опытные пользователи (которые ввели платёж 10+ раз) уже хорошо ориентируются в текущем UI.

Без matching:

  • Test group случайно получит 25% опытных
  • Control group случайно получит 15% опытных
  • → Дисперсия высокая

С matching:

  • Каждый опытный пользователь в тесте паруется с опытным в контроле
  • Каждый новичок в тесте паруется с новичком в контроле
  • → Дисперсия снижена

7. Bayesian Methods

Суть: вместо frequentist подхода (p-values), использовать Bayesian inference с prior информацией.

Преимущество: можешь использовать исторические данные как prior, что снижает дисперсию.

Пример:

from scipy.stats import beta

# Historical data: 1000 tests, avg lift 5%
prior_alpha = 1000 * 0.05
prior_beta = 1000 * (1 - 0.05)

# Current test: 100 conversions из 1500
current_conversions = 100
current_total = 1500

# Posterior distribution
posterior = beta(prior_alpha + current_conversions, 
                 prior_beta + current_total - current_conversions)

# Credible interval
print(f"95% credible interval: [{posterior.ppf(0.025):.3f}, {posterior.ppf(0.975):.3f}]")

8. Machine Learning для прогнозирования метрик

Суть: использовать ML модель для прогнозирования, какой будет метрика, на основе признаков пользователя. Потом использовать остатки (residuals) от модели как метрику теста.

Эффект: может снизить дисперсию на 20-50%.

Сравнение методов по эффективности

МетодСнижение дисперсииСложностьПрименимость
Стратификация10-30%НизкаяВсегда
CUPED20-40%СредняяКогда есть historical data
Правильная метрика30-70%СредняяВсегда
Sequential testingN/A (ускоряет)ВысокаяКогда возможно
Matching15-25%ВысокаяСпецифичные cases
Bayesian20-50%ВысокаяКогда есть strong prior
ML prediction20-50%Очень высокаяБольшие датасеты

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

Большинство компаний применяют:

  1. Стратификация (простая, всегда помогает)
  2. Правильный выбор метрики (выбрать метрику с низкой дисперсией)
  3. Power analysis (рассчитать нужный sample size заранее)
  4. CUPED (если есть исторические данные)

Эта комбинация обычно снижает время тестирования на 30-50%.

Заключение

Снижение дисперсии — это критический навык для Product Analyst'а, так как это позволяет компании быстрее принимать решения на основе тестов. Выбор метода зависит от конкретной ситуации, но начать стоит со стратификации и правильного выбора метрики — это даст быстрый выигрыш без сложности.