Ответ
Выбор критерия зависит от типа метрики и свойств данных. Вот мой практический подход:
Для бинарных метрик (конверсия, кликабельность):
- Z-тест для пропорций: Основной инструмент при больших размерах выборок (n > 30, а лучше > 100 на группу), когда можно аппроксимировать биномиальное распределение нормальным.
from statsmodels.stats.proportion import proportions_ztest # count - количество успехов, nobs - размер группы count = np.array([150, 180]) # Конверсии в группах A и B nobs = np.array([1000, 1000]) # Размеры групп z_stat, p_value = proportions_ztest(count, nobs, alternative='two-sided') print(f"Z-статистика: {z_stat:.3f}, p-value: {p_value:.4f}")
Для непрерывных метрик (средний чек, время в приложении):
- T-тест Стьюдента: Использую, когда данные приблизительно нормально распределены и дисперсии в группах схожи (проверяю тестом Левена).
from scipy.stats import ttest_ind # revenue_a, revenue_b - массивы с данными по чекам t_stat, p_value = ttest_ind(revenue_a, revenue_b, equal_var=True) - U-тест Манна-Уитни: Непараметрическая альтернатива, когда данные не нормальны или есть выбросы. Он сравнивает не средние, а распределения в целом.
from scipy.stats import mannwhitneyu u_stat, p_value = mannwhitneyu(time_on_site_a, time_on_site_b, alternative='two-sided')
Ключевые принципы, которые я соблюдаю:
- Проверка предпосылок: Перед t-тестом смотрю на гистограммы и проверяю нормальность (Shapiro-Wilk) и гомогенность дисперсий (Levene's test).
- Коррекция множественных сравнений: Если тестируется несколько гипотез одновременно, применяю поправку Бонферрони или Бенджамини-Хохберга (FDR).
- Расчёт мощности теста: До запуска оцениваю необходимый размер выборки, чтобы с заданной вероятностью (обычно 80%) обнаружить эффект ожидаемого размера (MDE). Использую для этого
statsmodels.stats.power. - Анализ не только p-value: Всегда смотрю на доверительные интервалы разницы метрик, чтобы оценить не только статистическую значимость, но и практическую значимость эффекта.
Ответ 18+ 🔞
А, ну это же классика, ёпта! Сейчас объясню, как я обычно разбираюсь с этой статистической ерундой, чтобы не облажаться. Сидишь такой, смотришь на цифры, и подозрение ебать чувствуешь — а вдруг это просто случайный всплеск, а не реальный эффект? Вот тут и начинается магия.
Если метрика простая, как две копейки — «кликнул/не кликнул», «купил/не купил»: Тут всё просто, как три рубля. Берёшь Z-тест для пропорций. Работает он на ура, когда выборки большие (ну там, от сотни наблюдений в каждой группе, а лучше больше). По сути, он проверяет, не сошли ли мы с ума, думая, что разница в процентах — это не просто погрешность.
from statsmodels.stats.proportion import proportions_ztest
# count - количество успехов, nobs - размер группы
count = np.array([150, 180]) # Конверсии в группах A и B
nobs = np.array([1000, 1000]) # Размеры групп
z_stat, p_value = proportions_ztest(count, nobs, alternative='two-sided')
print(f"Z-статистика: {z_stat:.3f}, p-value: {p_value:.4f}")
Если p-value меньше 0.05 — поздравляю, можно начинать волнение ебать, скорее всего, разница реальная. Но это ещё не конец!
А вот если метрика посложнее — средний чек, время сессии, какая-нибудь хитроумная скор-бла-бла: Тут уже нужно смотреть, что у нас за данные. Идеальный мир — это T-тест Стьюдента. Но он, сука, такой нежный, требует, чтобы данные были хоть немного похожи на нормальное распределение и чтобы разбросы в группах были примерно одинаковые.
from scipy.stats import ttest_ind
# revenue_a, revenue_b - массивы с данными по чекам
t_stat, p_value = ttest_ind(revenue_a, revenue_b, equal_var=True)
Но жизнь — не идеальный мир. Часто данные выглядят так, будто их кот сука собака через себя пропустил: выбросы, дикие распределения, хвосты во все стороны. Вот тут на сцену выходит спаситель — U-тест Манна-Уитни. Ему похуй на нормальность, он сравнивает вообще всё распределение. Сильная штука.
from scipy.stats import mannwhitneyu
u_stat, p_value = mannwhitneyu(time_on_site_a, time_on_site_b, alternative='two-sided')
Но самое главное, чувак, — это не тупо запустить тест и порадоваться зелёной галочке. Вот мои железные правила, чтобы не выглядеть потом пиздопроебибной:
- Не верь глазам своим, проверь. Перед тем как тыкать в t-тест, посмотри на гистограммы. Данные нормальные? Дисперсии похожи? Есть тесты (Шапиро-Уилк, Левен) для этого, но иногда и глазами видно, что это хуй с горы, а не нормальное распределение.
- Если тыкаешь во всё подряд, рано или поздно попадёшь. Запустил десять гипотез? Жди, что одна случайно сработает просто так. Это как обезьяна с пишущей машинкой. Поэтому, если тестов много, применяй поправки — Бонферрони или Бенджамини-Хохберга. Без этого доверия ебать ноль к твоим результатам.
- Сила — не только в мышцах, но и в тесте. Перед экспериментом прикинь, сколько данных нужно, чтобы поймать эффект того размера, который тебе интересен. Иначе можешь месяц ждать и в итоге получить «разницы нет», хотя её просто невозможно было обнаружить с твоими крошечными выборками. Это называется «расчёт мощности».
- P-value — это не бог. «О, p-value 0.04, ура!» — стоп, блядь. Посмотри на доверительный интервал для разницы. Он показывает не просто «есть эффект», а «эффект скорее всего от X до Y». Может оказаться, что эффект есть, но он такой мизерный, что и заморачиваться не стоило. Всегда смотри и на p-value, и на интервалы, и на сами цифры. Иначе будешь как тот полупидор, который радуется статистической значимости увеличения конверсии с 0.001% до 0.002%.
Вот, собственно, и вся философия. Главное — не быть распиздяем, проверять предпосылки и смотреть на задачу с разных сторон. А то ведь можно и впиздюрить себе в отчёт красивую, но совершенно ложную находку.