Содержание курса 19 / 22

19 / 22 · От вероятности к статистике

Проверка гипотез и A/B-тесты

Как решить, реален ли эффект: нулевая и альтернативная гипотезы, статистики критериев, p-значения и ошибки двух родов, A/B-тест от статистики z до размера выборки, нужного для мощности 80%, чем p-значение не является (и почему треть значимых результатов может оказаться ложной), подглядывание и множественные сравнения, а также перестановочные тесты, которым не нужны предположения о распределении.

На этой странице 12

В эксперименте с 20 000 пользователей в каждой группе доля кликов с новой кнопкой выросла с 2.0% до 2.3%. Кнопка лучше или разница — это шум? Проверка гипотезы (hypothesis test) превращает этот вопрос в вычисление: предположить, что эффекта нет, вычислить, насколько неожиданными были бы данные при этом предположении, и действовать, если они достаточно неожиданны. В этой заметке мы строим тест, разбираем A/B-тест как его самое частое применение и мощность, которая определяет, насколько большим должен быть эксперимент, а также то, как тесты неверно читают и неверно применяют: p-значение принимают за вероятность того, что гипотеза верна, подглядывают (peeking) в идущие эксперименты и проверяют много гипотез сразу.

Обозначения. H0H_0 — нулевая гипотеза (null hypothesis; эффекта нет), H1H_1 — альтернативная гипотеза. TT — статистика критерия (test statistic), α\alpha — уровень значимости (significance level), обычно 0.050.05. Φ\Phi — функция распределения стандартного нормального распределения.

Логика теста#

У теста четыре части:

  1. Нулевая гипотеза H0H_0: монета честная, кнопка ничего не меняет.
  2. Статистика критерия TT, распределение которой при H0H_0 известно: число орлов, стандартизованная разность.
  3. p-значение (p-value): вероятность при H0H_0 получить статистику не менее экстремальную, чем наблюдённая.
  4. Решение: отвергнуть H0H_0, если p≤αp \le \alpha.

Монета дала 60 орлов в 100 бросках. При гипотезе о честной монете число орлов имеет распределение Bin(100,0.5)\mathrm{Bin}(100, 0.5), а результат, который отстоит от 50 в ту или другую сторону не меньше наблюдённого, имеет вероятность 0.0570.057: это не меньше 0.050.05, поэтому тест гипотезу не отвергает. Но и вывода, что монета честная, он не делает; вывод в том, что этих 100 бросков недостаточно, чтобы решить.

Возможны ошибки двух родов. Ошибка первого рода (type I error) — отвергнуть верную H0H_0; её вероятность по построению не больше α\alpha. Ошибка второго рода (type II error) — сохранить неверную H0H_0; единица минус её вероятность — это мощность (power), вероятность обнаружить эффект, который действительно есть. Уровень выбирают; мощность зависит от величины эффекта и от объёма данных.

A/B-тест#

Пользователей случайно делят на две группы: группа A видит старую кнопку, группа B — новую, и сравнивают доли кликов p^A=0.020\hat p_A = 0.020 и p^B=0.023\hat p_B = 0.023. По центральной предельной теореме их разность приближённо нормальна со стандартной ошибкой pA(1−pA)/n+pB(1−pB)/n=0.00145\sqrt{p_A(1-p_A)/n + p_B(1-p_B)/n} = 0.00145, и статистика критерия

z=p^B−p^Ase⁡^=2.07z = \frac{\hat p_B - \hat p_A}{\widehat{\operatorname{se}}} = 2.07

имеет приближённо распределение N(0,1)N(0, 1), если кнопка ничего не меняет. p-значение равно P(∣Z∣≥2.07)=0.039P(\lvert Z \rvert \ge 2.07) = 0.039:

Рисунок

Нулевое распределение, p-значение и мощность

