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

Что такое ratio metrics и как их правильно анализировать в A/B тестах?

1.7 Middle🔥 181 комментариев
#SQL и базы данных#Метрики продукта

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

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

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

Ratio Metrics в A/B тестах: определение и анализ

Ratio metrics (метрики-отношения) — это метрики, рассчитываемые как отношение одного значения к другому. Например: средний чек, CTR (Click-Through Rate), конверсия, ARPU. Они основаны на делении числителя на знаменатель и требуют специального подхода при анализе в A/B тестах, так как обладают нелинейным распределением.

Типы ratio metrics

Простые отношения:

  • Конверсия (conversions / sessions)
  • CTR (clicks / impressions)
  • ARPU (revenue / users)
  • Средний чек (total_revenue / orders)

Составные отношения:

  • Revenue per session = total_revenue / sessions
  • LTV / CAC (lifetime value / customer acquisition cost)
  • Engagement rate = active_users / total_users

Почему ratio metrics опасны в A/B тестах

Проблема 1: Ненормальное распределение

Обычные метрики (количество кликов) имеют нормальное распределение при большом размере выборки (CLT). Ratio metrics нарушают это предположение.

Конверсия = 320 / 10000 = 0.032 (3.2%)

Среднее значение может быть 3.2%, но распределение НЕ нормально!
Это распределение, ограниченное интервалом [0, 1] для конверсии.

Проблема 2: Различные вариансы при одинаковых значениях

Вариант A: 1000 заказов из 100000 посещений = 1.0% конверсия
Вариант B: 100 заказов из 10000 посещений = 1.0% конверсия

Дисперсия разная! Вариант B более волатилен.

Проблема 3: Корреляция числителя и знаменателя

Если числитель и знаменатель коррелированы, стандартная ошибка занижается.

Методы анализа ratio metrics

Метод 1: Дельта-метод (Delta Method) — классический подход

Использует разложение Тейлора для аппроксимации дисперсии отношения.

Для ratio X/Y:

Var(X/Y) ≈ (1/μ_Y)² * Var(X) + (μ_X/μ_Y²)² * Var(Y) - 2*(μ_X/μ_Y³) * Cov(X,Y)

Когда использовать: когда числитель и знаменатель независимы и распределения близки к нормальным.

Пример в Python:

import numpy as np
from scipy import stats

# Данные варианта A
conversions_a = np.array([1, 0, 1, 0, 1, ...])  # 1 = конверсия
sessions_a = len(conversions_a)  # 10000

# Данные варианта B
conversions_b = np.array([1, 1, 0, 1, ...])
sessions_b = len(conversions_b)  # 10000

# Конверсии
conv_a = conversions_a.sum() / sessions_a
conv_b = conversions_b.sum() / sessions_b

# Дисперсия конверсии (Bernoulli)
var_a = conv_a * (1 - conv_a) / sessions_a
var_b = conv_b * (1 - conv_b) / sessions_b

# Стандартная ошибка разницы
se_diff = np.sqrt(var_a + var_b)

# t-статистика
t_stat = (conv_a - conv_b) / se_diff
p_value = 2 * (1 - stats.t.cdf(abs(t_stat), df=sessions_a + sessions_b - 2))

Метод 2: Bootstrap (Бутстрэп) — универсальный подход

Пересэмплирование из исходных данных для получения эмпирического распределения ratio.

def bootstrap_ratio_ci(data_a, data_b, n_iterations=10000, ci=0.95):
    """
    Вычисляет доверительный интервал для разницы ratio метрик
    
    data_a, data_b: массивы вида [numbers, totals]
    """
    ratios_diff = []
    
    for _ in range(n_iterations):
        # Случайная выборка с возвращением
        sample_a = np.random.choice(len(data_a), size=len(data_a), replace=True)
        sample_b = np.random.choice(len(data_b), size=len(data_b), replace=True)
        
        ratio_a = data_a[sample_a].sum() / len(sample_a)
        ratio_b = data_b[sample_b].sum() / len(sample_b)
        
        ratios_diff.append(ratio_a - ratio_b)
    
    # Доверительный интервал
    lower = np.percentile(ratios_diff, (1 - ci) / 2 * 100)
    upper = np.percentile(ratios_diff, (1 + ci) / 2 * 100)
    
    return lower, upper

# Использование
ci_lower, ci_upper = bootstrap_ratio_ci(conversions_a, conversions_b)
print(f"95% CI: [{ci_lower:.4f}, {ci_upper:.4f}]")

Когда использовать: всегда, когда есть сомнения в предположениях дельта-метода. Bootstrap работает для любого распределения.

Метод 3: Линеаризация (Linearization) — для ARPU и сложных метрик

Преобразуем ratio метрику в линейную комбинацию.

ARPU = Revenue / Users

Для каждого пользователя i:
  arpu_i = revenue_i / users
  
Преобразуем:
  arpu_i ≈ (revenue_i - μ_revenue/μ_users * users_i) / μ_users

