Привет, Хабр! Меня зовут Федор Тюрин, я руководитель команды продуктовой аналитики в Учи.ру. Мы проводим очень много А/Б-тестов (десятки запусков в неделю и сотни в течение года). В таких условиях очень важна автоматизация процесса анализа и подведения итогов теста.

В нашей компании была платформа для анализа А/Б-тестов (А/Б-тестер), который со временем перестал справляться с объемом и сложностью запросов. Это осложняло анализ данных: добавление нового функционала и метрик занимало очень много времени и порождало костыли в коде, платформа не умела учитывать сетевые эффекты, команда аналитиков тратила много времени на ручной анализ тестов. Чтобы решить эти проблемы и улучшить методологию А/Б-тестирования, мы решили создать новую платформу для А/Б-тестов. Рассказываю, как мы это сделали. 

Проблемы старого А/Б-тестера

Старая платформа для анализа тестов появилась, когда Учи.ру была небольшой компанией. Это был весьма простой скрипт, который в моменте закрывал основные потребности в анализе тестов. C ростом компании появилось много команд, которым требовалось одновременно запускать тесты и анализировать их. Это привело к тому, что старая платформа постепенно перестала отвечать нашим запросам и аналитика становилась фрагментированной. Почему так произошло?

Проблема 1. У каждой продуктовой команды свой подход к аналитике 

Разные команды, запуская А/Б-тесты, использовали свой подход к их подсчетам и интерпретации. Они самостоятельно определяли метрики, на основе которых принималось решение об успешности или не успешности теста, и сами критерии этой успешности. 

Из-за этого мы получали фрагментированную аналитику. В ней было сложно разобраться сотруднику, который не принимал участия при запуске одного из множества А/Б-тестов в другой команде. Например, новый аналитик вряд ли бы понял, какой подход к анализу данных использовался при анализе старых А/Б-тестов.

Проблема 2. Проблемы с масштабируемостью

Добавить что-то новое в код платформы— например, кастомную функцию — было сложно. Приходилось делать «костыли», которые со временем стало тяжело поддерживать. Тогда команды начали писать собственные А/Б-тестеры — как правило, не всегда хорошие и понятные. Это только увеличивало количество плохих инструментов. А нам важно было прийти к централизованной аналитике. 

Проблема 3. Не учитывались сетевые эффекты

А/В-тест можно считать валидным, если для него выполняется «stable unit treatment value assumption (SUTVA)». Это предположение о том, что отклик пользователя зависит только от изменений, которые были направлены именно на него, а не от изменений, направленных на пользователей вокруг него.

На Учи.ру школьники занимаются вместе со своими одноклассниками. Некоторые механики мы тестируем для всего класса (например, соревнования), а внутри класса поведение одного ребенка зависит от поведения других детей. При этом, нам все еще интересны метрики на уровне ученика (конверсия, среднее время на платформе и т.д.)

Поэтому в тестировании рандомизация на уровне ученика нам не подходила, а по классам, где процент влияния других факторов сведен к минимуму, требовалось внедрение более сложных подсчетов статистической значимости, которые трудно было интегрировать в платформу. 

Проблема 4. Нельзя быстро посчитать кумулятивные метрики

Считать кумулятивные метрики на каждый день эксперимента – вычислительно сложная задача, которая средствами стандартных баз данных (Postgres) легко не решается, а в Python подобные вычисления с помощью циклов занимают много времени. Но отказываться от кумулятивных метрик нам не хотелось, как и не хотелось тратить кучу времени на их расчеты.

Проблема 5. Продакты использовали платформу для подтверждения своих гипотез

Многие продакты подвержены так называемой предвзятости подтверждения (confirmation bias) – предвзятому поиску подтверждения своих гипотез, ведь они как никто иной заинтересованы в их успехе. Существовавшая платформа для анализа тестов никак не ограничивала такое поведение, из-за чего некоторые тесты закрывались с некорректными выводами. 


Продолжать работать с платформой в таком виде дальше было нельзя, поэтому мы стали искать решение, которое нас полностью устроит. 

Решение — сделали новую платформу на ClickHouse

ClickHouse — это колоночная система управления базами данных для онлайн-обработки аналитических запросов. На ее основе мы сделали кастомизированную А/Б-платформу. Поскольку мы стремились к автоматизации, ускорению и изменению методологии в процессе анализа тестов, использование ClickHouse стало для нас неоспоримым решением.

Главные плюсы: 

  • Скорость. База данных позволяет проводить практически любые расчеты внутри ее, не прибегая к использованию Python. 

  • Колоночно-ориентированная база. Колоночная архитектура намного лучше подходит для работы с тяжелыми аналитическими запросами. Более того, при работе с широкими таблицами, используются только те колонки, которые явно указаны в запросе, а не вся таблица, что также преимущество, когда метрик много, а для каждого конкретного кейса нужна только подвыборка из них.

  • Богатый функционал, сильно выходящий за рамки стандартного диалекта SQL. Например, ClickHouse позволяет хранить промежуточные состояния агрегирующих функций без финализации результатов, чтобы потом их можно было использовать в дальнейших расчетах. Очень полезными также оказались модификаторы агрегирующих функций, функционал для работы с массивами и внешние словари.