Две нормальные кривые с закрашенными областямиНулевая кривая с центром 0 и хвостами за ±1.96; отметка z = 2.07; альтернативная кривая с центром 2.07, правее 1.96 лежит 54% её площади.-4-20246нет разницы: z ~ N(0, 1)α = 0.051z = 2.07p = 0.0392разница 0.3 п. п.: z ~ N(2.07, 1)мощность 0.543Две нормальные кривые с закрашенными областямиНулевая кривая с центром 0 и хвостами за ±1.96; отметка z = 2.07; альтернативная кривая с центром 2.07, правее 1.96 лежит 54% её площади.-4-20246нет разницы: z ~ N(0, 1)α = 0.051z = 2.07p = 0.0392разница 0.3 п. п.: z ~ N(2.07, 1)мощность 0.543
A/B-тест из заметки: доли кликов 2.0% и 2.3%, по 20 000 пользователей в группе. Синяя кривая — распределение статистики z, если разницы нет; красные хвосты |z| > 1.96 — область отклонения, 5% (1). Наблюдаемое z = 2.07 попадает в неё; p-значение, жёлтая площадь за ±2.07, равно 0.039 (2). Зелёная кривая — распределение z, если разница действительно 0.3 п. п.; доля её площади в области отклонения, 0.54, — мощность теста (3).

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

Мощность и размер выборки. Если истинные доли равны 2.0% и 2.3%, эксперимент с 20 000 пользователей в группе обнаруживает разницу с вероятностью всего 0.540.54; почти половина таких экспериментов пропустила бы реальный эффект. Число пользователей в группе, нужное для мощности 1−β1 - \beta на уровне α\alpha, равно

n=(z1−α/2+z1−β)2(pA(1−pA)+pB(1−pB))(pB−pA)2,n = \frac{(z_{1-\alpha/2} + z_{1-\beta})^2 \big(p_A(1-p_A) + p_B(1-p_B)\big)}{(p_B - p_A)^2} ,

и для мощности 80% это 36 691 пользователь в группе. Малым эффектам на малых долях нужны большие эксперименты: требуемое nn растёт обратно пропорционально квадрату эффекта, поэтому уменьшение обнаруживаемого эффекта вдвое увеличивает эксперимент вчетверо.

Чем p-значение не является#

  • Не P(H0∣данные)P(H_0 \mid \text{данные}). Пусть из идей, которые проверяет команда, на самом деле работают 10%, мощность тестов — 80%, а α=0.05\alpha = 0.05. Из 1000 идей работают 100, и 80 из них обнаруживаются; 900 не работают, и 45 из них оказываются значимыми случайно. Около трети значимых результатов, 45/125=0.3645/125 = 0.36, ложные, хотя у каждого из них p<0.05p < 0.05. Это расчёт с базовой частотой из вводной заметки, только с тестами вместо пациентов.
  • Не величина эффекта. При достаточном объёме данных значимой оказывается и пренебрежимо малая разница; при слишком малом не оказывается значимой и большая. Эффект нужно приводить с доверительным интервалом, а не только с p-значением.
  • Большое p-значение — не свидетельство отсутствия эффекта. p=0.3p = 0.3 означает, что данные совместимы с отсутствием эффекта — и обычно также с заметным эффектом.
  • Не мера воспроизводимости. Результат с p=0.04p = 0.04 при том же размере выборки и при истинном эффекте, равном наблюдённому, воспроизводится лишь примерно в половине случаев, потому что наблюдённый эффект лишь чуть превышает порог.

Подглядывание#

Проверять идущий эксперимент каждый день и останавливать его, как только p<0.05p < 0.05, кажется безобидным, но это не так. Каждая проверка — ещё один шанс для шума пересечь порог:

Рисунок

Подглядывание в A/A-тесте

Траектории статистики z11 из 40 траекторий хотя бы раз пересекают границы ±1.96.-1.9601.9615101520номер проверкиТраектории статистики z11 из 40 траекторий хотя бы раз пересекают границы ±1.96.-1.9601.9615101520номер проверки
40 A/A-тестов: в обеих группах конверсия 2%, между проверками добавляется по 1000 пользователей в группу, всего 20 проверок. Линии — статистика z после каждой проверки, пунктир — ±1.96. Разницы нет, и в конце значимы только 2 из 40; но 11 траекторий (красные) хотя бы раз выходят за ±1.96, и аналитик, останавливающий тест при первом таком выходе, объявил бы их значимыми. По 20 000 повторений это 25% ложных срабатываний вместо 5%.

