Коротко: Нормальное распределение (распределение Гаусса) — это симметричный колокол, где около 68% значений лежат в пределах одного стандартного отклонения от среднего, 95% — двух и 99.7% — трёх (правило 68-95-99.7). Проверять нормальность нужно, чтобы выбрать корректный статистический тест: t-тест и линейная регрессия опираются на неё в малых выборках. Смотрят на данные тремя способами — гистограмма, QQ-plot и формальный тест (Шапиро-Уилка на выборках до ~5000, Колмогорова-Смирнова с оговорками). Если данные не нормальны — помогают лог-трансформация, непараметрические тесты (Манна-Уитни) или бутстрап.
Что такое нормальное распределение и правило 68-95-99.7?
Нормальное распределение задаётся двумя числами: средним mu (центр колокола) и стандартным отклонением sigma (ширина). Плотность симметрична относительно среднего, а среднее, медиана и мода совпадают. Чем больше sigma, тем более пологий и растянутый колокол.
Правило 68-95-99.7 — это доля наблюдений, попадающих в интервалы вокруг среднего:
| Интервал | Доля наблюдений | Что это значит |
|---|---|---|
mu ± 1·sigma | ~68.3% | Две трети всех значений |
mu ± 2·sigma | ~95.4% | Почти все обычные значения |
mu ± 3·sigma | ~99.7% | За пределами — редкие выбросы (0.3%) |
Пример с числами. Пусть время загрузки страницы распределено нормально со средним 800 мс и стандартным отклонением 100 мс. Тогда:
- 68% пользователей увидят страницу за 700–900 мс.
- 95% уложатся в 600–1000 мс.
- Значение 1100 мс (это
mu + 3·sigma) встретится примерно у 0.15% пользователей — это уже хвост.
Именно на правиле трёх сигм строится классическое определение выброса: всё, что дальше трёх стандартных отклонений от среднего, помечают как аномалию. Работает это только если данные действительно близки к нормальным — для скошенных распределений (выручка, время сессии) правило трёх сигм врёт, и лучше опираться на медиану и перцентили вместо среднего.
Почему нормальность важна для выбора статистического теста?
Многие классические методы выведены в предположении, что данные (или ошибки модели) нормальны. Если предположение нарушено на маленькой выборке — p-value и доверительные интервалы становятся кривыми, и вы можете принять неверное решение по A/B-тесту.
Где нормальность реально нужна:
- Одновыборочный и двухвыборочный t-тест — на малых выборках (условно n < 30 на группу) чувствителен к сильной скошенности.
- Линейная регрессия — нормальность требуется не для самих X или Y, а для остатков модели, если вы строите доверительные интервалы коэффициентов на малых данных.
- Доверительный интервал через t-распределение — та же логика, что у t-теста.
- ANOVA — сравнение средних нескольких групп.
Где нормальность НЕ требуется (частая путаница):
- Хи-квадрат тест на таблицах сопряжённости — работает с частотами.
- Непараметрические тесты (Манна-Уитни, Уилкоксона, Краскела-Уоллиса) — специально созданы, чтобы обойтись без неё.
- Бутстрап-доверительные интервалы — не делают допущений о форме распределения.
Ключевая тонкость: t-тест требует нормальности не самих наблюдений, а выборочного среднего. А среднее по мере роста выборки становится нормальным само по себе — об этом в разделе про ЦПТ ниже. Поэтому на больших выборках (тысячи наблюдений на группу) проверка нормальности исходных данных почти не влияет на валидность t-теста. Разбор того, как ошибки в выборе теста превращаются в ошибки первого и второго рода, стоит держать под рукой.
Как проверить нормальность визуально: гистограмма и QQ-plot?
Начинать всегда стоит с глаз, а не с p-value. Два инструмента закрывают 90% случаев.
Гистограмма. Строите распределение и смотрите на форму. Нормальные данные дают симметричный колокол с одним пиком. Тревожные сигналы:
- Длинный правый хвост (правая скошенность) — типично для денег, времени, счётчиков событий.
- Два пика (бимодальность) — часто это смесь двух сегментов, которые надо разделить.
- Резкая отсечка слева на нуле — счётчики и суммы не бывают отрицательными.
QQ-plot (квантиль-квантильный график). Это более честный инструмент. По оси X — теоретические квантили нормального распределения, по оси Y — квантили ваших данных. Если данные нормальны, точки ложатся на прямую диагональ. Как читать отклонения:
- Точки на концах загибаются вверх на правом краю и вниз на левом — тяжёлые хвосты (больше экстремальных значений, чем у нормального).
- S-образный изгиб — скошенность.
- Точки уходят выше линии справа — правый хвост длиннее.
QQ-plot полезнее гистограммы, потому что не зависит от выбора числа бинов и наглядно показывает поведение именно в хвостах, где и прячутся проблемы.
Как работают тесты Шапиро-Уилка и Колмогорова-Смирнова?
Формальные тесты дают число. У всех них нулевая гипотеза одна: «данные взяты из нормального распределения». Если p-value меньше 0.05 — нормальность отвергаем.
Тест Шапиро-Уилка — рабочая лошадка для проверки нормальности. Он сравнивает порядковые статистики выборки с ожидаемыми при нормальности и выдаёт статистику W близко к 1 для нормальных данных. Мощный на малых и средних выборках. Ограничение: scipy считает его надёжным примерно до n = 5000; на больших данных тест становится сверхчувствительным и отвергает нормальность из-за микроскопических отклонений.
Тест Колмогорова-Смирнова сравнивает эмпирическую функцию распределения с теоретической и берёт максимальное расхождение между ними. Важная ловушка: классический одновыборочный KS-тест требует, чтобы mu и sigma были известны заранее, а не оценены по той же выборке. Если подставить выборочные среднее и стандартное отклонение — тест становится слишком консервативным. Для проверки нормальности с оценёнными параметрами корректнее тест Лиллиефорса или Андерсона-Дарлинга. KS чаще применяют для сравнения двух выборок между собой.
| Тест | Когда применять | Ограничение |
|---|---|---|
| Шапиро-Уилк | Основной выбор, n от 3 до ~5000 | Сверхчувствителен на больших n |
| Колмогоров-Смирнов | Сравнение двух выборок | Требует известных параметров для проверки нормальности |
| Андерсона-Дарлинга | Акцент на хвостах | Сложнее интерпретировать |
Главный риск любого формального теста нормальности: на большой выборке он почти всегда даёт p < 0.05, потому что идеально нормальных данных в реальности не бывает. Поэтому решение не должно строиться только на p-value — сочетайте тест с QQ-plot и здравым смыслом про размер эффекта. Кстати, о том, что на самом деле означает p-value, полезно освежить перед собеседованием.
Как проверить нормальность в Python за один проход?
Соберём проверку в один блок: гистограмма, QQ-plot и Шапиро-Уилк на синтетических данных.
import numpy as np
from scipy import stats
rng = np.random.default_rng(42)
# Нормальные данные и скошенные (экспоненциальные) для сравнения
normal_data = rng.normal(loc=800, scale=100, size=500)
skewed_data = rng.exponential(scale=300, size=500)
def check_normality(x, name):
stat, p = stats.shapiro(x)
skew = stats.skew(x)
kurt = stats.kurtosis(x) # избыточный эксцесс, для нормального ~0
verdict = "нормально" if p > 0.05 else "НЕ нормально"
print(f"{name}: W={stat:.3f}, p={p:.4f} -> {verdict}")
print(f" асимметрия={skew:.2f}, эксцесс={kurt:.2f}")
check_normality(normal_data, "Нормальные")
check_normality(skewed_data, "Скошенные")
Ожидаемый вывод: у нормальных данных p будет заметно больше 0.05, асимметрия около нуля; у экспоненциальных — p близко к нулю и положительная асимметрия около 2. Дополнительно смотрят на два числа:
- Асимметрия (skewness) — для нормального распределения около 0. Положительная означает длинный правый хвост.
- Эксцесс (kurtosis) — избыточный эксцесс нормального распределения равен 0. Положительный — тяжёлые хвосты.
Для визуальной части добавьте QQ-plot:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
stats.probplot(normal_data, dist="norm", plot=axes[0])
axes[0].set_title("Нормальные: точки на линии")
stats.probplot(skewed_data, dist="norm", plot=axes[1])
axes[1].set_title("Скошенные: загиб в хвосте")
plt.tight_layout()
Прогнать этот код и поменять параметры распределений можно прямо в браузере — в Python-тренажёре есть scipy и numpy без локальной установки. Если хочется сначала подтянуть базу по массивам и векторизации, стартуйте с курса по NumPy, а генерацию случайных выборок для симуляций разбирает отдельная статья про случайность и A/B-симуляции в NumPy.
Что делать, если данные не нормальны?
Ненормальность — это не тупик, а развилка. Есть три рабочих пути.
1. Трансформация. Скошенные вправо данные (выручка, время, счётчики) часто выпрямляются логарифмом. Логарифм сжимает большие значения сильнее маленьких и убирает длинный правый хвост.
# Лог-трансформация для правоскошенных данных.
# log1p безопасен при нулях: log(1 + x)
transformed = np.log1p(skewed_data)
stat, p = stats.shapiro(transformed)
print(f"После log1p: p={p:.4f}") # часто становится > 0.05
Помимо логарифма используют квадратный корень (для счётчиков) и преобразование Бокса-Кокса, которое подбирает оптимальную степень автоматически (scipy.stats.boxcox). Минус трансформаций — результат приходится интерпретировать в преобразованной шкале, а среднее логарифмов не равно логарифму среднего.
2. Непараметрические тесты. Вместо t-теста берёте тест, который не требует нормальности. Он сравнивает не средние, а ранги значений:
# Вместо t-теста при ненормальных данных
u_stat, p = stats.mannwhitneyu(normal_data, skewed_data, alternative="two-sided")
print(f"Манна-Уитни: p={p:.4f}")
Соответствия простые: двухвыборочный t-тест меняете на тест Манна-Уитни, парный t-тест — на тест Уилкоксона, ANOVA — на тест Краскела-Уоллиса. Платите за это небольшой потерей мощности, если данные всё-таки были нормальны.
3. Бутстрап. Самый универсальный подход. Многократно пересэмплируете данные с возвращением, каждый раз считаете нужную статистику (среднее, медиану, разность) и строите распределение оценки эмпирически. Никаких допущений о форме.
def bootstrap_mean_ci(x, n_boot=10000, alpha=0.05):
boot_means = np.array([
rng.choice(x, size=len(x), replace=True).mean()
for _ in range(n_boot)
])
lo = np.percentile(boot_means, 100 * alpha / 2)
hi = np.percentile(boot_means, 100 * (1 - alpha / 2))
return lo, hi
lo, hi = bootstrap_mean_ci(skewed_data)
print(f"95% ДИ среднего (бутстрап): [{lo:.1f}, {hi:.1f}]")
Бутстрап отлично работает для метрик вроде выручки на пользователя или ARPU, которые почти никогда не нормальны из-за китов в правом хвосте. Механика доверительных интервалов подробно разобрана в статье про доверительный интервал простыми словами.
Как выбрать путь из трёх? Если цель — построить понятную модель или объяснить эффект бизнесу, начинайте с трансформации: лог-шкала часто ещё и осмысленнее (проценты роста вместо абсолютных рублей). Если нужен просто ответ «есть разница или нет» на небольшой выборке — берите непараметрику, она быстрая и не требует ничего настраивать. Если же метрика денежная, с редкими огромными значениями, и вам важен именно доверительный интервал среднего — бутстрап честнее всех, потому что не пытается натянуть колокол на данные, которые колоколом никогда не были. На практике эти подходы не конкурируют: аналитики часто считают и бутстрап, и Манна-Уитни, и если оба дают согласованный вывод — доверия к результату больше.
Как нормальность связана с ЦПТ и A/B-тестами?
Центральная предельная теорема (ЦПТ) — причина, по которой аналитики в продакшене редко паникуют из-за ненормальных данных. ЦПТ утверждает: распределение выборочного среднего стремится к нормальному по мере роста размера выборки, независимо от того, как распределены исходные данные (при конечной дисперсии).
Что это значит на практике. Даже если время сессии распределено экспоненциально с уродливым хвостом, среднее время по группе из нескольких тысяч пользователей будет распределено практически нормально. А t-тест сравнивает именно средние. Поэтому:
- На больших выборках (типичный продуктовый A/B-тест — тысячи-десятки тысяч на группу) t-тест валиден даже без нормальности исходных данных. Проверять нормальность сырых событий тут — пустая трата времени.
- На малых выборках (пилот на 20 пользователей, редкое событие) ЦПТ ещё не сработала, и нормальность действительно важна — берите непараметрику или бутстрап.
Практический чек-лист для A/B-теста:
- Метрика нормальная или выборка большая → t-тест.
- Метрика скошена и выборка маленькая → Манна-Уитни или бутстрап.
- Метрика — доля (конверсия) → z-тест для пропорций или хи-квадрат, нормальность исходных не при чём.
- Есть тяжёлые выбросы-киты → бутстрап по среднему либо сравнение медиан.
Скорость роста «нормальности среднего» зависит от того, насколько кривые исходные данные: для слегка скошенных хватит пары сотен наблюдений, для экстремальных хвостов нужны тысячи. Проверить это своими руками легко — сгенерируйте выборки, посчитайте средние много раз и постройте их распределение (та самая симуляция из раздела про Python). Как всё это увязывается с расчётом статзначимости, показано в разборе A/B-тестов на Python через scipy.stats.
Что запомнить
- Нормальное распределение — симметричный колокол; правило 68-95-99.7 задаёт доли внутри одного, двух и трёх стандартных отклонений.
- Нормальность важна для t-теста и регрессии на малых выборках; для долей, непараметрики и бутстрапа она не нужна.
- Проверяйте в порядке: гистограмма → QQ-plot → формальный тест (Шапиро-Уилк до ~5000 наблюдений).
- На больших выборках формальные тесты почти всегда отвергают нормальность — не решайте по одному p-value.
- Ненормальные данные лечатся лог-трансформацией, непараметрическими тестами или бутстрапом.
- Благодаря ЦПТ на больших A/B-тестах t-тест работает и без нормальности исходных данных.
Статистика на собеседовании аналитика — почти гарантированный блок вопросов. Прогнать типовые формулировки помогут подборка главных вопросов по статистике и живая тренировка в AI-интервьюере. А закрепить SQL-часть, без которой аналитику никуда, удобно на банке SQL-задач и в тренажёре вопросов — первые задачи открыты бесплатно, дальше подписка Pro.