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

Как рассчитывается дисперсия для метрики конверсии нажатия на кнопку?

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

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

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

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

Как рассчитывается дисперсия для метрики конверсии нажатия на кнопку

Дисперсия (variance) — это фундаментальная концепция в статистике. Для Product Analyst'а важно понимать как её рассчитывать, почему она нужна, и как использовать для A/B тестов.

Что такое дисперсия: интуиция

Дисперсия (Variance, σ²) — мера разброса данных относительно среднего значения.

Простой пример:

Кнопка A:
- День 1: 5% конверсия
- День 2: 5% конверсия
- День 3: 5% конверсия
- День 4: 5% конверсия
- День 5: 5% конверсия
Дисперсия: 0 (нет разброса, очень стабильно)

Кнопка B:
- День 1: 2% конверсия
- День 2: 8% конверсия
- День 3: 3% конверсия
- День 4: 7% конверсия
- День 5: 5% конверсия
Дисперсия: ВЫСОКАЯ (очень нестабильно)

Средняя конверсия одинаковая (5%), но Кнопка A более надёжна!

Формула дисперсии для бинарной переменной

Конверсия нажатия на кнопку — это бинарная переменная:

  • Пользователь нажал (1) или нет (0)

Дисперсия для бинарной переменной:

σ² = p × (1 - p)

где:
p = доля успешных (конверсия)
(1 - p) = доля неудачных

Пример расчета:

Если конверсия p = 5% = 0.05:

σ² = 0.05 × (1 - 0.05)
σ² = 0.05 × 0.95
σ² = 0.0475

Standard Deviation (σ) = √σ² = √0.0475 = 0.218

Это значит средний разброс ±21.8 ppt от средней

Почему дисперсия p × (1-p)?

Доказательство через базовую статистику:

Для бинарной переменной X (0 или 1):

  • Mean (μ) = p
  • Variance (σ²) = E[X²] - (E[X])²

Вычисляем:

E[X] = 0×(1-p) + 1×p = p
E[X²] = 0²×(1-p) + 1²×p = p

σ² = E[X²] - (E[X])²
σ² = p - p²
σ² = p(1 - p)

Вывод: формула σ² = p(1-p) —это математический факт для бинарных данных.

Практический расчет для метрики

Сценарий: A/B тест кнопок

Button A:
- Показана: 1000 пользователей
- Нажата: 50 пользователей
- Конверсия p_A = 50 / 1000 = 0.05 = 5%

Button B:
- Показана: 1000 пользователей
- Нажата: 70 пользователей
- Конверсия p_B = 70 / 1000 = 0.07 = 7%

Дисперсии:
σ²_A = 0.05 × 0.95 = 0.0475
σ²_B = 0.07 × 0.93 = 0.0651

Standard Errors (для выборки):
SE_A = √(σ²_A / n_A) = √(0.0475 / 1000) = 0.0069
SE_B = √(σ²_B / n_B) = √(0.0651 / 1000) = 0.0081

Дисперсия и стандартная ошибка

Это НЕ одно и то же!

σ² = Variance (дисперсия в генеральной совокупности)
SE = Standard Error (стандартная ошибка ВЫБОРКИ)

SE = σ / √n = √(p(1-p) / n)

Почему SE меньше σ?

  • При большей выборке оценка становится точнее
  • √n растёт с размером выборки
  • Поэтому SE уменьшается
-- SQL для расчета variance и SE

SELECT
    'Button A' as button,
    COUNT(*) as total_shown,
    SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) as clicks,
    
    -- Конверсия
    ROUND(100.0 * SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*), 2) as conversion_pct,
    
    -- Дисперсия
    ROUND(
        (SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*)) * 
        (1 - SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*)),
        6
    ) as variance,
    
    -- Standard Error
    ROUND(
        SQRT(
            (SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*)) * 
            (1 - SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*)) / 
            COUNT(*)
        ),
        6
    ) as standard_error,
    
    -- 95% Confidence Interval
    ROUND(100.0 * SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*), 2) as ci_lower_bound,
    ROUND(100.0 * SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*) + 
          1.96 * SQRT((SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*)) * 
          (1 - SUM(CASE WHEN clicked = 1 THEN 1 ELSE 0 END) / COUNT(*)) / COUNT(*)), 2) as ci_upper_bound
FROM button_clicks
WHERE test_date >= DATE_SUB(TODAY(), INTERVAL 7 DAY)
GROUP BY button

Результат:

Button | Conversion | Variance | SE     | 95% CI Lower | 95% CI Upper
--------|-----------|----------|--------|--------------|-------------
A       | 5.0%      | 0.0475   | 0.0069 | 4.86%        | 5.14%
B       | 7.0%      | 0.0651   | 0.0081 | 6.84%        | 7.16%

Дисперсия в статистических тестах

Chi-square test требует дисперсию:

Напоминаю формулу Chi-square:

χ² = Σ [(Observed - Expected)² / Expected]

Expected = (row_total × col_total) / grand_total

Это как раз работает с дисперсией!

Z-test для пропорций требует дисперсию:

Z = (p_A - p_B) / √(p(1-p) × (1/n_A + 1/n_B))

Знаменатель = корень из дисперсии!

Power анализ требует дисперсию:

from scipy.stats import norm

# Для расчета требуемого размера выборки:

