Не можешь победить — автоматизируй. Упрощаем рутину в аналитических задачах

от автора

Автоматизация — краеугольный камень современной аналитики, и речь здесь не только о том, чтобы оптимально настроить масштабные базовые процессы вроде CI/CD. Точечное внедрение инструментов и фреймворков, исходя из конкретной задачи, могут дать ощутимый быстрый эффект как минимум на уровне экономии времени. И стать предпосылками к более крупным оптимизациям.

Одним из наших локальных кейсов автоматизации в Сравни делимся под катом. Рассказываем, как наладили регулярный процесс сверки данных из десятков таблиц силами одного специалиста, с помощью уже имеющихся в компании инструментов — low code-платформы и мессенджера.

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


Привет, Хабр! Я Никита, аналитик данных в Сравни. Занимаюсь оптимизацией и автоматизацией процессов аналитики, выстраиваю взаимодействие между бизнесом и аналитикой в различных командах. Сегодня расскажу, как мы наладили и автоматизировали один из важных процессов: сэкономили массу времени на выполнении рутинных операций по сверке данных из таблиц и уменьшили риски потери денег для компании. 

Давайте сопоставим данные — их и наши

В команде «Образования» мы работаем над сервисом сравнения и выбора различных образовательных курсов, то есть выступаем агрегатором в EdTech. Например, если пользователь не знает, какой курс по аналитике данных выбрать, он может зайти к нам на сайт, посмотреть список таких курсов и выбрать наиболее подходящий.

Мы работаем с партнерами по модели CPA. То есть пользователь попадает на наш сайт, совершает какое-то целевое действие, например, клик, и за это мы получаем комиссию от партнера. 

Чтобы точно отслеживать целевые действия, необходима трекинговая система, которая будет их записывать. Мы используем TUNE (бывш. HasOffers). Cистему нужно настроить на нашей стороне и на стороне партнера. У нас ее настроить легко, а вот у партнеров — увы, не всегда, поскольку события записываются на их бэкенде, и сами партнеры должны передавать их в трекинговую систему. Не у всех партнеров есть такие технические возможности — для этого требуется определенное количество разработчиков. Поэтому есть риск, что те или иные конверсии не попадут в трекинговую систему. 

Чтобы компании избежать потери денег из-за некорректного подсчета конверсий, пришлось организовать процесс сверки – в первом приближении вручную, поэтому довольно трудоёмко. Ежемесячно партнер присылал нам выгрузку со всеми транзакциями из своей трекинговой системы (как правило, это CRM-системы); наши аккаунт-менеджеры просили аналитиков сделать выгрузку со всеми операциями из нашей системы. Менеджеры сверяли выгрузки и искали различия. При их обнаружении шли к партнеру обсудить вопросы по той или иной транзакции. И просили аналитиков загрузить её к нам в базу данных.

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

Мы решили это изменить – с помощью «подручных средств» организовали несложный процесс автоматизации. И теперь ежемесячная задача, занимавшая у менеджеров неделю рабочего времени, сократилась до нескольких часов работы.

Автоматизация

Основная трудность в этом кейсе даже не техническая, а управленческая. Важно было договориться с каждым партнером, чтобы они регулярно присылали нам корректную таблицу со всеми операциями. Изначально я допустил фатальную ошибку, сказав, что можно отправлять нам таблицы любого формата: «для партнера будет менее трудоемко, а я их всё равно обработаю». Это в разы замедлило мою работу: между таблицами партнеров были существенные отличия, все их требовалось провести в единый формат. 

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

Рассмотрим подробнее каждый этап.

Сперва нам нужно было загрузить в базу данных Snowflake десятки гугл-таблиц от наших партнеров. В качестве инструмента для этого масштабного ETL-процесса мы выбрали low code платформу n8n, которая до этого уже применялась в компании. Лично мне она понравилась за счет простоты использования, удобного UI и внушительного списка интеграций с другими инструментами.

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

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

Так выглядит флоу по загрузке данных. К сожалению, из-за количества нод (117) не получилось все уместить на одной картинке

Так выглядит флоу по загрузке данных. К сожалению, из-за количества нод (117) не получилось все уместить на одной картинке

Начали мы с базовой стандартизации данных — наиболее коварной части всего процесса. Я провёл встречу и написал документацию для наших менеджеров, чтобы они могли доступно объяснить партнерам правила оформления таблиц с данными. При разработке этого ТЗ постарался учесть все корнер-кейсы, которые могли встречаться в таблицах. Тем не менее, человеческий фактор никто не отменял, поэтому иногда в выгрузках я вижу страшные вещи. Например, дату в соответствующий столбец вставляют буквально прописью. Вместо 10.09.2024 аналитик видит «десятое сентября» — представьте его лицо в этот момент!

