Peeking Problem: як підглядання впливає на A/B тести. На прикладі експерименту

💡 Усі статті, обговорення, новини про AI — в одному місці. Приєднуйтесь до AI спільноти!

Усім привіт! Мене звати Максим, я — Data Engineer в ІТ-компанії Quarks, що спеціалізується на створенні продуктів і технологій у галузі Social Discovery та дейтингу. До того, як перейти на позицію дата-інженера, чотири роки працював аналітиком у продуктових компаніях та консультував стартапи.

У цій статті спробую коротко описати, що таке Peeking Problem та провести декілька експериментів, які розкривають наслідки «підглядання» за результатами в процесі проведення A/B тестів.

Що таке Peeking Problem

Якщо коротко, то Peeking Problem — це про проблему, що виникає за умови постійного «підглядання» за результатами тесту до того, як кількість даних досягає необхідного і попередньо визначеного обсягу. Під час таких «підглядань» аналітик чи менеджер може випадково отримувати статистично значущі результати тесту, що може призводити до помилкової інтерпретації отриманих даних.

Цьому зокрема сприяє те, що очікуваний позитивний апліфт метрик, на основі яких приймають рішення, не є відомим заздалегідь. Що робить очікувану тривалість тестів (необхідну кількість даних) досить орієнтовною і мотивує періодично перевіряти результати.

Усі аналітики та менеджери в продукті проводять чи присутні при проведенні спліт-тестів, та загалом в курсі, що стандартний тест (критерій) t-Стьюдента не відповідає на питання, чи кращий новий платіжний екран. Але відповідає, з якою ймовірністю наші розбіжності в тестовій та контрольній групах є випадковими.

Якщо аналітик із менеджером домовилися, що тест буде прийматися на рівні статистичної значущості 95% (тобто обирають 5% ймовірності того, що результат є випадковим), то завдяки практиці такого підглядання «випадково» можна значно частіше приймати тести, які приймати не варто було б. Матеріали, які мені траплялися в «інтернетах», свідчать, що цей відсоток може сягати 20%. Що означає, що потенційно кожен п’ятий спліт-тест міг бути прийнятий дарма. Або ж дарма не прийнятий.

Щоби підтвердити чи спростувати цю тезу, та й загалом дізнатись, як це працює, — го проводити експерименти... та підглядати за ними 🎉

Експерименти на синтетичних даних

Для першого тесту згенеруємо масив з N «юзерів» зі значеннями 0 або 1. У такому масиві «1» буде свідчити про те, що користувач конвертувався в щось важливе для нас. Наприклад, в абстрактну покупку, тобто став «баєром». Для двох груп тесту згенеруємо окремі масиви з рандомною кількістю таких баєрів, але з однаковим математичним очікуванням. Іншими словами, ми порівнюватимемо дві групи зі схожими конверсіями, відмінність між якими є випадковою.

Фінальний результат щодо розбіжностей у таких синтетичних групах можна швидко отримати за допомогою t-тесту, зіставивши фактичні конверсії груп. Підглядання ж можна реалізувати як порівняння перших N% значень із кожного з масивів із певним кроком. Для спрощення експерименту можна поділити обидва масиви на 10 рівних частин та порівнювати відповідно 10%, 20%, 30% ... від усіх значень.

Для першого експерименту я взяв дві групи розміром у 500 000 спостережень у кожній з очікуваною конверсією у 2% та запустив моделювання на 10 000 таких тестів. Крок підглядання обрав у 50 000 спостережень, — тобто наші віртуальні менеджер з аналітиком перевірятимуть результати тесту з інтервалом у 50 000 віртуальних користувачів у кожній із груп.

Код для генерації та проведення такого тесту можна знайти тут: synthetic_data_experiment.py

Результат був очікуваним: близько 5% з усіх 10 000 ітерацій показали статистично значущі результати на всіх даних (500 000 віртуальних користувачів у кожній групі). І близько 20% тестів показали статистично значущі результати принаймні один раз протягом спліт-тесту.

Проведений експеримент моделює досить неприродний перебіг подій, отже, давайте його ускладнимо:

  • додамо віртуальним менеджеру та аналітику здогадок про те, що не варто приймати рішення щодо тесту на наступний день після його запуску;
  • дамо їм доступ до A/B Test Size калькулятору та рівень сподівань для всіх нових запущених спліт-тестів на рівні апліфту конверсії в покупку у 5% (тобто очікувань, що в тестовій групі ми матимемо хоча б 2,1% покупців);
  • завершувати експеримент будемо, досягнувши 320 000 користувачів у групі;
  • підглядати за результатами будемо всього тричі: на 100, 150 та 200 тисячах користувачів у кожній із груп.

