Сегментация данных — это не больно. Применяем ML-модели в аналитике. analytics.. analytics. ml-модель.. analytics. ml-модель. polars.. analytics. ml-модель. polars. python3.. analytics. ml-модель. polars. python3. streamlit.. analytics. ml-модель. polars. python3. streamlit. аналитика.. analytics. ml-модель. polars. python3. streamlit. аналитика. дашборды.. analytics. ml-модель. polars. python3. streamlit. аналитика. дашборды. решающие деревья.. analytics. ml-модель. polars. python3. streamlit. аналитика. дашборды. решающие деревья. сегментация.
Сегментация данных — это не больно. Применяем ML-модели в аналитике - 1

Как именно пол, возраст или семейное положение пользователей влияют на наши продуктовые метрики? 

Ответить на подобные вопросы помогает решение задач в духе «сегментация чего-либо по имеющимся данным».

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

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

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


Привет! Меня зовут Марк, я Analytics Developer в Сравни. Однажды нам в команде продуктовой аналитики потребовалось выяснить, какие социально-демографические характеристики пользователей из нашей базы (пол, возраст, семейное положение, работа и т.п.) больше всего влияют на одну из метрик продукта (далее — MTR, от слова metric). 

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

Надеюсь, наша история будет полезна для продуктовых и data-аналитиков, интересна для продактов и всех, кто интересуется вопросами сегментации и в целом анализа данных.

Классическая сегментация: привычно, но тяжеловесно 

Как выглядели бы типичные подходы аналитика при такой задаче? 

  1. Анализ зависимостей отдельных переменных

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

  1. Группировка по всем потенциальным переменным

Более радикально настроенный аналитик может попробовать группировать данные сразу по множеству интересных признаков (возраст, город, доход и т.д.), получив много мелких сегментов, каждый со своим MTR. Дальше он начинает вручную сжимать эту информацию до нескольких репрезентативных сегментов.

Оба подхода сложны и требуют значительных временных затрат. Особенно остро проблема проявляется в следующих ситуациях:

  • Численные поля. Как разделить, например, возраст на оптимальные интервалы?

  • Гранулярные категориальные признаки. Как объединить города в оптимальные группы?

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

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

Обращаемся к ML-технологиям

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

  • Полноценно справляется с задачами по сегментированию

  • Похож на привычный аналитику инструментарий вроде BI-инструментов (PowerBI, Superset). 

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

Выбор подходящей технологии не вызвал особых затруднений — можно сказать, тут нам повезло. Популярная ML-модель «решающее дерево» отлично справляется с задачей разделения данных на сегменты в контексте некоторой целевой метрики. Однако популярные BI-системы не слишком-то поддерживают интеграцию с ML-алгоритмами.

Значит, необходимо было самостоятельно написать инструмент (сервис), который содержал бы всю нужную нам функциональность. 

Как устроен наш самописный ML-инструмент

С учётом вышеуказанных требований остановились на следующем наборе технологий: 

  1. Веб-фреймворк

Нужен UI, который бы обеспечил для аналитика знакомый интерфейс BI-инструментов.
Наш выбор: Streamlit — популярный веб-фреймворк на Python, который как раз заточен под разработку аналитических приложений.

  1. Работа с данными

Нужен некоторый движок, на котором мы бы смогли провести препроцессинг данных перед их отправкой в ML-модель для сегментации. Фильтрация, сортировка, группировка с агрегациями и всё такое.

Наш выбор: Polars — набирающая популярность Blazingly fast библиотека для работы с датафреймами, которую мы ранее использовали в проектах компании и очень полюбили. В первую очередь, за выразительный API и действительно высокую скорость работы с такими данными (десятками миллионов строк), на которых тот же Pandas либо работал бы неприлично долго, либо попросту упал с какой-нибудь ошибкой.

Отличной альтернативой для работы с данными является «темная лошадка» в виде DuckDB. Это полноценная локальная OLAP база данных, по скорости не уступающая Polars. При этом она позволяет управлять данными в том числе через привычный аналитикам SQL-код — и решает проблему хранения данных «близко» к сервису, о которой я рассказываю ниже. Выбор в пользу Polars мы сделали в целях экономии времени: по этой технологии в компании уже была устоявшаяся экспертиза. 

  1. Сегментация

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

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

  1. Визуализация результатов

Результаты нужно показать пользователю в виде чартов. Наш выбор: встроенные чарты Streamlit и Plotly, с которым у Streamlit настроена интеграция.

Сегментируем пользователей, изучаем результаты

Давайте посмотрим на наш инструмент в работе — для примера возьмем конкретную задачу с сегментацией.

Так выглядит начальная панель у пользователя:

Сегментация данных — это не больно. Применяем ML-модели в аналитике - 2

