Мощность А/В-теста с неравными выборками
Что, если sample ratio не 50/50, а 10/90?
Зачем это нужно и как с этим жить
Привет 👋 ! Вернемся к разговору про t-тест, на этот раз в контексте дизайна эксперимента 🧐. Год назад Iskander Mir уже написал отличную статью, в которой приводил пример необходимости такого дизайна: бизнес хочет тестировать смелые двусторонние гипотезы. Последний термин означает, что изменения могут дать как положительный, так и отрицательный эффект. И, конечно, снижение метрик на малой доле пользователей не так плохо для бизнеса, как на половине клиентов.
Приведу второй пример, который не так очевиден, но очень интересен и полезен. Большая часть крупных веб-сервисов — это агрегаторы (концепция Uber для всего на свете), например классифайды, такси и райдшеринг и тд. Их особенность в том, что они представляют собой маркетплейсы, а значит предложение на них ограничено (еще Andrew Chen нас учил, что большая часть проблем и возможностей маркетплейса приходится на supply часть). Если мы увеличим спрос в таргетной группе, она съест большую часть предложения, и контрольной ничего не достанется. Тем самым контрольная группа уже не будет таковой, потому что она изменилась по сравнению тем, какой она была бы без воздействия. Это и есть пресловутый сетевой эффект, для которого придумывают switchback, квази-эксперименты и другие методы causal inference (я уже разбирал их в отдельной статье). Причем здесь sample ratio? Если таргетная группа будет небольшой (допустим 1%), то сетевой эффект проявиться в гораздо меньшей степени, чем при 50%. На этом кстати основывается один из методов учета сетевого эффекта — многоуровневый дизайн.
Эта статья является дополнением статьи Искандера, и вместо моделирования данных содержит теоретические выкладки (double check это всегда хорошо), а также предлагает удобный фреймворк для дизайна подобных тестов.
Теория
Ты уже знаешь из прошлой статьи, что расчет длительности теста должен соответствовать методу расчета стат-значимости 🤫. Очень хочу чтобы эта фраза стала аналитическим бэнгером вместо текущих заблуждений. Самая популярная формула для sample size содержит в себе дисперсию изучаемой статистики, которая в случае сравнения двух средних выглядит так, как показано на картинке 2.
Но как уже много раз обсуждалось на cross-validated (и мной), лучше всегда считать дисперсии неравными и использовать Welch test. К сожалению, я не знаю, как правильно рассчитать размер выборки / MDE для данного критерия. Более того, этот вопрос на cross validated также оставлен без ответа 😩. Проблема как минимум в том, что мы не знаем даже критического значения T-статистики, т.к. количество степеней свободы в этом критерии — случайная величина (чуть позже мы вернемся к этому вопросу).
Можешь написать мне в телеграмм, если у тебя есть теоретически обоснованное решение или симуляции на данных.
Что же тогда делать 🤔
В этой статье мы будем использовать вариант с pooled variance. Объясню, почему я считаю это релевантным выбором:
- Во-первых, на этапе дизайна неизвестно, будут ли различаться дисперсии, и какие они вообще будут. Разве что дисперсию контрольной группы можно оценить по историческим данным, предполагая что она не изменится по сравнению с пред-экспериментальным периодом.
- Во-вторых, тестируя популярные веб-сервисы, мы часто имеем дело с настолько большими выборками, что группы в разбиениях 50/50 и 80/20 имеют почти не отличающиеся дисперсии с довольно точной их оценкой (не зря же говорят, что вместо t-теста на таких размерах можно использовать z-test), отличаются только дисперсии средних. А значит внутри разбиения 80/20 обе группы будут иметь примерно одинаковые дисперсии.
- В-третьих, в большом и давно работающем сервисе скорее всего эксперимент не сделает настолько сильное изменение, что распределение таргетной группы поменяет свою форму. Скорее всего, мы лишь немного сместим средние. И на таких данных оба варианты t-критерия (pooled variance и Welch’s) дадут примерно одинаковые результаты.
Так что если ваши группы не отличаются на несколько порядков (не 99/1), вполне можно использовать pooled variance (разные размеры выборок, но равные дисперсии).
Калькуляторы умеют?
Лучший калькулятор от Booking, к сожалению, не позволяет указать пропорции групп (на момент написания статьи). Cамые известные (от Evan Miller, SurveyMonkey, Optimizely, VWO и Mindbox) мало того, что не позволяют указать sample ratio, так еще и только для биноминальных метрик).
Не будем расстраиваться 😳🙁, а сделаем его сами🤯 (уже во время написания статьи появился калькулятор, который всё-таки смог).
Слева на картинке №3 (из блога твиттера) схематично изображены все необходимые понятия. Decision cutoff — линия, равная критическому значению распределения при p-value = 0.05 (область, выкрашенная в рыжий, является стат-значимым отклонением). Зеленая область — это часть второго распределения, которая как раз выходит за этот decision cutoff. Площадь этой части определяется критическим значением уже второго распределения.
Напомню, что критическое значение считается как Z-статистика * стандартное отклонение (вы знаете это из доверительных интервалов). На картинке 4 показан вывод формулы MDE для выборок одинаковых дисперсий. Значение статистики для β берем отрицательное, поскольку нас интересует левая часть распределения (см. картинку 3). В случае, когда выборки имеют одинаковый размер (сплит 50/50), мы получаем знакомую формулу (последняя строчка) для размера каждой группы.
Внимательный читатель спросит — почему мы смотрим z-, хотя должны смотреть t-статистику. А помнишь, что в прошлом разделе я обещал вернуться к разговору о степенях свободы? Так вот, в онлайн А/В-тесте мы заранее не знаем, сколько именно будет юнитов в каждой выборке, а значит не знаем количество степеней свободы для t-распределения => не можем точно рассчитать t-статистику. Более того, в случае статистики для β мы должны использовать смещенное t-распределение, для которого в принципе не существует таблиц значений. Поэтому пользуемся упрощением — заменяем распределение Стьюдента нормальным. Так что в следующий раз, когда на собеседовании вас спросят, чем отличается t-тест от z-теста, просто напомните, что стандартная формула для размера выборки/мощности делает расчеты для z-теста.
На всякий случай напомню, что для p-value 5% и мощности 80% константы в скобке равны 1.96 и 0.84 соответсвенно. Для других значений вы всегда можете найти константы через этот калькулятор. Для односторонних гипотез нужно использовать в 2 раза меньшую площадь под графиком для каждого конца (Lower Tail и Upper Tail), поэтому критическое значение изменится (1.65 для p-value 5%).
Зависимость от пропорции 💹
Мы вспомнили формулу для сплита 50/50. Как теперь посчитать размер выборки для другой пропорции? Помнишь, Искандер говорил что этот параметр влияет именно на мощность? Сейчас я тебе расскажу как. В качестве основы воспользуемся картинкой 4 и учтем в ней равенство дисперсий (мы же за pooled variance❗).
Далее есть 2 связанных, но разных задачи:
- Найти размер одной из выборок (например, минимальной) для заданных пропорций сплитования -> найти общий размер выборки
- Определить, насколько отличается мощность и размер при изменении сплитования с 50/50, т.е. сравнить с минимальным значением.
Для первой задачи: Если принять за r отношение таргетной группы к контрольной (n2=Nt= Nc*r = n1*r), то получится формула (см. картинку 5, ее можно найти стенфордских лекциях по статистике, тебе нужна 11я) для размера последней (n1). Путем несложных преобразований получаем формулу общей выборки для теста. Что интересно — если одна из групп становится во много раз больше другой, то и размер общей выборки также увеличивается во столько же раз (почти линейно). Также, если мы сделаем замену x=1/r, то получим такую-же формулу относительно x, что подтверждает тот факт, что не важно какая из групп больше (контрольная или таргетная), главное их соотношение.
Теперь ко второй задаче: Сделаем замену n=n1 + n2, p = n1/n. Её суть должна быть понятна: обычно у нас есть выделенный кусок трафика (n), который мы должны поделить на контрольную и таргетную группу, варьируя параметр “доля контрольной группы (p)”. Функцию от последнего параметра я и хочу получить. Выкладки для дисперсии разницы средних можно увидеть на картинке 6 (и этот результат можно найти в статье).
Давай поисследуем получившуюся функцию. Напомню, σ и n — это константы, а p измеряется от 0 до 1. Выражение p*(1-p) — перевернутая парабола c центром в 0.5. Она в знаменателе, а гипербола при x>0 монотонно убывает, значит нам надо перевернуть график (форма, конечно, не сохранится, но очертания похожи, и я покажу, что там квадратичный закон). Также мы заметим что в точках 0 и 1 данная функция стремится к бесконечности. Можно было бы воспользоваться Python/R чтобы изобразить данную функцию, но мои лишние пару минут как аналитика стоят дорого, поэтому просто вобьем ее в WolframAlpha:
Искандер говорил, что максимальная мощность достигается при сплите 50/50, и теперь мы понимаем почему (при нем дисперсия минимальна). Учитывая прямую пропорциональность, отношение размера выборки при неравном сплите к размеру выборки оптимального разбиения 50/50 — это отношение дисперсии сплита к дисперсии оптимального (p=0.5):
Этим результатом уже можно пользоваться, подставляя нужный p. Для примера, если p=1/5 (разбиение 20/80), требуемый размер выборки больше оптимального 50/50 в 25/16 =1.5625 раз. Для других сплитов результат представлен на картинке 9.
Нюансы, о которых стоит знать
Во-первых, уверен что многие хоть раз встречались с кейсом: запустили А/В-тест на всю аудиторию сплитом 50/50, нашли эффект, малую долю пользователей оставили в контроле чтобы проверить долгосрочный эффект (т.н. холдаут). И в большинстве кейсов никакой долгосрочный эффект не наблюдается. Такую ситуацию часто списывают на эффекты новизны и привыкания, хотя проблема в другом. Если посмотрим на таблицу выше, то увидим, что при малом холдауте (1%), общий размер аудитории должен быть в 25! раз больше, чем при оригинальном тесте, чтобы иметь возможность поймать эффект с такой же мощностью. Так что в следующий раз серьезно подумай, а нужен ли тебе холдаут.
Во-вторых, представим гипотетическую ситуацию: у тебя есть слой для запуска эксперимента, и для нового теста ты разбил пополам весь свободный трафик. И тут ты узнаешь, что освободился еще кусок трафика, и думаешь, стоит ли добавить его в таргетную группу, чтобы собрать больше данных? Тут палка о двух концах: с одной стороны, увеличение общей популяции в тесте должно повысить мощность, с другой стороны изменение пропорции контроль/таргет должно понизить мощность. Вопрос — какой эффект сильнее??
На самом деле все просто. Предположим, изначально у нас группы по n юнитов, и затем в контрольную или таргетную группу мы добавляем еще x*n юнитов. Выкладки на картинке 10 (используют формулу с картинки 4). Тут мы решаем обратную задачу — имея sample size одной из групп, нужно посчитать MDE для двух кейсов. Если взять их отношение, то видно что оно меньше 1, а значит во втором кейсе мощность больше. Этот вывод интуитивно понятен — чем больше пользователей добавлено в тест, тем лучше.
В-третьих, еще один интересный момент! Он не относится к статье, поскольку я рассматриваю вариант равных дисперсий, но все же стоит о нем знать. Помнишь, в прошлой статье я говорил, что тест Уэлча (а на самом деле все семейство t-тестов) требует, чтобы большая выборка имела большую дисперсию? Так вот, в обратном случае можно получить странные результаты не только для ошибок I рода, но и для II рода. Вот тут на симуляциях показано, что дисбаланс (не 50/50) может увеличить мощность теста. Оно и понятно — если группе с большей дисперсией дать больше число семплов, то точность оценки среднего увеличиться.
Внимательнее смотрим на формулу
Можешь пропустить этот раздел, если тебе не очень важна математика. Помнишь, я обещал доказать, что формула имеет квадратичный закон. Для этого давай попробуем упростить ее. Изначально я думал разложить каждый член знаменателя в ряд Тейлора, как меня учили в 11 лет назад в первом семестре в моем alma mater. Ведь для 1/(1-p) получается самое простое разложение: 1 + p+ p² +…, а для 1/p нужно сделать замену x = 1-p. Но внимательный читатель заметит, что эти разложения сделаны в разных точках (p=1 и p=0 соотвественно).
Сделаем замену, как показано на картинке 11. Поскольку нас интересует отклонение от 0.5 (т.е. от сплита 50/50), мы возьмем это за точку, от которой начинается разложение Тейлора. Да, при больших z формула почти пропорциональна z (я это тоже уже говорил), но вот что происходит при малых!? Скобку в знаменателе мы разложим в ряд Тейлора -2–4z-8z²-16z³…, а числитель так и оставим. Итого, у нас получится ряд, показанный на картинке 12, в котором минимальная степень многочлена равна 2м.
А как же мощность ❔❔
Ну и последнее, что хочется обсудить в нашей математике. В этой статье, судя по названию, мы должны были обсуждать именно мощность, а не размер выборки, но сделано этого лишь для краткости. Дело в том, что вывести такую простую формулу для мощности нельзя, т.к. мощность — это фактически персентиль, т.е. считается как интеграл плотности вероятности. А, как известно, для нормального распределения он не выражается в элементарных функциях, и является обратной функцией к z-статистике.
Бинарные переменные
Тут все просто, ведь биноминальный тест — это аналог t-теста для бинарных переменных. Различие только в том, что дисперсия не оценивается по стандартному отклонению выборки, а используются теоретические значения для биноминального распределения: D=n*p*(1-p). Вспомним, что классическое биноминальное распределение оценивает кол-во успехов в n испытаниях, а нас интересует конверсия, т.е. успех в одном испытании, значит дисперсия конверсии в n раз меньше, т.е. D=p*(1-p). Итого, подставив это в формулу для sample size, получаем:
Надо понимать, что использование аналитической формулы для дисперсии вместо ее выборочной оценки повышает точность (мощность) критерия. Есть важный момент — что такое p в этой форумуле? Это т.н. pooled proportion.
Неоднократно обсуждалось, что при увеличении первоначальной конверсии растет и мощность. Теперь, имея на руках финальную формулу (перевернутую параболу), мы понимаем что все работает наоборот, т.к. точка 0.5 — это глобальный максимум. Более того, часто именно p=0.5 используют в качестве верхнего предела при построении доверительных интервалов. Так что эту статью можно смело называть аналогично прошлой, как “История еще одного обмана”. Надо учитывать, что если конверсия и так большая, то effect-size должен быть огромным, поэтому стоит задуматься а нужно ли вообще проводить эксперимент.
К сожалению, именно биноминальные переменные очень чувствительны к нарушениям предположений, которые мы обсуждали в прошлой статье. Поэтому доверительные интервалы, а значит и формула выше, требуют дополнительных коррекций (читай плюсы-минусы всех видов дов. интервалов для пропорций тут).
Как делать поэтапную раскатку
Изначально я не планировал этот блок в данной статье, но на собесах я заметил, что не все еще в курсе парадокса Симпсона. Допустим ты, перестраховываясь, запустил эксперимент на небольшое кол-во пользователей и проследил, что нет больших дропов в метриках. Затем ты прочитал эту статью и захотел повысить мощность теста, увеличив долю таргета до 50%, и раскатил на часть контроля. Так вот — так делать нельзя, если метрики контроля на первом этапе отличны от метрик контроля на втором этапе (например, первоначально тест запущен в рабочие дни, а потом была дораскатка в выходные), причины прочитай по ссылке выше.
Как правильно поступить в этом случае — всегда держать долю контроля/таргета постоянной и равной финальному варианту (50/50, или даже 80/20 в пользу таргета). А параметр, который нужно изменять — доля пользователей в эксперименте (т.е. и контроль, и таргет) от всех пользователей. Это называется staged/phased rollout, и об этом уже много раз рассказывал Uber.
Конечно, в случае поэтапной раскатки мобильных приложений нам приходится использовать функционал aпп-сторов, что влечет за собой использование первого неправильного подхода. Единого подхода к решению этой проблемы нет, но вот Netflix делает synthetic allocation, т.е. умным способом отбирает контрольную группу из всех новых установок старой версии приложения.
Если таргетных групп несколько
Важно понимать, какую именно гипотезу вы проверяете. Ровно такой же вопрос возникает при применении поправок на множественное сравнение. Есть 2 принципиально разных задачи(количество групп в тесте обозначим как N):
- Понять, выигрывает ли значимо хотя бы одна группа у контроля. Кол-во сравнений в таком случае равно N - 1
- Попарно сравнить группы между собой и понять, отличаются ли значимо между собой хотя бы 2 из них. Кол-во сравнений здесь равно N*(N-1)/2.
Обычно при запуске А/В-тестов с несколькими таргетными группами я склоняюсь к первому варианту, поскольку он отвечает именно на тот вопрос, который ставит бизнес: хотя бы одно из изменений улучшает текущее состояние или нет? Зачем сравнивать 2 таргетные группы между собой, если мы уже знаем, что они обе не дают значимого прироста?!
Теперь при подсчете размера выборки или мощности нужно:
- Сделать поправку Бонферрони, подставив в формулу расчета размера выборки для Z-статистики скорректированный p-value/(N-1), поскольку количество сравнений и есть количество проверяемых гипотез.
- При подсчете pooled variance нужна оценка дисперсии (в самом начале обсудили, что скорее всего она равна в выборках), а также размеры контрольной и самой маленькой из таргетных групп.
- Затем применяем все то, что мы уже обсудили в этой статье.
С другой стороны, если тебе не интересно какая именно из групп лучше контрольной, а важен лишь сам факт что такая группа есть, то можешь сделать всего 1 тест — ANOVA, который кстати при 2х выборках даст тот же результат, что и t-тест. BTW, для ANOVA также возможно множественное тестирование (нет, я не про post-hoc Tukey’s test), и размер выборки для такого теста это чуть более сложная тема.
Удачного дизайна тестов, и до скорых встреч!
P.S.: Если тебе понравилась стать, в качестве благодарности можешь купить мне кофе на https://www.donationalerts.com/r/stats_data_ninja или https://buymeacoffee.com/koch.