В A/A-тестах, где обе группы одинаковы, 20 просмотров данных дают «значимый» результат в 25% экспериментов вместо 5%. Исправить это можно тремя способами: заранее зафиксировать размер выборки; использовать последовательные тесты (sequential tests), пороги которых учитывают повторные просмотры (расходование уровня значимости — alpha spending, всегда корректные p-значения — always-valid p-values).

Множественные сравнения#

Эксперимент, который сообщает 20 метрик и проверяет каждую на уровне α=0.05\alpha = 0.05, находит хотя бы один ложный эффект с вероятностью 1−0.9520=0.641 - 0.95^{20} = 0.64, если ни одна метрика на самом деле не изменилась и метрики независимы, — это вычислила заметка об аксиомах. Поправка Бонферрони (Bonferroni correction) проверяет каждую из mm гипотез на уровне α/m\alpha/m и через оценку объединения контролирует вероятность хотя бы одного ложного отвержения. Когда гипотез много и некоторое число ложных открытий допустимо, процедура Бенджамини–Хохберга (Benjamini–Hochberg) контролирует ожидаемую долю ложных открытий среди отвергнутых гипотез (false discovery rate, FDR) вместо вероятности хотя бы одного ложного отвержения — групповой вероятности ошибки (family-wise error rate), которую контролирует поправка Бонферрони, — и сохраняет гораздо большую мощность. Её гарантия предполагает корректные p-значения, независимые или положительно зависимые в определённом смысле; для метрик с произвольной зависимостью нужна более консервативная поправка Бенджамини–Иекутиели (Benjamini and Yekutieli, 2001) или метод повторных выборок, сохраняющий зависимость. Та же проблема возникает незаметно для всех, когда анализ перебирает несколько сегментов, метрик или временных окон и сообщает о том, что сработало.

Перестановочные тесты#

z-тест опирается на центральную предельную теорему. Перестановочный тест (permutation test) опирается только на саму рандомизацию: если воздействие ничего не меняет, метки групп произвольны и любое их перераспределение равновероятно. Вычислим статистику для каждого способа разбить данные на группы исходных размеров; p-значение — доля разбиений, в которых статистика не менее экстремальна, чем наблюдённая. Когда разбиений слишком много, чтобы перебрать все, берут BB случайных и используют p=(b+1)/(B+1)p = (b + 1)/(B + 1), где bb — число случайных разбиений, не менее экстремальных, чем наблюдённое: учёт самого наблюдённого разбиения сохраняет корректность теста и никогда не даёт p=0p = 0. Для двух групп по шесть измерений с разностью средних 2.132.13 в 20 из 924 разбиений разность по абсолютной величине не меньше: p=0.022p = 0.022 против 0.0150.015 у t-теста, который предполагает нормальность данных. Если нулевая гипотеза — полное отсутствие эффекта, перестановочные тесты точны при любом распределении и для любой статистики, поэтому они — естественный тест для медиан, разностей AUC и любых метрик без формулы.

Что изменилось#

ДоС тестами
«Реальна ли разница?»субъективное суждениеp-значение: насколько неожиданны данные при отсутствии эффекта
Ошибкипервого рода — не больше α\alpha; второго рода — задаётся мощностью
Размер экспериментасколько позволяет трафикnn для нужной мощности; ∝1/эффект2\propto 1/\text{эффект}^2
Чтение результатовp<0.05p < 0.05 — значит, правдатреть значимых результатов может быть ложной, когда работают немногие идеи
Процесссмотреть когда угодно, сообщать о том, что сработалофиксированный горизонт или последовательные тесты; поправки на множественные сравнения

Ограничения#

  • Статистическая значимость — не практическая значимость. Реальный эффект может быть слишком мал, чтобы иметь значение, а большой эффект может оказаться необнаружимым на имеющихся данных.
  • Тесты предполагают независимые единицы и стабильные условия. Пользователи, взаимодействующие друг с другом, эффекты новизны (novelty effects) или трафик, меняющийся во время эксперимента, нарушают предположения, на которых держится p-значение.
  • Порог 0.05 — условность. Он контролирует одну вероятность ошибки на тест; решения связаны с издержками, которые фиксированный порог игнорирует.

