Наше подразделение Agima.ai занимается проектами в области машинного обучения и анализа данных. В аналитических проектах нам нравится, когда данные для отчетов доступны пользователям в режиме self-service аналитики (то есть, аналитики самообслуживания). В этом случае любой специалист может самостоятельно собрать себе нужный отчет в BI-инструменте, без использования SQL или другого кода.

Такой подход увеличивает доступность данных, скорость и качество выводов, которые бизнес-пользователи могут сделать по данным.

В этой статье расскажем, как подойти к задаче построения сквозной маркетинговой аналитики “с нуля” таким образом, чтобы:

  • данные были хорошо документированы;

  • в полученные отчеты было легко добавлять любые фильтры и разрезы: в том числе, по новым атрибутам пользователя, по сегментам АВ-тестирования, по языкам и т.п.

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

Рассказ будем вести на примере одного из реализованных клиентских проектов.

Задача

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

Если подробнее:

  • есть несколько рекламных кабинетов, из которых нужно собрать затраты на рекламные кампании: Facebook, Yandex.Direct, Google Adwords, Vkontakte. Также есть затраты на маркетинг, которые не проходят через рекламные кабинеты, а ведутся в ручном справочнике.

  • пользователи, которых привлекли с помощью рекламных кампаний, совершают покупку на сайте.

  • на сайте установлен Google Analytics, который фиксирует id пользователей, их utm-метки и покупки.

Задача кажется стандартной, но в клиентском проекте есть несколько нюансов в бизнес-логике, из-за которых стандартные решения не подошли:

  • Из-за особенностей маркетинговой стратегии нужно реализовать кастомную логику атрибуции и оценить каждый канал по двум моделям: кастомной и стандартной last click;

  • Есть ряд особенностей бизнес-логики, которые нужно учитывать при выстраивании связи маркетинговых каналов с покупками: например, языки пользователей; 

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

Как мы организовали процесс

Этап 1: Скачивание «сырых» данных

Для начала нам нужно получить набор данных для анализа.

В качестве хранилища данных мы используем BigQuery. Источников данных у нас девять.

Для загрузки данных используем open source стек Singer + Meltano. Для преобразования данных используем DBT.

Этап 2: Моделирование данных

Для проектирования модели предметной области используем минимальное моделирование. Это подход к моделированию данных, который позволяет одновременно разобраться в структуре данных и задокументировать ее.

В результате анализа выделяем в данных:

  • ⚓️Анкеры (это основные существительные предметной области, например, ⚓️Пользователь, ⚓️Визит, ⚓️Рекламная кампания и т.п.).

  • Атрибуты (это характеристики анкеров, например, Имя пользователя, Дата визита, Название рекламной кампании).

  • ?Линки (связи между двумя анкерами, например, “?⚓️Пользователь сделал ⚓️Заказ”).

Найденные анкеры, атрибуты и линки сразу же документируем в excel-файле, то есть описание финальных данных появляется раньше реализации.

Список найденных анкеров предметной области
Список найденных линков предметной области
Список найденных атрибутов предметной области в разрезе по каждому анкеру

Теперь собираем модель предметной области. Для сквозной аналитики она вполне понятна и выглядит так:

Моделирование кастомной атрибуции 

Основным понятием (анкером) в системе является ⚓️Визит (visit) пользователя.

У ⚓️Визита есть два атрибута, которые содержат информацию о кастомной маркетинговой атрибуции:

  • номер визита (visit_number);

  • ценность визита (visit_value).

Как только ⚓️Визит приводит к ⚓️Транзакции, мы делим выручку от транзакции между всеми предшествующими визитами, начиная с первого и заканчивая последним.

Рассчитанная ценность сохраняется в атрибуте “ценность визита” (visit_value).

Для оценки эффективности маркетинга, кроме ценности визита (visit_value), нас еще интересует стоимость визита (visit_cost).

Стоимость визита — это стоимость клика для рекламной кампании, которая привела пользователя. Бывает, что стоимость одного визита складывается из стоимости нескольких кампаний. Например, из стоимости клика в рекламном кабинете и стоимости промокода, который пользователю дарят в результате рекламной кампании.

Этап 3: Реализация data API

На уровне физической реализации все анкеры, атрибуты и линки независимы друг от друга. Мы их собираем в виде отдельных таблиц в базе.

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

Граф трансформаций в DBT для линка “Объявление AdWords привело к визиту”. Видно, какие атрибуты используются при вычислениях, и что именно рассчитывается на основании этого линка впоследствии.
Если вести документацию в Notion, то таблицу со списком атрибутов можно переключить в вид канбан-доски. Таким образом, физическая реализация каждого анкера, атрибута и линка становится отдельной задачей, у которой есть исполнитель и статус. Очень удобно для управления проектом.

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

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

Как работает модель данных, всё в сборе:

Этап 4: Сбор витрины для self-service аналитики

Для отчетности мы используем бесплатный инструмент с открытым исходным кодом Metabase.

Для подготовки витрины для self-service аналитики в Metabase собираем все данные, доступные в data api, в несколько связанных широких таблиц:

  • таймлайн со всеми событиями системы собираем из всех линков, которые мы нашли на этапе моделирования данных;

  • широкая таблица на каждый анкер, куда собираем все атрибуты анкера.

Все таблицы в интерфейсе Metabase

Связи между этими таблицами мы задаем прямо в Metabase.

Этап 5: Определение метрик

Данные и витрина собраны, остается посчитать по ним бизнес-метрики.

В модели данных Metabase можно задать словарь метрик, который будет доступен бизнес-пользователям при построении отчетов.

Добавление новых метрик не требует программирования и доступно всем пользователям Metabase.

Этап 6: Финальный отчет

Все данные собраны, метрики определены, приступаем к сборке финального отчета.

Мы это делаем без написания SQL, просто накликивая данные в Metabase.

Этап 7: Документация по проекту

Под конец проекта приводим в порядок документацию. Это просто, поскольку все данные мы описали в самом начале проекта — на этапе моделирования данных. Проверяем опечатки и возникшие расхождения при реализации.

На этом проекте мы дополнительно перенесли всю документацию в Notion (для красоты).

В процессе реализации проекта мы узнали много нового про устройство данных заказчика. Все наши находки описали в коротких заметках, которые делали в процессе разработки, их отдали заказчику вместе с результатами работы и документацией.

Таким образом, если заказчик подключит к работе собственных аналитиков, они легко разберутся в структуре данных и логике решения.

Выводы и следствия

В ходе проекта мы реализовали для заказчика отчетность по сквозной маркетинговой аналитике. Данные доступны бизнес-пользователям в режиме self-service аналитики (аналитики самообслуживания).

Благодаря использованию концепций минимального моделирования получили ряд важных следствий:

  • данные полностью документированы, актуальность документации поддерживается «по построению», для бизнес-пользователей данные доступны в режиме self-service аналитики; 

  • благодаря независимой реализации каждого атрибута в отчеты легко добавлять дополнительные данные и разрезы (например, реализация альтернативной модели атрибуции — это добавление ровно одного атрибута);

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