Когда такое происходит, возникает ошибка при записи в Snowflake, поскольку тип данных не соответствует ожидаемому. И здесь очень помогает система алертов, которую можно настроить в n8n. При возникновении ошибки мне в мессенджер прилетает вот такое сообщение:

Сама же стандартизация ака обработка данных в n8n легко выполняется через python-код. Вот пример такого кода:

from datetime import datetime  #Переименовываем столбцы for item in _input.all():     item.json['COURSE_NAME'] = item.json.pop('Название курса')    for item in _input.all():     item.json['LEAD_DT'] = item.json.pop('Дата заявки')    #Функция, которая заменяет пропуски в выручке на 0 def revenue(data):     if not data:         return '0'     else:         return data  #Применяем функцию for item in _input.all():     item.json['SCHOOL_REVENUE_VAT'] = revenue(item.json['SCHOOL_REVENUE_VAT'])  for item in _input.all():     item.json['SRAVNI_REVENUE_VAT'] = revenue(item.json['SRAVNI_REVENUE_VAT'])    #Функция для обработки даты def remove_time_from_date(date_time_str):     if not date_time_str:         return date_time_str          current_year = datetime.now().year          #Перебираем форматы дат     formats = ['%d.%m.%Y %H:%M:%S', '%Y-%m-%d %H:%M:%S', '%d.%m.%Y %H:%M', '%d.%m.%Y', '%d.%m', '%d-%m-%Y', '%d.%m.%Y, %H:%M']          for fmt in formats:         try:             #Пробуем распарсить дату             date_time_obj = datetime.strptime(date_time_str, fmt)                          #Если формат без года, добавляем текущий год             if fmt == '%d.%m':                 date_time_obj = date_time_obj.replace(year=current_year)                          #Возвращаем дату в формате 'YYYY-MM-DD'             return date_time_obj.strftime('%Y-%m-%d')         except ValueError:             #Если текущий формат не сработал, продолжаем проверку             continue          #Если ни один формат не подошел, возвращаем исходную строку     return date_time_str  #Применяем функцию для форматирования даты for item in _input.all():     item.json['LEAD_DT'] = remove_time_from_date(item.json['LEAD_DT'])       for item in _input.all():     item.json['SALE_DT'] = remove_time_from_date(item.json['SALE_DT'])    #Прописываем тип курса for item in _input.all():     item.json['POSTBACK_TYPE'] = 'Платный'  #Прописываем модель оплаты for item in _input.all():     item.json['MODEL'] = 'CPS'    return _input.all() 

В n8n есть особенность: при чтении таблицы программа конвертирует таблицу в JSON. Поэтому в коде мы работаем с JSON’ами, хотя данные, на самом деле, представлены в табличном виде.

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

ETL-процесс из n8n к нам в Snowflake работает на ежедневной основе, чтобы как можно скорее автоматически анализировать поступившие данные. Дату последней проверки при наличии новых данных мы записываем в специальную таблицу с логами, чтобы python-скрипт не проверял одно и тоже каждый день. 

Сама проверка заключается в том, что мы берем id транзакции из нашей базы и сравниваем его с id транзакции партнера; если они различаются, это записывается в специальную эксель-таблицу, которую бот по API отправляет в мессенджер. Более того, если мы видим, что в нашей базе нет какого-либо id транзакции, то скрипт автоматически записывает его к нам в трекинговую систему. Это позволяет видеть все потерянные транзакции в наших отчётах, например, на чартах в SuperSet.

Вот так выглядят логи проверки: 

В итоге сообщение с проверкой выглядит следующим образом: 

После получения такого файлика менеджерам остается лишь направить его партнеру со словами: «Где транзакции, Лебовски?».

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

Весь процесс можно представить в виде такой схемы:

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

Автоматизация, которая у нас в итоге получилась, опирается на специфику работы стрима «Образование»). В других направлениях (страхование, кредиты, остальное) технические и организационные детали реализации могут отличаться, с учётом специфики взаимодействия с партнерами. Но где угодно, далеко не только в задаче сопоставления данных из внутренних и внешних источников, могут пригодиться два ключевых принципа из кейса выше. 

Во-первых, вместо решения отдельно взятой задачи («взаимодействие с конкретным партнером») попробовать решить сразу класс таких задач («взаимодействие со всеми партнерами»).

Во-вторых, выжимать больше из уже имеющихся инструментов.

***

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


ссылка на оригинал статьи https://habr.com/ru/articles/854654/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *