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

Как проводить анализ значимости выборки, если данные не прошли тест на нормальность?

3.0 Senior🔥 61 комментариев
#A/B тестирование#Метрики и аналитика

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

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

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

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

Это продвинутый статистический вопрос. Расскажу, как я подходу к нему как к PM, который понимает базовые принципы статистики.

Понимание проблемы

Почему нормальность важна: Много классических тестов (t-test, ANOVA) предполагают нормальное распределение. Если данные не нормальны, результаты могут быть некорректны.

Когда это возникает в практике PM:

  • A/B тест конверсии: она часто распределена ненормально (0 или 1)
  • Времени ответа: обычно skewed right (длинный хвост больших значений)
  • Среднего чека: тоже часто ненормально

Подход 1: Непараметрические тесты

Идея: Не требуют предположения о нормальности.

Основные тесты:

ПараметрическийНепараметрическийКогда использовать
t-testMann-Whitney U testСравнение 2 групп
ANOVAKruskal-WallisСравнение 3+ групп
Pearson correlationSpearman rank correlationКорреляция

Пример: A/B тест конверсии

  • Вместо t-test используем Mann-Whitney U
  • Это более консервативный, но надёжный подход

Подход 2: Трансформация данных

Идея: Преобразовать данные так, чтобы они стали нормальными.

Методы:

  • Log transformation: Если данные skewed, логарифм часто помогает

    • Y_transformed = log(Y)
    • Особенно полезно для times и revenue
  • Square root transformation: Для count data

    • Y_transformed = sqrt(Y)
  • Box-Cox transformation: Автоматически найти оптимальную трансформацию

Пример: Средний чек клиентов: $10, $15, $50, $100, $500 (ненормально, skewed) После log transform: log(10), log(15), ... → более нормально

Подход 3: Увеличение размера выборки

Центральная предельная теорема (Central Limit Theorem):

  • Если выборка достаточно большая (n > 30-50), даже ненормальные данные при усреднении дают нормальное распределение

Практика:

  • A/B тест с 10,000 пользователей в группе часто дает достаточно нормальные средние
  • При меньших выборках (n < 100) нужна осторожность

Подход 4: Bootstrap и пермутационные тесты

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

Bootstrap:

  1. Из выборки случайно берём подвыборки с replacement
  2. Вычисляем статистику (среднее, медиан) для каждой подвыборки
  3. Смотрим на распределение этих статистик
  4. Считаем confidence interval

Преимущества:

  • Не нужно предположение о нормальности
  • Работает с любыми данными

Пример кода (Python):

import numpy as np

def bootstrap_ci(data, iterations=10000):
    bootstraps = []
    n = len(data)
    for _ in range(iterations):
        # Берём случайную выборку
        sample = np.random.choice(data, size=n, replace=True)
        bootstraps.append(np.mean(sample))
    
    # 95% confidence interval
    ci_lower = np.percentile(bootstraps, 2.5)
    ci_upper = np.percentile(bootstraps, 97.5)
    return ci_lower, ci_upper

Подход 5: Permutation test

Идея: Проверить, случайна ли разница между группами.

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

  1. У нас есть группа A и группа B
  2. Вычисляем разницу в means
  3. Случайно перемешиваем метки (A vs B) много раз
  4. Для каждой перестановки вычисляем разницу
  5. Если реальная разница в top 5% — результат значимый

Преимущество: Без предположений о распределении.

Мой практический подход как PM

Шаг 1: Проверка нормальности

Тесты:
- Shapiro-Wilk test (для малых выборок)
- Kolmogorov-Smirnov test
- Q-Q plot (визуальная проверка)

Шаг 2: Выбор метода

Если нормальность? → Да → t-test
                  → Нет:
                    - n > 100? → t-test (CLT работает)
                    - n < 100? → Mann-Whitney U или bootstrap

Шаг 3: Практический пример — A/B тест конверсии

Данные:

  • Group A: 1000 юзеров, 150 конвертировались (15%)
  • Group B: 1000 юзеров, 180 конвертировались (18%)
  • Разница: +3 процентных пункта

Вопрос: Значима ли разница или случайность?

Решение:

  1. Данные бинарные (0 или 1) — явно ненормальны
  2. Но n=1000, по CLT можем использовать z-test или t-test
  3. Или используем exact binomial test (более консервативно)
  4. Результат: p-value = 0.02 → значимо на уровне 0.05

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

Малая выборка (n < 30):

  • Используй Mann-Whitney U (непараметрический)
  • Или bootstrap
  • Помни, что p-value может быть ненадёжным

Средняя выборка (30 < n < 100):

  • Проверь Q-Q plot
  • Если явно ненормально → Mann-Whitney U
  • Если близко к нормальности → t-test OK

Большая выборка (n > 100):

  • CLT работает → t-test OK даже если ненормально
  • Но всё равно проверь Q-Q plot на экстремальные skew

Практический совет: Используй несколько методов и смотри, консистентны ли результаты:

  • t-test
  • Mann-Whitney U
  • Bootstrap

Если все три дают похожий результат (p < 0.05 или p > 0.05), можешь быть уверен.

Инструменты

Python:

from scipy import stats

# Mann-Whitney U test
stat, p_value = stats.mannwhitneyu(group_a, group_b)
print(f"p-value: {p_value}")

# Bootstrap confidence interval
from scipy.stats import bootstrap
ci = bootstrap((group_a,), np.mean, confidence_level=0.95)
print(f"95% CI: {ci}")

Online калькуляторы:

  • AB Testguide.com
  • Evan Miller's A/B test calculator

Ошибки, которых избегаю

  1. Не игнорирую ненормальность — всегда проверю
  2. Не множу гипотезы — делаю One A/B test, не 10 одновременно (множественное тестирование → inflated p-values)
  3. Не полагаюсь на p-value один — смотрю на effect size и confidence intervals
  4. Не путаю корреляцию с причинностью — даже если есть статистическая значимость

Вывод

Ненормальные данные — не проблема, если выбрать правильный метод:

  • Непараметрические тесты — самый простой способ
  • Bootstrap — самый гибкий
  • Трансформация — когда возможна
  • Большие выборки — опираются на CLT

Как PM, я не глубоко погружаюсь в статистику, но понимаю основные принципы и консультируюсь с data scientist'ами. Главное — убедиться, что результаты A/B теста надёжны.