статистикаANOVAсравнение групп

ANOVA (дисперсионный анализ) простыми словами

2026-07-12 10 мин

Если у вас три группы и больше, а нужно понять, отличаются ли их средние, — не запускайте попарные t-тесты пачками. Возьмите ANOVA, дисперсионный анализ. Она одним тестом отвечает на вопрос «есть ли вообще хоть какое-то различие между группами» и при этом не раздувает вероятность найти различие там, где его нет. Ниже разберу, почему куча t-тестов — это ловушка, как ANOVA сравнивает разброс между группами с разбросом внутри них, что за зверь F-статистика и как посчитать всё это в scipy за пять строк.

Почему нельзя сравнить три группы кучей t-тестов?

Потому что каждый t-тест на уровне значимости 0.05 несёт 5% шанс ложного срабатывания, и эти шансы накапливаются.

Представьте эксперимент с тремя вариантами лендинга: A, B и C. Чтобы сравнить их попарно, нужно три теста: A vs B, A vs C, B vs C. Для пяти вариантов уже десять пар, для шести — пятнадцать. Каждый тест — это отдельный бросок монетки с 5% шансом «увидеть» различие, которого на самом деле нет.

Если сравнения условно независимы, вероятность хотя бы одной ложной находки считается как 1 - 0.95^m, где m — число сравнений. Для трёх пар это примерно 14%, для десяти — уже около 40%. То есть на пяти группах вы почти гарантированно найдёте «значимое» различие на пустом месте. Это классическая проблема множественных сравнений, и её любят спрашивать на собеседованиях — если готовитесь, загляните в банк вопросов по статистике.

ANOVA решает это в лоб: вместо кучи попарных проверок она задаёт один общий вопрос — «есть ли хоть где-то разница между средними?» — и отвечает на него одним p-value с честным уровнем ошибки.

В чём идея ANOVA: межгрупповая и внутригрупповая дисперсия?

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

Разброс данных ANOVA раскладывает на два источника:

Дальше логика такая. Если межгрупповой разброс большой на фоне внутригруппового шума — скорее всего, группы действительно разные. Если средние групп отличаются не сильнее, чем значения случайно гуляют внутри группы, — различие тонет в шуме, и говорить не о чем.

Отсюда и название «дисперсионный анализ»: мы сравниваем не сами средние напрямую, а два вида дисперсии. Немного контринтуитивно — тест про средние, а работает через разброс, — но именно это делает его устойчивым.

Что показывает F-статистика?

F-статистика — это и есть то самое отношение: межгрупповая дисперсия, делённая на внутригрупповую. Формула словами: F = средний межгрупповой квадрат / средний внутригрупповой квадрат.

Чтобы получить эти средние квадраты, суммы квадратов отклонений делят на степени свободы: для межгрупповой части их k - 1 (где k — число групп), для внутригрупповой — N - k (где N — общее число наблюдений). Делить обязательно, иначе большие группы автоматически давали бы больший разброс.

Как читать результат:

Важный нюанс, о который спотыкаются новички: ANOVA — тест «омнибус». Маленький p-value говорит только, что где-то среди групп есть различие. Он не говорит, между какими именно. Вернёмся к этому в разделе про post-hoc.

Как посчитать one-way ANOVA в Python?

One-way ANOVA — это версия с одним фактором-группировкой (например, вариант эксперимента). В scipy она делается функцией f_oneway. Возьмём выручку на пользователя в трёх вариантах онбординга:

import pandas as pd
from scipy import stats

df = pd.read_csv("experiment.csv")  # user_id, variant, revenue

# собираем массив выручки по каждому варианту
groups = [g["revenue"].values for _, g in df.groupby("variant")]

f_stat, p_value = stats.f_oneway(*groups)
print(f"F = {f_stat:.3f}, p = {p_value:.5f}")

Если данные лежат просто списками, ещё короче:

from scipy import stats

a = [340, 290, 410, 380, 300, 360, 420, 310]
b = [300, 280, 260, 330, 290, 275, 310, 295]
c = [450, 500, 470, 430, 490, 510, 460, 480]

