Коротко: t-критерий Стьюдента проверяет, отличаются ли средние двух групп настолько, что случайностью это объяснить трудно. Он считает t-статистику — насколько разница средних велика в единицах шума (стандартной ошибки), — и переводит её в p-value. Маленькое p-value (обычно < 0.05) говорит: разница вряд ли случайна. В A/B-тестах чаще всего берут двухвыборочный тест Уэлча, потому что он не требует равенства дисперсий групп.
Что показывает t-критерий Стьюдента простыми словами?
Представь, что в A/B-тесте у контрольной группы средняя выручка на пользователя 512 рублей, а у тестовой — 548. Разница 36 рублей. Вопрос на миллион: это реальный эффект нового баннера или просто в тестовую группу случайно попало несколько крупных покупателей?
t-критерий отвечает на этот вопрос через одну идею: он сравнивает наблюдаемую разницу средних с тем, насколько сильно средние вообще скачут от выборки к выборке. Если разница в разы больше типичного разброса — эффект похож на настоящий. Если сопоставима с разбросом — это шум.
Формально t-статистика — это отношение сигнала к шуму:
t = (разница средних) / (стандартная ошибка этой разницы)
Чем больше по модулю t, тем сильнее сигнал выделяется на фоне шума. А p-value — вероятность увидеть такое (или ещё большее) t, если на самом деле разницы между группами нет. Логика та же, что за p-value простыми словами: мы не доказываем, что эффект есть, а показываем, что «ничего нет» плохо объясняет данные.
Важно, чего t-тест НЕ делает: он не говорит, что эффект большой или бизнес-значимый. Он говорит только о статистической значимости. Оценивать размер эффекта нужно отдельно — через доверительный интервал.
Одновыборочный, двухвыборочный, парный — когда какой?
Есть три разновидности, и путать их — классическая ошибка на собеседовании.
| Тип теста | Что сравниваем | Пример из аналитики |
|---|---|---|
| Одновыборочный | Среднее одной группы с фиксированным числом | Средний чек = 500 руб. по нормативу? |
| Двухвыборочный (независимый) | Средние двух РАЗНЫХ групп | Выручка контроль vs тест в A/B |
| Парный | Две измерения на ОДНИХ и тех же объектах | Конверсия магазинов до и после редизайна |
- Одновыборочный нужен редко: например, проверить, отличается ли среднее время ответа саппорта от SLA в 4 часа.
- Двухвыборочный — рабочая лошадка A/B-тестов. Группы независимы: один пользователь либо в контроле, либо в тесте.
- Парный применяют, когда есть естественная пара «до/после» на одном объекте. Он мощнее, потому что убирает межобъектную вариацию: если магазин А всегда продаёт больше магазина Б, парный тест это учитывает и смотрит только на изменение внутри каждого магазина.
Главная ловушка: применить независимый тест там, где данные парные. Тогда ты выбрасываешь информацию о связи и теряешь мощность — рискуешь не заметить реальный эффект. И наоборот: парный тест на независимых группах вообще неприменим.
Как устроена формула t-статистики?
Разберём двухвыборочный случай, он самый частый. Обозначим средние групп как m1 и m2, дисперсии как s1² и s2², размеры как n1 и n2.
Классический тест Стьюдента (предполагает равные дисперсии) считает так:
t = (m1 - m2) / (Sp * sqrt(1/n1 + 1/n2))
где Sp — объединённое стандартное отклонение:
Sp = sqrt( ((n1-1)*s1^2 + (n2-1)*s2^2) / (n1 + n2 - 2) )
Тест Уэлча (не требует равных дисперсий) считает стандартную ошибку иначе:
t = (m1 - m2) / sqrt(s1^2/n1 + s2^2/n2)
Разберём знаменатель по частям, потому что в нём вся суть:
s1^2/n1иs2^2/n2— это квадраты стандартных ошибок средних. Чем больше выборка, тем меньше ошибка, тем устойчивее среднее.- Сумма под корнем — стандартная ошибка разницы средних, тот самый «шум».
- Разница средних в числителе — «сигнал».
Дальше t сравнивают с t-распределением с определённым числом степеней свободы. У распределения Стьюдента хвосты толще, чем у нормального, — это плата за то, что дисперсию мы не знаем точно, а оцениваем по выборке. На больших n (сотни-тысячи наблюдений, как в типичном A/B) t-распределение почти совпадает с нормальным.
Число степеней свободы для теста Стьюдента = n1 + n2 - 2, а для Уэлча считается по громоздкой формуле Уэлча–Саттертуэйта и обычно получается дробным. Руками это не считают — за тебя всё сделает scipy.
Какие допущения у теста и что такое критерий Уэлча?
У t-критерия три допущения, и относиться к ним надо трезво.
- Независимость наблюдений. Каждый пользователь считается один раз, эффекты не перетекают между людьми. Это самое важное и невосстановимое: если данные зависимы (один юзер сгенерировал 100 покупок), тест сломан.
- Нормальность. Формально требуется, чтобы данные (точнее — распределение выборочного среднего) были близки к нормальному. Хорошая новость: по центральной предельной теореме на выборках в сотни-тысячи наблюдений среднее становится нормальным почти при любом исходном распределении. Поэтому на больших A/B нормальность редко проблема.
- Равенство дисперсий. Классический тест Стьюдента его требует. На практике оно почти никогда не выполняется точно.
Именно поэтому существует критерий Уэлча — модификация t-теста, которая НЕ предполагает равные дисперсии. Он считает стандартную ошибку по формуле выше и корректирует степени свободы. Практическое правило простое:
По умолчанию всегда используй тест Уэлча. Он почти не теряет мощности, когда дисперсии равны, и защищает тебя, когда они различаются. В scipy это флаг equal_var=False.
Отдельно про данные, где нормальность плохая даже после ЦПТ (например, доля-конверсия на малых выборках или сильно скошенная выручка с редкими выбросами): там лучше подойдут непараметрический тест Манна–Уитни, бутстрап или z-тест пропорций для конверсии. t-тест — не универсальный молоток.
Как посчитать t-тест в Python через scipy.stats.ttest_ind?
Самый частый инструмент — scipy.stats.ttest_ind. Сравним выручку двух групп A/B-теста. Сначала синтетические данные, чтобы код запускался как есть.
import numpy as np
from scipy import stats
rng = np.random.default_rng(42)
# Контроль и тест: выручка на пользователя, руб.
control = rng.normal(loc=512, scale=140, size=1800)
treatment = rng.normal(loc=548, scale=155, size=1820)
# Тест Уэлча (equal_var=False) — рекомендуемый вариант для A/B
t_stat, p_value = stats.ttest_ind(treatment, control, equal_var=False)
print(f"Среднее контроль: {control.mean():.1f}")
print(f"Среднее тест: {treatment.mean():.1f}")
print(f"Разница: {treatment.mean() - control.mean():.1f}")
print(f"t-статистика: {t_stat:.3f}")
print(f"p-value: {p_value:.4f}")
Типичный вывод: разница около 35 рублей, t-статистика примерно 7, p-value заметно меньше 0.001. Вывод: разница статистически значима.
Для парного теста используется другая функция — ttest_rel (данные должны идти парами и быть одной длины):
before = np.array([120, 98, 145, 110, 132, 101])
after = np.array([131, 105, 150, 121, 139, 115])
t_stat, p_value = stats.ttest_rel(after, before)
print(f"t = {t_stat:.3f}, p = {p_value:.4f}")
Для одновыборочного — ttest_1samp, где второй аргумент это эталонное значение:
sla_hours = np.array([3.8, 4.2, 5.1, 3.9, 4.6, 4.0, 4.9])
t_stat, p_value = stats.ttest_1samp(sla_hours, popmean=4.0)
print(f"t = {t_stat:.3f}, p = {p_value:.4f}")
И почти обязательный спутник теста — доверительный интервал на разницу средних. p-value говорит «есть эффект или нет», а интервал показывает, насколько он большой:
diff = treatment.mean() - control.mean()
se = np.sqrt(treatment.var(ddof=1)/len(treatment) + control.var(ddof=1)/len(control))
ci_low, ci_high = diff - 1.96*se, diff + 1.96*se
print(f"Разница {diff:.1f} руб., 95% ДИ: [{ci_low:.1f}; {ci_high:.1f}]")
Хочешь прогнать эти сниппеты и поменять размеры выборок — открой Python-тренажёр, там scipy уже подключён и ничего ставить не надо. Если пробелов в pandas/numpy пока много, начни с курса pandas с нуля.
Как интерпретировать p-value в A/B-тесте?
Стандартный порог значимости alpha = 0.05. Логика решения:
p-value < 0.05— отвергаем нулевую гипотезу «разницы нет», считаем эффект статистически значимым.p-value >= 0.05— оснований отвергнуть «разницы нет» недостаточно. Это НЕ доказательство, что эффекта нет, — возможно, просто не хватило данных.
Чего p-value НЕ означает (и что любят спрашивать на собесе):
- Это НЕ вероятность того, что нулевая гипотеза верна. Это вероятность увидеть такие данные ПРИ условии, что нулевая гипотеза верна.
- p = 0.03 не значит «эффект на 97% реален». Про это подробно в разборе p-value простыми словами.
- Значимость не равна важности. При выборке в миллион пользователей значимой станет разница даже в 1 копейку, которая бизнесу безразлична.
Поэтому решение по A/B-тесту принимают по трём вещам сразу: p-value (значимо ли), доверительный интервал (насколько велик эффект и не задевает ли ноль) и заранее заданный минимальный детектируемый эффект. А размер выборки под нужную мощность считают ДО теста — иначе половина результатов окажется недоказуемой. Полезно освежить ошибки первого и второго рода и доверительный интервал.
Какие ошибки чаще всего делают с t-тестом?
Собрал грабли, на которые наступают чаще всего.
- Пиккинг (peeking). Смотрят на p-value каждый день и останавливают тест, как только увидели p < 0.05. Это раздувает вероятность ложного срабатывания в разы. Останавливай тест на заранее рассчитанном размере выборки или используй методы последовательного анализа.
- Тест Стьюдента вместо Уэлча. По умолчанию
ttest_indв старых версиях бралequal_var=True. Если дисперсии групп разные, это завышает уверенность. Ставьequal_var=False. - t-тест на конверсии малой выборки. Для бинарной метрики «купил / не купил» на небольших числах корректнее z-тест пропорций или точный тест. На больших выборках t-тест по конверсии работает приемлемо, но осознанно.
- Игнор выбросов и скошенности. Выручка — распределение с длинным правым хвостом. Один кит может перекосить среднее. Проверь распределение глазами, при необходимости логарифмируй или используй бутстрап/непараметрику. Иногда честнее сравнивать медиану вместо среднего.
- Зависимые наблюдения выдают за независимые. Считать не пользователей, а их события (сессии, клики) — типичный способ искусственно раздуть выборку и получить фальшивую значимость.
- Множественные сравнения. Тестируешь 20 метрик — при alpha 0.05 одна «значимость» вылезет случайно. Нужна поправка (Бонферрони, Бенджамини–Хохберг) или заранее выбранная главная метрика.
- Путают одностороннюю и двустороннюю гипотезу. По умолчанию scipy считает двусторонний тест. Односторонний берут, только если направление эффекта строго задано заранее.
Разбор целого A/B-кейса с кодом есть в разборе тестового по A/B и в статье A/B-тесты на Python через scipy.stats.
Что спрашивают про t-критерий на собеседовании?
Подборка реальных формулировок с короткими ответами — чтобы не поплыть.
- Чем отличается t-тест от z-теста? z-тест применяют, когда дисперсия генеральной совокупности известна (редко) или выборка очень большая. t-тест оценивает дисперсию по выборке и использует распределение с более толстыми хвостами. На больших n они почти совпадают.
- Когда Уэлч, когда Стьюдент? Стьюдент требует равенства дисперсий, Уэлч — нет. На практике по умолчанию Уэлч,
equal_var=False. - Какие допущения у t-теста? Независимость наблюдений, нормальность (спасает ЦПТ на больших выборках), равенство дисперсий (снимается Уэлчем).
- Что такое p-value словами? Вероятность увидеть такую или большую разницу при условии, что реального эффекта нет.
- Значимо p = 0.049 и незначимо p = 0.051 — это разные миры? Нет. Порог 0.05 условен, разница между этими значениями практически нулевая. Смотри ещё и на доверительный интервал.
- Можно ли t-тестом сравнивать конверсию? На больших выборках приемлемо, но корректнее z-тест пропорций, особенно на малых числах.
- Как выбрать размер выборки? Заранее, через мощность, alpha, MDE и дисперсию метрики — калькулятор в статье расчёт sample size.
Разбор метрик, которые обычно и сравнивают t-тестом, лежит в карточках ARPU и среднего чека AOV. Больше теории для собеса — в подборке главных вопросов по статистике и в банке вопросов по интервью.
Понимать t-критерий по-настоящему получается, только когда сам считаешь t-статистику и p-value на живых данных, а не пересказываешь формулу. Собери всё вместе так: возьми пару выборок в Python-тренажёре, прогони ttest_ind с equal_var=False, построй доверительный интервал, а потом на том же датасете посчитай агрегаты в SQL-тренажёре. Первые пять задач открыты бесплатно, дальше — Pro. Если хочется прогнать эти вопросы вслух перед реальным собеседованием, есть AI мок-собес, который гоняет именно по статистике и A/B.
Держи в голове одну связку: t-критерий — это сигнал делить на шум, p-value — перевод этого сигнала в вероятность, а доверительный интервал — размер эффекта. Три числа вместе, а не одно из них, и есть грамотное решение по A/B-тесту.