Шанс побить всех — теория

A/B эксперименты, на мой взгляд, один из самых мощных инструментов для проверки придуманных гипотез (относительно чего угодно — целевой аудитории, юзабилити, маркетинговых ходах и решениях, … ). Говоря об экспериментах, всегда возникает естественное желание оценить достоверность полученных выводов. Метод «на глаз», как правило, работает сомнительно. На помощь приходит «шанс побить» — та самая магия, которая позволяет вовремя остановить эксперимент и быть более-менее уверенным в его результатах. Эту же магию колдует Google Optimize. Про шанс побить есть шикарная статья на Хабре. Она и является первоисточником этой заметки, но я постараюсь сделать некоторые выкладки более подробными. Ну, и от себя кое-что добавить. Тем не менее, первоисточник также крайне рекомендую прочитать ввиду наличия интересных комментариев и пояснений, которые я не стала повторять.

Поскольку нам очень хочется воспользоваться аппаратом математической статистики, то нам понадобится понять, с чем мы имеем дело и добавить немного условностей. Каждый посетитель сайта по сути является некой бернуллиевской случайной величиной с параметром \(p\). Параметр \(p\) будем называть истинной конверсией — неким внутренним желанием и готовностью посетителя купить. С вероятностью \(p\) посетитель сайта совершит конверсионной действие или с вероятностью \((1-p)\) его не совершит. Отдельно стоит отметить, что в случае конверсии сайта (в лиды или продажи) значение p обычно невелико: \(p\in[0, 0.05]\)

Но величину p мы замеряем за некоторый промежуток времени. Поэтому вместо распределения Бернулли нам потребуется биномиальное распределение, которое обычно интерпретируют как число успехов в серии одинаковых независимых испытаний Бернулли с вероятностью успеха \(p\) в каждом испытании. Здесь стоит обратить внимание на вынужденное предположение, что все наши испытания имеют одинаковую \(p\), что вообще говоря неверно. Все посетители сайта имеют разную вероятность покупки, однако «в среднем по больнице» предположение можно использовать.

Считаем плотность вероятности

Вспомним формулу Байеса. Из определения условной вероятности получим, что \( P(AB) = P(A) \cdot P(B|A)\) для любых двух событий A и B.
Абсолютно аналогично \( P(BA) = P(B) \cdot P(A|B)\). Воспользуемся тем, что \( P(BA) = P(AB)\), и в результате из \( P(A) \cdot P(B|A) = P(B) \cdot P(A|B)\) получим знаменитую формулу Байеса: \( \begin{equation} P(A|B) = \frac{P(A) \cdot P(B|A)}{P(B)} \end{equation} \). Обозначим за s количество успехов, за f — количество неуспехов. Тогда по формуле Байеса:
\(P(p=x | (s,f)) = \frac{P(p=x) \cdot P((s,f)| p=x)} {P((s,f))} \) (1)
При этом мы знаем, что \(P((s,f)| p=x) = K(s,f) \cdot x^s (1-x)^f \), где \(K(s,f) = \frac {(s+f)!} {s!f!}\) — биномиальный коэффициент. Из-за факториалов его немного муторно считать.

