Десять тысяч A/B тестов
Большой текст. Будет интересен тем, кто знает, что такое A/B тесты и статистическая значимость.
A/B тесты полезная штука для валидации гипотез, но не такая простая как кажется — легко ошибиться. Если о статистической значимости и p-значениях большинство знает, то вот о более хитрых возможностях ошибиться — нет.
Одна из проблем: repeated significance testing error (повторные ошибки тестирования значимости). Умные люди пишут (русский перевод), что выборка должна быть фиксированной, например “в тесте поучаствует 1000 посетителей”. После чего тест нужно обязательно завершить и подсчитать результаты.
Нельзя завершать тест досрочно, если он вдруг показал статистическую значимость раньше. Нельзя держать тест запущенным так долго, пока какой-то вариант не покажет статистическую значимость(без ограничения на размер выборки).
Эта мысль контринтуитивна для меня. Я знаю, что про это пишут люди, которые понимают в статистике больше чем я (я понимаю так себе). Но я не мог понять до конца и осознать по настоящему почему оно работает так. Мысли об этом меня преследовали и воскресной ночью я понял — надо сделать модель и просимулировать всё это!
Я сделал модель, которая симулирует множество A/B тестов, сравнивая две гипотезы с разной конверсией. В каждой симуляции трафик случайным образом распределяется между двумя версиями. Каждый симулированный посетитель случайным образом конверится, согласно конверсии у гипотезы. Мы собираем статистику и оцениваем:
- ситуации с досрочным завершением теста, если появилась статистическая значимость;
- ситуации завершением с ограничением по выборке
- и ситуации когда тест идет бесконечно долго, пока не появится статистическая значимость в одном из вариантов.
Сам код можно найти на Гитхабе. Также я там подробнее описал подход к симуляции. Если вы увидели ошибку в коде или же расчетах — пожалуйста, расскажите мне (@qetzal в Телеграме) — я буду очень благодарен (я не настоящий программист и статистик.
Ниже я расскажу про результаты (много чисел). Я просимулировал три ситуации:
- две гипотезы сильно отличаются по конверсии,
- отличаются немного
- и не отличаются совсем
В каждой ситуации мы смотрим и на результат после фиксированной выборки (26000 посетитилей, то рекомендованное число для 3% baseline конверсии, обнаружения разницы в 20% и 95% стат. значимости). Каждая ситуация была просимулирована 10,000 раз — проценты ниже отображают ситуации от всех симуляций.
Ситуация первая — гипотезы сильно отличаются по конверсии
У контрольной версии конверсия 3%. У тестовой - 2.15%.
- В 99.6% случаев после фиксированной выборки мы получили правильный и статистически значимый результат.
- В 0.03% случаев после фиксированной выборки мы получили не статистически значимый результат.
- В 87% случаев статистическая значимость наступила раньше чем прошла вся фиксированная выборка. Результат был правильным (мы определили, что тестовая версия хуже конвертит). То есть тут мы могли завершить тест раньше чем прошла вся фиксированная выборка и были бы правы.
- В 13% случаев статистическая значимость наступила раньше чем прошла вся фиксированная выборка. Но результат был неправильным, мы бы ошибочно посчитали, что контрольная версия конвертит хуже, хотя это не так (это тестовая заметно конветит хуже).
Вывод: Фиксированная выборка показала значимый и правильный результат в 99.6% случаев (ожидаемо).
Если мы завершаем тест раньше, как только получили значимость и версии сильно отличаются по конверсии, то в ~87% случаев можно это сделать и получить верный результат. Это может сэкономить время. Но в 13% случаев такой подход приводит к ошибке и неправильному выбору — даже при такой большой разнице в конверсиях.
Ситуация вторая — гипотезы отличаются по конверсии, но не сильно
У контрольной версии конверсия 3%. У тестовой - 2.8%.
- В 75.2% случаев после фиксированной выборки мы получили не статистически значимый результат (то есть мы не смогли достоверно определить какая гипотеза конвертит лучше). Это ожидаемый результат, так как разница в конверсии гипотез меньше, чем 20%, заложенная в расчете рекомендованной выборки (26000 посетителей).
- В 24.4% случаев после фиксированной выборки мы получили статистически значимый и правильный результат.
- В 0.4% случаев после фиксированной выборки мы получили статистически значимый и неправильный результат (редкое событие)
- В 54.8% случаев статистическая значимость наступила раньше чем прошла вся фиксированная выборка. Результат был правильным (мы определили, что тестовая версия хуже конвертит). То есть тут мы могли завершить тест раньше чем прошла вся фиксированная выборка и были бы правы.
- В 15.8% случаев статистическая значимость наступила позже чем прошла вся фиксированная выборка. Результат был правильным (мы определили, что тестовая версия хуже конвертит). То есть тут мы могли подержать тест чуть подольше и получить конкретный результат несмотря на то, что фиксированная выборка ничего не показала.
- В 29.1% случаев статистическая значимость наступила раньше чем прошла вся фиксированная выборка. Но результат был неправильным, мы бы ошибочно посчитали, что контрольная версия конвертит хуже, хотя это не так (это ведь тестовая конвертит хуже).
Вывод: если версии не сильно отличаются по конверсии (но отличаются), то при недостаточно большой фиксированной выборке мы будем получать не статистически значимые результаты (в нашем случае 75% случаев). Значимые и правильные результаты были получены только в четверти случаев по результатам фиксированной выборки. Это ожидаемый результат — если нет уверенности в сильной разнице гипотез надо делать выборку больше.
Если мы завершаем тест раньше, как только получили значимость, и версии не сильно отличаются по конверсии, то в ~54% случаев можно это сделать и получить верный результат. В 15% можно подержать тест запущенным уже после того как прошла фиксированная выборка (которая не показала значимость) и все таки получить значимый и правильный результат.
Но вот уже в 29% случаев (каждый третий!) такой подход приводит к ошибке и неправильному выбору. Мы останавливаем тест раньше и получаем значимые результаты, что контрольная версия конвертит хуже (что не так).
Ситуация третья — гипотезы не отличаются по конверсии
У контрольной версии конверсия 3%. И у тестовой — 3%. (спойлер — тут начинается самое веселое)
- В 90% случаев после фиксированной выборки мы получили не статистически значимый результат (то есть “мы не смогли достоверно определить какая гипотеза конвертит лучше”). Это ожидаемый результат, так как разница в конверсии гипотез нет.
- В 5% случаев после фиксированной выборки мы получили статистически значимый и правильный результат.
- В 5% случаев после фиксированной выборки мы получили статистически значимый и неправильный результат (ожидаемо)
- В 78.6% случаев (!) статистическая значимость наступила раньше чем прошла вся фиксированная выборка. И результат был неправильным — мы подумали, что у какой-то версии преимущество (а они одинаковые).
- В 12.9% случаев статистическая значимость наступила позже чем прошла вся фиксированная выборка. И результат был неправильным — мы опять подумали, что у какой-то версии преимущество.
- В 8.5% случаев статистическая значимость так и не наступила, как долго мы тест не держали запущенным (в симуляции тест автоматически завершался, если было больше миллиона посетителей)
Вывод: если версии не отличаются по конверсии и мы завершаем тест после фиксированной выборки, мы будем получать не статистически значимые результаты в большинстве случаев (в нашем случае 90% случаев). В 5% случаев мы получим значимые и неправильные результаты — процент таких ошибок ограничен сверху нашим “p-value”, мы можем его снижать (увеличивая выборку), но он не будет больше.
Если отличий в гипотезах нет и мы или завершаем тест раньше (до окончания фиксированной выборки) как только получили первый значимый результат или держим тест запущенным пока не получим значимый результат — мы получим значимые и неверные данные (что какая-то гипотеза отличается) в 91.5% случаев. 9 из 10 неверных ответов. Wow.
Выводы
Эти симуляции показывают, что если мы запускаем эксперимент не на выборке с заранее определенным размером, а просто останавливаем его как только получили значимые результаты, то мы будем получать ошибки. Если гипотезы сильно отличаются — в 10% случаев мы выберем худшее решение. Если не сильно, то в 29% случаев (каждый третий!). Если гипотезы не отличаются — в 91.5% случаев, в девяти из десяти экспериментов мы убедим себя (“там же статистическая значимость!”) в том, чего нет и будем это делать в полной уверенности, что это приносит пользу (а не приносит)
Компании и консультанты, которые показывают выигрыш теста как только появился значимый результат (до теста на всей фиксированной выборке, если используется стандартный подход к вычислению стат. значимости) — хитрят и обманывают. Они показывают много false positives, якобы успехов тестов. Особенно у начинающих, которые тестируют практически одинаковые гипотезы типа “зеленая кнопка против красной”. Таким образом они создают фальшивое ощущения прогресса “ого, A/B тесты как круто работают — я тут заимплементил кучу гипотез и ща у меня все в гору пойдет”.
TL;DR: Надо заранее выбирать размер выборки, останавливать тест когда он прошел и измерять значимость только в конце. Если тест не значимый — надо его перезапускать (а не продолжать). Если тест не значимый — возможно эффект изменений слишком мал для детектирования, надо увеличивать выборку.
P.S. Читатель Igor Yashkov прислал (спасибо большое!) еще интересных ссылок, которые открывают еще одну интересную штуку.
С одной стороны уже понятно, что останавливать тест раньше или держать его дольше, чтобы достичь стат. значимости — нехорошо, так как легко принять неправильное решение.
С другой стороны — это очевидно неудобно. Каждый тест надо держать запущенным до заранее определенного конца (при не таком частом событии, например апгрейд до платного плана и небольшой разнице в гипотезах это может занять недели и месяцы). Тест может не показать статистическую значимость и значит надо все или начинать заново (еще месяц!) или выкидывать сделанную работу.
Люди пытаются обойти эту проблему, используя другие подходы к расчетам, без p-value (то что все используют c p-value называют frequentist hypothesis testing).
Один из подходов это Bayesian A/B Testing. Очень подробно про него пишет VWO. При каждом свидетельстве (есть конверсии или нет) мы обновляем вероятности гипотезы. При таком подходе мы можем и остановить тест в любой момент и держать его запущенным так долго как хотим. VWO говорит, что это заметно ускоряет тесты. Это сильно уменьшает процент ошибок, но говорят не убирает их совсем.
Или вот еще один другой подход: frequentist approaches to sequential testing.
Но конечно никто как правило эти хитрые другие подходы не использует. У всех стандартный подход, который уязвим к ошибкам в случае ранних остановок.
(в ссылках выше много математики — я сходу не понял все штуки, потребуется сесть и обдумать)