Что нужно запомнить#

  • p-значение = P(статистика не менее экстремальна, чем наблюдённая∣H0)P(\text{статистика не менее экстремальна, чем наблюдённая} \mid H_0); на уровне α\alpha гипотезу отвергают, когда p≤αp \le \alpha.
  • Ошибка первого рода — не больше α\alpha; мощность — вероятность обнаружить реальный эффект; nn планируют под мощность, n∝1/эффект2n \propto 1/\text{эффект}^2.
  • A/B-тест для долей: z=(p^B−p^A)/se⁡^z = (\hat p_B - \hat p_A)/\widehat{\operatorname{se}}; 2.0% против 2.3% по 20 000 пользователей в группе дают z=2.07z = 2.07, p=0.039p = 0.039, мощность 0.54.
  • p-значение — не P(H0∣данные)P(H_0 \mid \text{данные}): при 10% работающих идей, мощности 80% и α=0.05\alpha = 0.05 ложны 36% значимых результатов.
  • Подглядывание и множество метрик увеличивают долю ложных срабатываний: 25% при 20 просмотрах, 64% при 20 метриках; помогают фиксированный горизонт, последовательные тесты, поправка Бонферрони или процедура Бенджамини–Хохберга.
  • Перестановочные тесты: перемешать метки; при рандомизации тест точен для любой статистики.

Код#

Монета, A/B-тест с его мощностью и размером выборки, доля ложных открытий, подглядывание и перестановочный тест:

import numpy as np, math, itertools
from scipy import stats

# 60 heads in 100 flips: exact two-sided p-value
print(round(float(stats.binomtest(60, 100, 0.5).pvalue), 4))      # 0.0569

# the A/B test: 2.0% vs 2.3% with 20,000 users per group; power now, and users per group for 80% power
p1, p2, n = 0.02, 0.023, 20_000
se = math.sqrt(p1 * (1 - p1) / n + p2 * (1 - p2) / n)
z = (p2 - p1) / se
print(round(z, 2), round(float(2 * stats.norm.sf(z)), 3))         # 2.07 0.039
za, zb = stats.norm.ppf(0.975), stats.norm.ppf(0.8)
print(round(float(stats.norm.sf(za - z)), 2), math.ceil((za + zb) ** 2 * (p1 * (1 - p1) + p2 * (1 - p2)) / (p2 - p1) ** 2))   # 0.54 36691

# false discoveries when 10% of tested ideas work, power 0.8, alpha 0.05
print(round(0.9 * 0.05 / (0.9 * 0.05 + 0.1 * 0.8), 2))            # 0.36

# peeking: 20,000 A/A tests checked after every 1,000 users per group, 20 checks
rng = np.random.default_rng(0)
a = rng.binomial(1000, 0.02, (20_000, 20)).cumsum(axis=1)
b = rng.binomial(1000, 0.02, (20_000, 20)).cumsum(axis=1)
m = 1000 * np.arange(1, 21)
pool = (a + b) / (2 * m)
zz = (b - a) / m / np.sqrt(2 * pool * (1 - pool) / m)
print(round(float((np.abs(zz) > 1.96).any(axis=1).mean()), 3), round(float((np.abs(zz[:, -1]) > 1.96).mean()), 3))   # 0.248 0.048

# a permutation test for two groups of six: all 924 splits
g1 = np.array([12.1, 14.3, 11.8, 15.2, 13.0, 12.7])
g2 = np.array([14.9, 16.2, 13.8, 15.5, 17.1, 14.4])
both, obs = np.concatenate([g1, g2]), g2.mean() - g1.mean()
diffs = []
for chosen in itertools.combinations(range(12), 6):
    mask = np.zeros(12, bool)
    mask[list(chosen)] = True
    diffs.append(both[mask].mean() - both[~mask].mean())
print(round(float(obs), 2), len(diffs), round(float((np.abs(diffs) >= abs(obs) - 1e-9).mean()), 4), round(float(stats.ttest_ind(g2, g1).pvalue), 4))
# 2.13 924 0.0216 0.0152

Дальше#

На этом статистическая часть курса заканчивается; последний раздел посвящён случайным процессам. До сих пор все наблюдения были независимы. Последовательность слов, случайное блуждание по веб-страницам и состояния сэмплера обладают памятью: следующее состояние зависит от текущего. Следующая заметка вводит цепи Маркова — простейшую модель такой памяти — и их стационарные распределения, а n-граммную языковую модель и PageRank рассматривает как два примера таких цепей.

Литература#