Метрика-отношение в A/B: считаем ошибку с учётом связи числителя и знаменателя
В эксперименте сравнивают выручку на заказ: общую выручку группы делят на число заказов. Один пользователь оформил десять покупок, другой — одну, третий ничего не купил. Если посчитать стандартную ошибку по чекам как по независимым наблюдениям, можно получить слишком уверенный вывод. Вариант назначали пользователю, поэтому неопределённость нужно оценивать по пользовательским парам «выручка, заказы», сохраняя связь между ними.
Отношение сумм отличается от среднего отношений
Для каждого назначенного пользователя соберём X — его выручку за полное окно, Y — число заказов за то же окно. Целевая метрика равна сумме X, делённой на сумму Y. Пользователь без покупок имеет пару (0, 0) и остаётся в массиве назначенных. Делить X на Y для него нельзя, но для отношения групповых сумм это не требуется. Среднее индивидуальных чеков отвечало бы другому вопросу и иначе взвешивало активных покупателей.
Выручка и число заказов обычно связаны: у активного покупателя больше и того, и другого. Поэтому нельзя отдельно оценить ошибки числителя и знаменателя и сложить их без поправки на совместное изменение. Метод дельты учитывает эту связь через ковариацию. Он приближает поведение отношения около наблюдаемых средних и полезен на достаточно больших независимых выборках со стабильным знаменателем.
Удобная форма через остаток пользователя
Пусть R — отношение средних X и Y. Для каждого пользователя вычислим Z = X − R × Y. Его среднее равно нулю с точностью вычислений. Оценка дисперсии отношения равна выборочной дисперсии Z, делённой на n и квадрат среднего Y. При раскрытии квадрата получается та же формула с дисперсиями X, Y и членом −2R × Cov(X,Y). Такой способ проще реализовать и сложнее случайно забыть связь числителя со знаменателем.
from statistics import mean, variance, covariance
from math import sqrt
rows = [(0,0),(100,1),(300,2),(600,3),(400,2),(200,1)]
x = [a for a,b in rows]
y = [b for a,b in rows]
n = len(rows)
assert n > 1 and mean(y) > 0
ratio = mean(x)/mean(y)
z = [a-ratio*b for a,b in rows]
var_ratio = variance(z)/(n*mean(y)**2)
expanded = (variance(x)+ratio**2*variance(y)-2*ratio*covariance(x,y))/(n*mean(y)**2)
se = sqrt(var_ratio)
print({'ratio':round(ratio,3), 'delta_se':round(se,3),
'normal_ci95':(round(ratio-1.96*se,3),round(ratio+1.96*se,3))})
assert abs(var_ratio-expanded) < 1e-9
assert abs(ratio-1600/9) < 1e-9
assert abs(mean(z)) < 1e-9Как перейти к разнице вариантов
В каждой группе отдельно получаем отношение и его дисперсию на уровне пользователя. Для независимо назначенных групп дисперсии разницы складываются; стандартная ошибка — квадратный корень суммы. При большой выборке нормальный интервал строят вокруг R_B − R_A. Пользователь должен принадлежать только одной группе. Если варианты назначались магазинам, такие пользовательские пары ещё не дают независимые единицы: сначала потребуется учитывать кластерный дизайн.
Маленький набор в коде нужен для проверки равенства двух формул, а его нормальный интервал не следует использовать как решение о запуске. В рабочем анализе посмотрите распределение числа заказов, долю нулей и вклад крупнейших покупателей. Когда знаменатель почти нулевой или несколько клиентов дают почти всю выручку, линейное приближение может быть слабым. Сверка с bootstrap по пользователям и оценка устойчивости помогают понять, хватает ли данных для выбранного метода.
Сохранить смысл бизнес-результата
Рост выручки на заказ может сопровождаться падением числа заказов и общей маржи на назначенного пользователя. Поэтому рядом с отношением нужны заранее выбранные показатели объёма и экономики. Если новый интерфейс отталкивает мелкие покупки, средний чек способен вырасти без улучшения общего результата. Расчёт ошибки отвечает за точность конкретного отношения, а набор метрик — за полноту продуктового решения.
Для повторяемого отчёта храните пользовательские X и Y либо достаточные суммы: n, суммы X и Y, квадраты и произведения. Сверьте групповые суммы с заказами, сохраните нулевые пары и одинаковое окно. Тогда аналитик сможет воспроизвести оценку и объяснить, откуда взялась точность, не выгружая заново все строки чеков.
Продолжить работу с данными
В «A/B тесты и анализ данных на Python» вы отработаете выбор продуктовых метрик, бутстрап и доверительные интервалы. Эти навыки помогут проверить устойчивость отношения на своих данных и связать его с объёмом заказов и решением команды; программа курса даёт основу для полного анализа эксперимента. Откройте программу платного курса «A/B тесты и анализ данных на Python».
Продолжить на практике
- A/B тесты и анализ данных на Python ↗
Практический курс по A/B-тестированию и продуктовым метрикам: формулируем гипотезы, считаем размер выборки, запускаем эксперименты и анализируем результаты. От первой идеи до внедрения изменений в продукт — без «воды» и лишней теории.