В формуле (1) кроме этого множителя есть еще неизвестные \(P((s,f))\) и \(P(p=x)\). Займемся первым. Исходя из свойств полной вероятности:
\(\int_{0}^{1}P(p=x|(s,f)dx = 1\)
Подставим нашу формулу (1):

\(\int_{0}^{1}P(p=x|(s,f)dx = \int_{0}^{1}\frac{P(p=x) \cdot P((s,f)| p=x)} {P((s,f))} = 1\)

Подставим формулу биномиального распределения и вынесем из интеграла \(P((s,f)) \), так как она не зависит от x:
\(P((s,f)) = \int_{0}^{1} P(p=x) K(s,f) x^s (1-x)^f dx = K(s,f) \cdot \int_{0}^{1}P(p=t) t^s (1-t)^f dt \) (выносим за скобки \(
K(s,f)\) и меняем \(x\) на \(t\), чтобы на следующем шаге у нас не перепутались переменные).

Вернемся к формуле (1) и подставим полученное значение для \(P((s,f)) \):
\(P(p=x | (s,f)) = \frac {P(p=x)K(s,f)x^s (1-x)^f} { K(s,f) \cdot \int_{0}^{1}P(p=t) t^s (1-t)^f dt} = \frac {P(p=x)x^s (1-x)^f} {\int_{0}^{1}P(p=t) t^s (1-t)^f dt}\)

Интеграл в знаменателе можно численно посчитать.

Остается вопрос, что делать с P(p=x). Здесь существует два подхода: частотный и байесовский. Частотный предполагает, что все значения p равновероятны (т.е. у нас есть только данные эксперимента, а что было «до» — забываем). Байесовский подход говорит нам, что мы можем задать p исходя из некоторого априори с помощью бета-распределения. Кстати, если взять параметры бета-распределения равными 1, то получим непрерывное распределение (а это частотный подход).

Бета-функция: \(B(x,y) = \int_{0}^{1}t^{x-1}(1-t)^{y-1}dt\)
Плотность бета-распределения: \(f(x) = \frac {1} {B(\alpha, \beta)} x^{\alpha-1}(1-x)^{\beta-1}\)
Эти две формулы подозрительно напоминают формулы, которые были получены выше.

Введем функцию \(T(x) = x^{x+\alpha-1}y^{y+\beta-1}\). При \(\alpha=1\) и \(\beta=1\) получим \(T(x) = x^s(1-x)^f\). \(\alpha\) и \(\beta\) можно выбрать и другим способом (передаем привет байесовскому подходу), но мне в голову не приходит хорошего способа корректно это сделать (посмотрите исходную статью, где приводится пример для прогноза).

Финальная формула будет иметь вид \( P(p=x|(s,f)) = \frac {T(x)} {\int_{0}^{1}T(t)dt}\)
Для этой функции плотности распределения можно построить график и посчитать доверительные интервалы с нужной доверительной вероятностью. На мой взгляд, для науки нужно 0.95 и более, а для бизнеса можно взять 0.9 (но лучше не меньше).

Шанс побить

Будем предполагать, что варианты в эксперименте независимые, т.е. \(P(A|B) = P(A)\). Для байесовского подхода это еще нужно показать (так как для обоих вариантов есть некое априори), но так как мы взяли за основу частотный подход, то независимость вариантов определяется схемой нашего эксперимента (тем, как мы его организовали). В основном независимость гарантируется тем, что один и тот же посетитель видит только один вариант. Опять же, это не совсем так, так как посетитель определяется браузером и печеньками, а, скажем, на работе и дома — два разных браузера, и вообще говоря, один и тот же человек теоретически может увидеть разные варианты, и они как-то на него повлияют… Тем не менее, этим фактом обычно пренебрегают ввиду малости его влияния (а где влияние больше, там есть возможность помудрить со сквозной аналитикой).

Вспомним формулу полной вероятности: \(P(A) = \sum_{0}^{N} P(H_i)P(A|H_i)\). Аналогично вместо конечной суммы может быть бесконечная сумма или интеграл. Главное, чтобы события \(H_i\) охватывали все возможные исходы.

Заметим, что \(P(p \lt x|(s,f)) = \int_{0}^{x} P(p=t|(s,f)) dt \)

\(P(W) = \int_{0}^{1} P(p=x) P(W|p=x) dx \)

Предположим, то в нашем эксперименте было N вариантов и были получены значения \((s_i, f_i), i=1,..,N\). Обозначим как \(CTBA_i\) (Chance to beat all) вероятность того, что вариант i лучше всех остальных вариантов.

\(CTBA_i = P(best=i) = P(p_i \gt p_j, \forall j \not = i) = \int_{0}^{1}P(p_i=x)P(best=i | p_i = x)dx\)
\(P(best=i|p_i = x) = P(p_i \gt p_j, \forall j \not = i| p_i = x) = P(p_j \lt x \forall j \not = i| p_i = x) = P(p_j \lt x, \forall j \not = i) = \prod_{i \not = j} P(p_j \lt x) \)
Подставим в первое второе и получим, что

\(P(best = i) = \int_{0}^{1}P(p_i=x) \prod_{i \not = j} P(p_j \lt x) dx\)
Собственно, это финальная формула для расчета шанса побить. Для каждого эксперимента нужно будет рассчитать свою \(P(p_i=x) = P(p_i=x | (s,f))\), для которой вывели формулу в первой части.

Примерчики и картинки — в следующей части. Эта слишком большая получилась.

Добавить комментарий