baseline_p = 0.05  # Baseline conversion 5%
min_effect = 0.02  # Хотим поймать 2 ppt effect
alpha = 0.05       # Type I error
beta = 0.20        # Type II error (power = 80%)

variance = baseline_p * (1 - baseline_p)  # ← дисперсия!

z_alpha = norm.ppf(1 - alpha/2)
z_beta = norm.ppf(1 - beta)

# Требуемый размер выборки в каждой группе
n = (z_alpha + z_beta)**2 * variance * 2 / (min_effect**2)

print(f"Требуется {int(n)} пользователей в каждой группе")
# Результат: 2649 пользователей в каждой группе

График: как дисперсия меняется с конверсией

Дисперсия p(1-p) максимальна при p=50%:

    Variance
        ▲
    0.25│          ╱╲
        │        ╱    ╲
    0.2 │      ╱        ╲
        │    ╱            ╲
    0.15│  ╱                ╲
        │╱                    ╲
     0  │─────────────────────── p
        0    0.25   0.5   0.75   1.0
        
Примеры:
- p = 1% (0.01): σ² = 0.01 × 0.99 = 0.0099 (низкая дисперсия)
- p = 5% (0.05): σ² = 0.05 × 0.95 = 0.0475
- p = 50% (0.50): σ² = 0.50 × 0.50 = 0.2500 (максимум!)
- p = 95% (0.95): σ² = 0.95 × 0.05 = 0.0475
- p = 99% (0.99): σ² = 0.99 × 0.01 = 0.0099 (низкая дисперсия)

Практический вывод:
- Экстремальные конверсии (очень низкие или высокие) имеют НИЗКУЮ дисперсию
- Средние конверсии (~50%) имеют ВЫСОКУЮ дисперсию
- Это значит экспериментам на 50% нужны БОЛЬШИЕ выборки

Пример: расчет дисперсии для разных кнопок

# Python пример

import math

def calculate_conversion_variance(clicks, total_shown):
    """Рассчитать дисперсию для конверсии нажатия"""
    p = clicks / total_shown
    variance = p * (1 - p)
    std_dev = math.sqrt(variance)
    std_error = std_dev / math.sqrt(total_shown)
    
    # 95% confidence interval
    ci_lower = (p - 1.96 * std_error) * 100
    ci_upper = (p + 1.96 * std_error) * 100
    
    return {
        'conversion': p * 100,
        'variance': variance,
        'std_dev': std_dev,
        'std_error': std_error,
        'ci_lower': ci_lower,
        'ci_upper': ci_upper
    }

# Тестируем разные кнопки

button_a = calculate_conversion_variance(clicks=50, total_shown=1000)
button_b = calculate_conversion_variance(clicks=70, total_shown=1000)
button_c = calculate_conversion_variance(clicks=500, total_shown=1000)

for button_name, metrics in [('A', button_a), ('B', button_b), ('C', button_c)]:
    print(f"Button {button_name}:")
    print(f"  Conversion: {metrics['conversion']:.1f}%")
    print(f"  Variance: {metrics['variance']:.4f}")
    print(f"  Std Dev: {metrics['std_dev']:.4f}")
    print(f"  95% CI: [{metrics['ci_lower']:.2f}%, {metrics['ci_upper']:.2f}%]")
    print()

# Output:
# Button A:
#   Conversion: 5.0%
#   Variance: 0.0475
#   Std Dev: 0.2179
#   95% CI: [3.84%, 6.16%]
#
# Button B:
#   Conversion: 7.0%
#   Variance: 0.0651
#   Std Dev: 0.2551
#   95% CI: [5.84%, 8.16%]
#
# Button C:
#   Conversion: 50.0%
#   Variance: 0.2500
#   Std Dev: 0.5000
#   95% CI: [46.90%, 53.10%]  ← НАМНОГО шире! Нужна большая выборка

Практическое применение: определение размера выборки

Дисперсия критична для определения когда остановить тест:

Нужно минимум n = (z_alpha/2 + z_beta)² × σ² × 2 / δ²

где:
- σ² = p(1-p) = дисперсия
- δ = minimum detectable effect
- z_alpha = 1.96 (для 95% CI)
- z_beta = 0.84 (для 80% power)

Пример:
Хотим детектировать +2 ppt эффект (0.02) на базе 5% (p=0.05):

σ² = 0.05 × 0.95 = 0.0475
n = (1.96 + 0.84)² × 0.0475 × 2 / (0.02)²
n = (2.80)² × 0.0475 × 2 / 0.0004
n = 7.84 × 0.0475 × 2 / 0.0004
n = 0.7448 / 0.0004
n = 1862

Нужно минимум 1862 пользователя в каждой группе = 3724 всего

Чеклист: правильный расчет дисперсии

  • Определена что такое "конверсия" (what counts as click)
  • Собраны данные (clicks и total_shown)
  • Рассчитана p = clicks / total_shown
  • Рассчитана σ² = p × (1-p)
  • Рассчитана SE = √(σ² / n)
  • Рассчитан 95% CI = p ± 1.96 × SE
  • Интерпретирована CI (есть ли overlap между группами?)
  • Проверена статистическая значимость (p-value < 0.05?)

Главный вывод: Дисперсия = p(1-p) для бинарных метрик. Она нужна для статистических тестов, confidence intervals, и определения размера выборки. Без правильного расчета дисперсии ты не сможешь делать валидные A/B тесты.