f_stat, p_value = stats.f_oneway(a, b, c)
print(f"F = {f_stat:.3f}, p = {p_value:.5f}")

Читаем так: если p_value меньше выбранного порога (обычно 0.05), делаем вывод, что хотя бы один вариант отличается по средней выручке. В примере выше вариант C явно выбивается вверх, поэтому F будет большим, а p — крошечным.

Хотите пощупать руками — соберите такой датасет и прогоните код в Python-тренажёре, а синтаксис scipy и pandas подсмотрите в справочнике по Python.

ANOVA нашла различие — а где именно?

ANOVA сказала «различие есть», но между A и B, A и C или B и C — молчит. Чтобы узнать конкретику, нужен post-hoc тест. И тут нельзя снова скатиться в пачку обычных t-тестов — вернётся та же проблема раздувания ошибки.

Самый ходовой post-hoc — критерий Тьюки (Tukey HSD, honestly significant difference). Он проверяет все пары сразу, но держит суммарную ошибку под контролем, закладывая поправку прямо в расчёт. В свежих версиях scipy для этого есть tukey_hsd:

from scipy.stats import tukey_hsd

res = tukey_hsd(a, b, c)
print(res)  # доверительные интервалы и p-value для каждой пары

На выходе — таблица по всем парам: для каждой видно p-value и доверительный интервал разницы средних. Если интервал не накрывает ноль, различие в этой паре значимо.

Логика всегда двухступенчатая: сначала ANOVA как привратник — есть ли смысл вообще копать. Если общий тест ничего не нашёл, лезть в попарные сравнения обычно не стоит. Если нашёл — Тьюки показывает, кто именно из групп отличается. Кроме Тьюки есть и другие поправки (Бонферрони — самая простая и консервативная), но для сравнения «каждый с каждым» Тьюки обычно даёт больше мощности.

Какие у ANOVA предпосылки и что делать, если они нарушены?

У классической one-way ANOVA три предпосылки, и знать их важнее, чем саму формулу.

from scipy import stats
stat, p = stats.levene(a, b, c)  # p < 0.05 -> дисперсии разные

Что делать, если предпосылки поплыли:

Выручка на пользователя, кстати, почти всегда скошена вправо: много мелких платежей и редкие крупные. Перед ANOVA такие метрики полезно прологарифмировать или сразу смотреть в сторону Краскела — Уоллиса.

Как использовать ANOVA в A/B-тесте с несколькими вариантами?

Типичный кейс — A/B/C/D-тест, где вы гоняете сразу несколько вариантов против контроля. ANOVA здесь работает как ворота: сначала одним тестом проверяем, есть ли различия в принципе, и только потом, если есть, идём в Тьюки смотреть, какой вариант выстрелил. Так вы не раздуваете ошибку первого рода и не радуетесь случайному выбросу.

Несколько практических оговорок, которые я усвоил на своих экспериментах:

Разбор реальных многовариантных экспериментов удобно смотреть на кейсах, а типовые метрики вроде DAU и выручки — та самая непрерывная величина, которую ANOVA и сравнивает между группами. Если готовитесь к собеседованиям в продуктовые команды, вопрос «чем ANOVA отличается от t-теста и когда её брать» всплывает постоянно — структурированно пройтись по статистике помогает программа подготовки к собеседованию.

Короткая шпаргалка

Чтобы всё уложилось:

Разница между t-тестом, ANOVA и их непараметрическими аналогами — один из самых частых блоков на собеседованиях аналитика. Если хочется не просто прочитать, а прорешать статистику и A/B по-настоящему, с проверкой прямо в браузере, — это открывается в Pro вместе со всеми задачами, кейсами и AI-собеседованиями. Начать можно бесплатно и без спешки.

Связанная тема — t-критерий Стьюдента простыми словами и пример.

Готовься к собесу аналитика
Вопросы по статистике и A/B с разбором — попробуй бесплатно.
Банк вопросов →