Глобально на дашборде есть два раздела: 

  1. Предварительная фильтрация данных

  2. Тут все стандартно, как в BI-системах. Пользователь может отсечь ненужные сегменты путем фильтрации данных по определённым полям. Например, на скрине ниже мы настроили фильтры на отбор холостых мужчин от 18 до 60 лет.

Сегментация данных — это не больно. Применяем ML-модели в аналитике - 3
  1. Настройка параметров сегментирования

Тут при помощи виджетов-селекторов пользователь может составить задачу сегментирования. Возвращаясь к нашему кейсу: давайте настроим сегментирование в контексте целевой метрики по ряду фич (возраст, пол, образование и т.д.). На графиках мы хотим увидеть значение целевой метрики, и также дополнить ее информацией о размере сегмента. Помимо этого мы можем управлять параметрами сегментации через параметры решающего дерева. Здесь мы указали, что хотим получить максимум 7 сегментов, при этом чтобы доля каждого сегмента составляла не менее 5% от общего размера.

Сегментация данных — это не больно. Применяем ML-модели в аналитике - 4

Получаем следующий аутпут:

Сегментация данных — это не больно. Применяем ML-модели в аналитике - 5

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

Таким образом пользователь может увидеть, как тот или иной атрибут клиента влияет на метрику в отдельности.

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

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

Детали технической реализации

Рассмотрим ключевые архитектурные особенности приложения. 

  • Формирование дашбордов

Сегодня популярен подход «что-то as code», имеющий свои достоинства и недостатки. Изначально мы хотели сделать сервис, в котором можно было бы исключительно силами UI-интерфейса создавать новые чарты и дашборды, как это реализовано в BI-инструментах. Но со временем отбросили идею в пользу создания и администрирования дашбордов «as python code». 

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

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

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

  • Хранение данных

Для плавной работы дашборда держать данные нужно «близко» к сервису, чтобы он имел к ним быстрый доступ. Мы сделали абстрактный класс, который позволяет сохранять произвольные Polars-датафреймы в некоторой «базе данных», откуда можно быстро считать данные в оперативную память для обработки. 

Из реализаций этого класса на текущий момент есть обертка над локальной файловой системой, которая монтируется к Docker-контейнеру с сервисом и позволяет хранить и обрабатывать датафреймы в .parquet файлах, а метаинформацию — в .json файлах.

  • Получение данных

Это абстрагированный процесс, основная задача которого — забрать данные из какого-либо источника и сформировать из них Polars-датафрейм с последующим сохранением его в локальную БД из предыдущего пункта.

Реализации этого процесса у нас выражены в виде специальных классов, отражающих абстракции датасетов, по одному на каждый тип источника данных. Так как основная аналитическая база данных в компании — DWH Snowflake, то основной класс «обертывает» именно этот источник данных. 

Условно, этот класс хранит SQL-запрос, умеет с ним ходить в БД и забирать соответствующие данные, преобразовывать данные в Polars-датафрейм и сохранять их и метаданные в локальной БД, а также поддерживать актуальность и тех, и других, обновляя в случае необходимости. Объект этого класса находится в основе любого дашборда, являясь тем самым «датасетом» — популярной абстракцией в BI-инструментах по типу Superset и DataLense.

  • Обработка данных

Производится Polars-ом, который умеет работать в lazy-режиме напрямую с сохраненными в файловой системе .parquet-файлами. Тем самым можно работать с данными, которые не помещаются в оперативную память.

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

Реализация сервиса заняла порядка двух недель — силами одного Analytics Developer (меня). Наиболее трудоёмким этапом оказалось изначальное продумывание архитектуры и проверка гипотез. В частности, ресёрч ветки, в которой все дашборды собирались бы через UI (от этого варианта я в итоге отказался). 

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

А завершение этого текста — всё-таки на дворе 2025 год и говорим мы об аналитике — поручим ChatGPT.

Итоги: аналитика, доступная каждому

Нам удалось создать небольшой, но мощный инструмент «self-аналитики». Этот сервис позволяет не просто автоматизировать сложные задачи сегментации данных, но делать это быстро и удобно. Результаты такого ресерча легко визуализировать в виде дашборда, которым можно поделиться с коллегами или даже бизнес-заказчиками.

С помощью Streamlit мы смогли совместить гибкость и функциональность, объединив ML-модель с привычным аналитическим интерфейсом. Этот подход открывает новые возможности для исследований данных, упрощает работу аналитика, обеспечивает ему продуктивное и, что немаловажно, быстрое решение задачи.

***

Если у вас есть собственные примеры применения ML-моделей во благо аналитики, делитесь в комментах! Будет рады узнать об опыте других компаний — и ответить на любые вопросы о нашей реализации. 

Автор: mark_mer

Источник

Рейтинг@Mail.ru
Rambler's Top100