За нових умов на 10 000 ітерацій та з очікуваною конверсією у 2% поведінка синтетичних юзерів показує ті самі 5% із досягнутою статистичною значущістю на етапі завершення тесту. Та близько ~10% тестів зі статистичною значущістю за умови трьох підглядань під час його проведення.

Отже, про що говорять такі експерименти із синтетичними даними? Виключно про те, що підглядання збільшує ймовірність прийняття хибних рішень. Яка водночас у реальних випадках і так вище нуля 🙂

Експеримент на живих / реальних даних

Наступним проведемо аналогічний експеримент на даних із «живого» проєкту. Для перевірки я взяв користувачів одного зі старих проєктів, які приходили протягом одного місяця 20xx року (загалом 1,6 млн юзерів, 3,4% з яких стали баєрами).

Для симуляції на кожній з ітерацій я витягав рандомні 640 000 юзерів із тих, кого дістав вище, та випадковим чином розподіляв їх між першою та другою групою. Після чого шукав статистично значущі відмінності у % баєрів.

Код із таким експериментом (без даних і з псевдозапитом) можна знайти тут: real_data_experiment.py.

На 10 000 ітерацій ми отримали подібні результати до попереднього експерименту на синтетичних даних. Близько 5% тестів показали статистично значущі відмінності, якщо не підглядати за результатами під час проведення тесту. І близько 10% A/A-тестів показали статистично значущі результати, якщо приймати рішення, досягнувши 100 000 користувачів у групі. Для продукту N за той період це було рівнозначно ухваленню рішення на четвертий день після запуску.

Що це значить для аналітиків та їхніх команд

Добре спланований спліт, для якого ми зібрали достатньо даних, і який насправді не призведе до покращень наших цільових метрик, у ~5 зі 100 випадків покаже нам статистично значущі результати. Він може бути рекомендований аналітиком або менеджером як до прийняття, так і до відхилення. А якщо додати до цього природні очікування, що ті зміни, над якими старанно працює вся команда, не є марними, то в реальних кейсах можна ще додати кілька відсотків сплітів, які «майже» досягають статистично значущих результатів. Таке життя!

Не дуже добре спланований спліт або спліт у проєкті, у якому ми не можемо назбирати достатньо даних для досягнення відповідної статистичної потужності, може бути «помилково» прийнятим або відхиленим у значно більшій кількості випадків (Ваш Кеп 🫡).

  1. Навіть добре сплановані спліти, за якими ми починаємо «підглядати», можуть мати рейт помилкових рішень до 20%. На синтетичних, а також реальних даних із продукту (за умови взятого зі стелі «стандарту» щодо 100 000 користувачів у групі), я отримав ~10% помилкових рішень зі 100.
  2. Загалом це нормально, і із цим можна працювати, оскільки:
> Рішення щодо спліту приймає аналітик, а не t-Test ©

Що робити, якщо ти аналітик

  1. Do not panic!
  2. Не соромтеся казати менеджеру, що іноді для отримання коректних результатів варто довше збирати дані.
  3. Приймати спліти, які не показали статистично значущих результатів, — нормально, якщо є плани на подальший розвиток функціонала.
  4. Якщо дані виглядають підозріло та / або суперечать логіці, цілком нормально порушувати питання коректності реалізації тесту та досліджувати, що саме пішло не так.
  5. Часом корисно проводити негативні A/B тести, щоби переконатися, що вам дійсно щось потрібно залишати в продукті й це щось дійсно цінують користувачі.
  6. Для проведення тестів на невеликій кількості спостережень також можна використовувати й альтернативні способи аналізу (статистичний бутстреп, метод Байєса).
  7. У будь-якій незрозумілій ситуації варто радитись з іншими аналітиками (до речі, багато менеджерів у продуктових компаніях — це і є колишні аналітики, що зовсім не випадково).

May the force be with you 🙂

👍ПодобаєтьсяСподобалось3
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Слухай, здогадувався що це так працює, дякую що перевірив і поділився!

Підписатись на коментарі