Теперь это линейная комбинация — можно использовать t-тест!

Пример для ARPU:

-- Расчёт ARPU по пользователю
WITH user_stats AS (
    SELECT 
        user_id,
        SUM(purchase_amount) as total_revenue,
        COUNT(DISTINCT session_id) as sessions,
        @global_mean_revenue / @global_mean_sessions as arpu_ratio
    FROM transactions
    WHERE variant IN ('A', 'B')
    GROUP BY user_id
)
SELECT 
    variant,
    AVG(total_revenue - arpu_ratio * sessions) as linearized_arpu,
    STDDEV(total_revenue - arpu_ratio * sessions) / SQRT(COUNT(*)) as se
FROM user_stats
GROUP BY variant;

Правильный анализ в SQL

-- Данные для A/B теста на ratio metrics
WITH variant_data AS (
    SELECT 
        variant,
        COUNT(DISTINCT user_id) as users,
        COUNT(CASE WHEN purchase_made = 1 THEN 1 END) as purchases,
        SUM(revenue) as total_revenue,
        COUNT(CASE WHEN purchase_made = 1 THEN 1 END)::FLOAT / 
        COUNT(DISTINCT user_id) as conversion_rate,
        SUM(revenue)::FLOAT / COUNT(DISTINCT user_id) as arpu
    FROM events
    WHERE test_id = @test_id
    GROUP BY variant
),
variance_calc AS (
    SELECT 
        variant,
        users,
        purchases,
        conversion_rate,
        arpu,
        -- Дисперсия конверсии (Bernoulli)
        conversion_rate * (1 - conversion_rate) / users as conv_variance,
        -- Дисперсия ARPU
        variance(revenue) / users as arpu_variance
    FROM variant_data
)
SELECT 
    *,
    -- Стандартная ошибка
    SQRT(2 * conv_variance) as conv_se,
    SQRT(2 * arpu_variance) as arpu_se
FROM variance_calc;

Критические ошибки при анализе ratio metrics

❌ Ошибка 1: Использовать обычный t-тест на конверсию

Конверсия имеет биномиальное распределение, не нормальное. Нужен точный Fisher test или chi-square.

-- Неправильно
SELECT 
    conversion_a,
    conversion_b,
    (conversion_a - conversion_b) / SQRT(var_a + var_b) as t_stat;

-- Правильно
-- Использовать chi-square для таблицы сопряженности 2x2

❌ Ошибка 2: Игнорировать корреляцию числителя и знаменателя

Если числитель и знаменатель сильно коррелированы, стандартная ошибка будет занижена, и you получите ложные положительные результаты.

❌ Ошибка 3: Анализировать ratio до достижения minimum sample size

Для ratio metrics нужен БОЛЬШИЙ размер выборки, чем для обычных метрик, потому что дисперсия выше.

# Минимальный размер выборки для ratio metrics примерно в 1.5-2 раза больше
# чем для обычных метрик с тем же эффектом
min_sample_size_ratio = min_sample_size_linear * 1.5

❌ Ошибка 4: Анализировать ratio в наивной стратификации

Если у вас есть стратификация по устройству, странам и т.д., нужно анализировать ratio для каждой страты отдельно или использовать CUPED/CUPAC.

Best practices для Product Analysts

1. Используйте инструменты, которые "знают" о ratio metrics

  • Statsig, Split.io, LaunchDarkly — встроенная поддержка
  • Mixpanel, Amplitude — встроенная статистика
  • Python: statsmodels, scipy, bootstrapped

2. Визуализируйте распределение, не только среднее

import matplotlib.pyplot as plt

plt.hist([ratio_a], bins=50, alpha=0.5, label='Variant A')
plt.hist([ratio_b], bins=50, alpha=0.5, label='Variant B')
plt.xlabel('Конверсия')
plt.legend()
plt.show()

# Убедитесь, что хвосты не слишком тяжелые
# и нет экстремальных выбросов

3. Предоставляйте отчет в формате:

  • Точечная оценка разницы
  • 95% доверительный интервал
  • Относительный эффект (%)
  • P-value
  • Статистическая мощность (1 - β)
  • Размер выборки
VARIANT A: Conversion 3.2% [3.0% - 3.4%]
VARIANT B: Conversion 3.5% [3.3% - 3.7%]

Difference: +0.3% (+9.4% relative lift)
95% CI: [0.1%, 0.5%]
p-value: 0.012 ✓ (significant at α=0.05)
Power: 88%
n_a = 50000, n_b = 50000

Итог

Ratio metrics требуют более аккуратного анализа, чем обычные метрики. Главное правило: используйте bootstrap или дельта-метод вместо наивного t-теста. Для ARPU и сложных ratio используйте линеаризацию. И всегда проверяйте предположения дельта-метода перед его применением. В современных A/B тестирования инструментах эти методы уже встроены, но Product Analyst должен понимать, что происходит под капотом.