Использование последовательного тестирования для уменьшения размера выборки
Привет, Хабр! Я Андрей Корнеев, аналитик команды Origination в Т-Банке. Наша команда работает над тем, чтобы клиент оформил продукт максимально быстро и комфортно, а потом захотел остаться с нами навсегда.
Команда большая, поэтому спектр задач — от развития конкретных продуктов до разработки и внедрения аналитических инструментов.
Наша команда проводит тысячи тестов в год, причем большинство из них — на бинарных метриках. И часто команда сталкивается с вопросами:
Как статистически понять, продолжать тест или нет в случае, когда наблюдаемый эффект сильно выше MDE, но до предрассчитанного размера выборки еще далеко?
Как уменьшить среднюю продолжительность теста для бинарных метрик? Конечно, существуют стандартные подходы к сокращению размера выборки, например стратификация и CUPED. Но на бинарных метриках они не дают сильного эффекта — либо нужны хорошие ковариаты, которые далеко не всегда есть.
Как понять, техническая метрика действительно просела или это случайный выброс?
Один из ответов на все эти вопросы — Group Sequential Test (GST), о котором и расскажу в статье. По пути обсудим:
Классический дизайн теста и почему он именно такой.
Концепцию последовательного тестирования.
Основные методы последовательного тестирования.
Как и почему работает GST.
Библиотеку в Python для использования GST.
Выводы.
Классический дизайн A/B-теста
Прежде чем перейти к обсуждению последовательного анализа, освежим в памяти дизайн классического A/B-теста.
Пусть— эффект от нашего изменения. Пусть у нас случай двух выборок, двусторонняя альтернатива. То есть
и , определяем :
— вероятность ошибки первого рода. Вероятность, что мы заметим эффект, когда его нет.
— вероятность ошибки второго рода. Вероятность, что мы не заметим эффект, когда он есть.
— минимальный детектируемый эффект.
Рассчитываем размер выборки, необходимый при заданных параметрах. Дожидаемся, пока размер набирается, считаем статистику, подводим итог. Все эти шаги делаются для того, чтобы контролировать вероятность ошибок первого и второго рода.
Вычисляя необходимый размер выборки, мы ожидаем, что вероятность принять альтернативную гипотезу, когда эффект совпадает с минимальным детектируемым, равна:
А вот вероятность ошибки первого рода мы контролируем, подсматривая ровно один раз за тест. Что будет с вероятностью ошибки первого рода, если мы будем подглядывать много раз?
Количество подглядываний | Вероятность ошибки 1-го рода |
1 | 0,05 |
2 | 0,08 |
5 | 0,14 |
10 | 0,19 |
20 | 0,25 |
100 | 0,37 |
Видим, что вероятность ошибки первого рода зависит от количества подглядываний и растет вместе с ним.
Поэтому выбирается ровно один момент, когда происходит подсматривание. Подглядывать нельзя. Или, может, стоит просто делать это правильно?
Последовательный анализ — метод, который описывает, как подглядывать правильно.
Концепция последовательного тестирования
Разбираться, почему возрастает вероятность ошибки первого рода, будем на примере z-теста.
Пусть = 0,05. Для двусторонней альтернативы граница, которую мы хотим пересечь, равна z-score = 1,96 для принятия припри
Прогоним 50 А/А на синтетических данных и будем равномерно подглядывать 10 раз на протяжении теста через каждые 200 наблюдений в вариации. Видим, что из 50 границу на одном из подглядываний пересекли 6, то есть вероятность отвергнуть нулевую гипотезу при отсутствии эффекта составила 0.12:
Вероятность ошибки первого рода при обычных подглядываниях
Видим, что вероятность ошибки первого рода не контролируется. Но что, если проблема не в концепции подглядывания, а в границах, по которым нужно принимать решение?
Концепция последовательного тестирования заключается как раз в том, чтобы как-то выстраивать границы для функции, по которой принимается решение. Так, чтобы вероятность ошибки первого рода контролировалась.
Например, так выглядит результат симуляций для метода GST. Видим, что из 50 синтетических A/A-тестов только в двух мы отвергли
Краткий обзор методов последовательного тестирования
1. SPRT — Sequential Probability Ratio Test Вальда. Функция, по которой метод Вальда принимает решение, — это отношение правдоподобий:
Здесь в числителе и знаменателе вероятность наблюдать полученные данные при условии, что верны и соответственно.
А границы:
Остановка, еслиили.
Преимущества:
Оптимальный метод с точки зрения ожидаемого размера выборки. Ускорение происходит в том числе на A/A-тестах, что делает метод более универсальным.
Не требуется заранее знать необходимый размер выборки.
Контроль мощности.
Недостатки:
Нет фиксированного времени остановки, поэтому за любое конечное время мощность ниже заданной. В том числе за время, необходимое стандартному z-тесту.
Данные должны собираться и анализироваться непрерывно для максимальной мощности и полноценного эффекта ранней остановки.
Библиотеку с методом реализовал мой коллега из команды Лаборатории прикладной статистики Витя Харламов:
Митап Tinkoff Product Analytics Meetup: A/B-тесты (offline)
meetup.tbank.ru2. AVI — Always Valid Interference. Можно выделить два вида этой группы методов: mSPRT и GAVI, хотя первый — подвид второго.
Always Valid Inference Tests позволяют проводить непрерывное тестирование во время сбора данных, не устанавливая заранее правило остановки или число промежуточных анализов. Мы представляем mSPRT и GAVI, но mSPRT — это частный случай GAVI, их преимущества и недостатки одинаковы.
Преимущества:
Не требуется заранее знать необходимый размер выборки.
Поддерживает потоковый и батчевый набор данных, но при батчевом наборе занижается вероятность ошибки первого рода.
Недостатки:
Требует от экспериментатора выбора параметров распределения, описывающего эффект в рамках альтернативной гипотезы. Этот выбор влияет на статистические свойства теста и оказывается нетривиальным. Если примерный ожидаемый размер выборки известен, он может быть использован для выбора параметра, но в таком случае теряется преимущество, связанное с отсутствием необходимости знать размер выборки.
3. Group Sequential Tests (GST). В этом методе в качестве функции используется обычная z-статистика, посчитанная на группе, а границы строятся на основе выбранной alpha-spending функции. Alpha-spending функция задает правило, по которому уровень значимостирасходуется на каждом этапе анализа, чтобы общий уровень значимости эксперимента не превышал значение. Как на примере с синтетическими данными выше, мы просто подстраиваем границы так, чтобы не нарушать вероятность ошибки первого рода при последовательном анализе.
Преимущества:
Ограниченное сверху время проведения теста, мы не выходим за пределы выборки, рассчитанной для стандартного z-теста.
тратится только в моменты подглядывания, что дает гибкость в этом вопросе.
Простая и привычная интерпретация из-за связи с z-тестом.
Нет необходимости непрерывно подглядывать, как в предыдущих методах, — можно учесть эффекты сезонности и другие нюансы.
Недостатки:
Не дает ускорения на тестах, где
Требует предрасчета размера выборки, как и при стандартном дизайне.
В классической реализации нет четкого контроля мощности, поэтому, хоть за определенный промежуток времени мощность выше, чем у метода Вальда, она оказывается ниже итогово.
Методология GST
Эта глава посвящена математическому обоснованию метода GST. Как я написал выше, мы просто смотрим на z-статистику на промежуточном анализе и сравниваем ее со скорректированными границами, чтобы сохранялся уровень значимости.
Опишу, почему и как это работает, для односторонней альтернативы. Для перехода к двусторонней альтернативе нужно заменитьнаи зеркально относительно нуля отобразить полученную границу.
Пусть у нас есть броуновское движение и мы хотим посмотреть, в какое времяпроцесс пересечет границув первый раз. Еслито известно:
— функция стандартного нормального распределения. Заметим, что— возрастающая функция, такая, чтоДопустим, мы подсматриваем, пересекло ли броуновское движение границу, только в моментыМожем назначить кумулятивную вероятность пересечения границыточкеопределивтак, чтобы она удовлетворяла следующему:
так, чтобы:
находится аналитически, а воттребуют численных методов интегрирования. Заметим, чтозависит только от выбораи предыдущих
В примере выше— alpha-spending-функция.
Идея GST заключается в том, что можно брать другие функции распределения α, которые строго возрастают по и удовлетворяют условиюНа основе последовательной траты(то есть, на основе распределения уровня значимости на каждом промежуточном этапе анализа) и вычисляются границы, чтобы вероятность ошибки первого рода контролировалась.
Результаты на синтетических данных
Идейно метод работает следующим образом: мы на каждой итерации считаем z−статистику по тесту, смотрим, какая доля выборки набралась, затем строим границу на основе предыдущих подглядываний и текущего размера выборки и смотрим, пересекла ли функция z−статистики границу.
В случае пересечения тест останавливается, в противном — ждём следующего подглядывания или набранной выборки.
Вот как это выглядит дляна синтетических данных:
Визуализация принципа работы GST
Главные вопросы, на которые точно хочется ответить:
Что с вероятностью ошибки первого рода?
Что с вероятностью ошибки второго рода?
Насколько уменьшается время, необходимое на подведение итогов?
По первому вопросу все достаточно ясно. Сам дизайн границ основывается на контроле вероятности ошибки первого рода, поэтому никаких неожиданностей:
Зависимость ошибки 1 рода от подглядываний
С мощностью ситуация несколько иная. В общем случае чем выше количество подглядываний, тем ниже мощность. Вот какая зависимость мощности от подглядываний при
Зависимость мощности от подглядываний
Видим, что при 128 подглядываниях теряется всего 4% мощности, что очень и очень неплохо. Размен в скорости за все это:
Ускорение времени, необходимого для принятия решения в долях
В итоге мы получаем, что, например, при 16 подглядываниях мы размениваем 3% мощности на ускорение в 34%.
Другие виды границ и их отличия
В предыдущих примерах границы были выстроены на основеЭто представитель power-family, где все функции имеют вид:
Мы тратим только восьмую часть альфы к середине эксперимента. Поэтому мощность особо не теряется, но пересечения границ случаются обычно после первой половины эксперимента. Чем больше x, тем больше будет потеря в мощности и выигрыш в скорости. Но есть и другие типы границ. Например, границы по Pocock имеют следующий вид:
При мы получаем . То есть при таких границах мы в среднем раньше останавливаем тест, но тут происходит потеря в мощности:
Потеря мощности при границах по Pocock
Ускорение времени, необходимого для принятия решения, Pocock
Использование в Python
Реализация на Python хранится на GItHub. Можно импортировать ее и пользоваться в своих целях. Основана на библиотеке расчета границ от Лана и Де Матса, реализованной на Fortran. Эту же реализацию брали за основу Spotify в своей известной статье сравнения методов последовательного тестирования.
В примере ниже показываю, как запустить GST на своем тесте в первый раз. Файлы из примера содержат массив из 0 и 1 по основной бинарной метрике.
from adaptiveGST import AdaptiveGST
import numpy as np
test_array = np.load('1007_13#test.npy')
control_array = np.load('1007_13#control.npy')
#Задаём переменные теста
p_0 = 0.09 #Базовая конверсия, она же историческая
mde = 1.5 # Изменение в процентах, которое ожидаем. То есть, p_test = p_0 * (1 + mde/100)
#Тип границ, которые используем
iuse = 3
phi = 4
#Массив долей выборок, когда были подглядывания. Пустой при первом подглядывании
peeking_array = []
gst = AdaptiveGST(
p_0,
mde,
alpha=0.05,
power=0.8,
test=test_array,
control=control_array,
peeking_array=peeking_array,
iuse=iuse,
phi=phi
)
result = gst.check_result(gst.test, gst.control)
peeking_array = result[2]
#Вывод результата
print(f'{result[0]}, набралось {result[1]} от необходимой выборки')
После этого сохраняется peeking_array — массив подглядываний, который после первого подглядывания состоит из одного числа. При дальнейших подглядываниях стоит подставлять массив, полученный после последнего подглядывания.
Вот как выглядит результат работы этого метода на одном из реальных тестов:
Пример GST на реальном тесте
Тест закончился бы спустя только 40% (!) выборки, если бы вместо обычного z-теста использовали этот подход.
Выводы
Когда дело касается принятия решений в бизнесе, скорость зачастую не менее важна, чем точность. Время — это деньги, а затянувшиеся тесты могут приводить к упущенным возможностям. Именно здесь на помощь приходит GST, способный существенно ускорить процесс принятия решения, сохранив при этом статистическую достоверность результатов.
Как и любая методология, GST имеет свои ограничения и особенности, которые важно учитывать. Разберемся, в чем его сильные и слабые стороны и почему его стоит применять, несмотря на некоторые минусы.
Основные недостатки:
Не подходит для метрик с долгим периодом созревания. Если результаты метрики становятся доступными только через длительное время (например, показатели возврата клиентов через полгода), последовательное тестирование теряет преимущество, так как требует регулярного пересчета статистики.
Менее точная оценка эффекта при ранней остановке. При досрочном завершении теста итоговый эффект может быть менее точным, так как метод не всегда предлагает встроенные механизмы для построения доверительных интервалов. Это делает результаты менее интерпретируемыми, особенно если требуется точная оценка разницы.
Зависимость от тех же допущений, что и z-тест.
Нет встроенного контроля мощности. Мощность теста напрямую зависит от выбранных границ и количества промежуточных анализов. Это может потребовать дополнительных симуляций и настроек, чтобы оптимизировать тест для конкретной ситуации.
Несмотря на вышеупомянутые ограничения, плюсы последовательного тестирования настолько значительны, что делают его одним из наиболее перспективных методов для оптимизации тестирования:
Экономия времени и ресурсов. В среднем с помощью последовательного тестирования можно ускорить A/B-тесты на 30—35%, а в ряде случаев — сократить их продолжительность на 60—70%. Это огромная разница, особенно для тестов с участием больших выборок.
Возможность принятия решений на ранних этапах. Если в процессе теста наблюдается явное доминирование одной из вариаций, последовательное тестирование позволяет зафиксировать победителя и завершить эксперимент значительно раньше, чем при использовании классических fixed-horizon-методов.
Гибкость в настройках. Вы можете выбирать различные функции и границы для принятия решений, адаптируя тест к конкретным целям: максимизация скорости, сохранение мощности, баланс этих параметров. Это делает метод универсальным инструментом для множества сценариев.
Простота интерпретации. В своей основе последовательное тестирование остается вариантом классического z-теста. Если проводить анализ только один раз, в самом конце эксперимента, результат будет идентичен традиционному подходу. Это позволяет использовать привычные метрики и статистики, не путая конечных пользователей.
Почему это важно для вашего бизнеса? Последовательное тестирование становится настоящим инструментом конкурентного преимущества, когда вам нужно:
Быстро принимать решения на основе данных.
Снижать затраты на тестирование.
Максимально эффективно использовать ограниченный трафик или выборку.
Сохранять при этом статистическую достоверность.
Если в вашей компании регулярные эксперименты — это важная часть бизнес-процессов, внедрение последовательного тестирования может не только ускорить процессы, но и повысить их качество
Последовательное тестирование — это не просто модный инструмент, а реальный способ адаптироваться к современным вызовам, где решения нужно принимать быстро, но без потери точности.