Архитектура платформы

  1. Сначала пользователь попадает в user interface, где задает параметры для расчета теста. Сюда входит выбор метрик, фильтрация сегментов и установка уровня значимости.

  2. Далее эти параметры попадают в бэкенд на Python, где генерируется один большой SQL-запрос, который выгружает все нужные данные. На этапе сборки запроса происходит большая работа с метриками: зная метрику, мы можем определить, какой статистический критерий применить для расчета значимости. Зная этот критерий — становится понятным, что должен отдать запрос.

Дельта-метод – основной для нас способ учета сетевых эффектов из-за простоты вычислений. t-тест и z-тест применяем в отсутствии сетевых эффектов, для непрерывных и биномиальных метрик соответственно.
Дельта-метод – основной для нас способ учета сетевых эффектов из-за простоты вычислений. t-тест и z-тест применяем в отсутствии сетевых эффектов, для непрерывных и биномиальных метрик соответственно.
  1. Потом запрос отправляется в ClickHouse. Там происходят самые тяжелые расчеты, так как их перенос в Python приводит к серьезной деградации скорости системы. Запрос всегда обращается к одной широкой таблице с данными по метрикам, это нужно, чтобы добавление новых метрик не влекло за собой смысловое изменение запроса (добавление новых подзапросов, джойнов и т.д.). Все нужные фильтры и сегменты подтягиваются из закэшированных внешних словарей.

  2. Результат запроса — это компактная таблица на уровне группы теста — которая обратно возвращается в бэкенд на Python, где происходит финализация полученных данных. То есть именно в ClickHouse происходит радикальное уменьшение размерности — от сотен миллионов строк сырых ивентов до десятков строк агрегированных результатов.

  3. И, наконец, полученные данные обратно отдаются в user interface, где происходит отображение результатов.

Как принимаем решения на основе данных

До запуска А/Б определяем срок теста. Для этого используем самописный калькулятор для расчета MDE — минимального детектируемого эффекта. На практике же, мы наблюдаем за стабильностью эффекта: для этого мы мониторим три графика — кумулятивное значение метрики, uplift во времени и кумулятивное p-value.

Мы хотим увидеть график p-value, который пробил уровень значимости и там закрепился, чтобы исключить ошибку из-за разовых прокрасов. Ниже примеры А/Б тестов, которые мы считаем значимыми и не значимыми.

Как платформа помогает продакт-менеджерам прийти к верному решению

Наша ключевая идея — не навязывать, а подталкивать пользователей А/Б-платформы к более корректному принятию решений и интерпретации статистики. Для этого мы добавили несколько хаков:

  • по-умолчанию для А/Б-теста не выбрана ни одна метрика — их нужно вручную накликивать из списка. Таким образом, мы побуждаем продактов задумываться о том, какие метрики им интересны, а не считать результаты по всем доступным (так как это увеличивает вероятность ошибки первого рода);

  • при выборе нескольких групп, нескольких метрик или нескольких сегментов, платформа автоматически применяет поправку на множественное тестирование, тем самым контролируя приемлемую вероятность ошибки первого рода;

  • дополнительно мы показываем долю А/Б-теста в общей выручке. Это позволяет в определенных моментах корректировать большой uplift, полученный на маленьком сегменте и в итоге слабо влияющим на общие показатели компании.

Вывод и оставшиеся задачи


Мы построили удобную платформу для А/Б-тестов, которая улучшила процесс анализа тестов для продуктовых и аналитических команд. Нам не приходится писать большой код, чтобы провести сложные расчеты и получить значения кумулятивных метрик. Мы видим объективную картину по итогам А/Б-теста: при расчетах учитываются сетевые эффекты, а финальный результат зависит от нескольких показателей. Но самое главное — мы повысили уровень аналитической культуры команд, так как подталкиваем их самостоятельно принимать верные решения.

Какие челленджи нам еще осталось решить?

  1. Дельта-метод (как и линеаризация) на симуляциях показывают весьма низкую мощность в сравнении с бутстрапом. Последний для нас неприемлем из-за вычислительной сложности, поэтому мы ищем способы улучшить текущие методы.

  2. Есть желание сократить время расчетов больших и средних А/Б-тестов, приблизив к моментальному получению результата — сейчас средний тест считается примерно 2–3 минуты.

  3. Хотим сделать текущее хранилище метрик полноценной библиотекой метрик, где помимо технической информации о метриках будет расширенное описание для команд: определения всех метрик, их сильные и слабые стороны, формулы расчетов.


Если ты разделяешь наш подход к аналитике, присоединяйся, чтобы вместе с нами развивать школьный EdTech.

Какие технические решения используете вы для проведения А/Б-тестов? Делитесь в комментариях.

Комментарии (1)


  1. uchitel
    24.01.2023 09:30

    Если честно, создается очень странное впечатление. Например, почему вы не используете последовательный анализ если хотите быть быстрее? Ну или быть точнее в оценках при той же скорости? Как будто критерий Вальда до сих пор засекречен.