Привет, Хабр! Поделюсь опытом того, как мы собрали собственную систему персонализации, основанную на «знаниях» о потенциальном покупателе.
Единственное, чем наше решение отличалось от классических, заключалось в использовании комбинации ряда решений и удовлетворении перечня требований:
- сервис должен был работать сразу на N сайтах
- динамическая сегментация аудитории
- Совместная фильтрация в целях прогнозирования в разных состояниях сегментов аудитории
- заранее сгенерированная статика в виде рекомендуемого контента + динамическое сочетание продуктов на основе анализа потока кликов
- изменение контента практически в реальном времени из оперативной памяти с учетом динамических коэффициентов
Фон
Есть группа сайтов по одной тематике со схожей аудиторией — сайты одного холдинга.Содержание другое; как правило, на каждом сайте публикуется информация о товарах, производимых холдингом.
Помимо этих «содержательных» сайтов, существует еще и собственный интернет-магазин, где продается данная продукция.
На каждом сайте есть своя команда маркетологов, свои счетчики GA и Y.Metrica. Анализируя собственную аудиторию, коллеги-маркетологи адаптировали контент сайта с учетом потребностей посетителей.
Естественно, аудитории этих сайтов пересекались, но поскольку единого счетчика на тот момент не было, результаты анализа были локальными.
Любой аналитик примет правильное решение, если под рукой будет больше данных.
Для этой благой цели я разработал свою версию счетчика.
Почему не Google Analytics? Выборка, невозможность извлечь все о пользователе с его цепочкой ходов с внешнего сайта, через кучу наших сайтов, с подробностями того, что он смотрел и т.д. Да, GA - хороший инструмент для задач, но когда хочется получать данные в режиме реального времени и сразу принимать решение о том, какой контент показывать посетителю, то… такого решения у гиганта аналитики нет. Танцы с бубнами клиентских ID для переноса между сайтами — не наш вариант. Установка единого счетчика для всех сайтов – не совсем правильное «политическое» решение и сразу попадает под ограничения бесплатной версии.
Скажу сразу, я не стал изобретать велосипед и ограничился скромным функционалом, задачами которого были:
- Записывайте каждого уникального пользователя, независимо от того, на каком сайте группы он находится.
Это было необходимо для создания единого профиля клиента, в котором были бы записаны все его данные применительно к каждому сайту.
- Отслеживание длинной цепочки переходов между всеми сайтами группы в течение сеанса.
Это было необходимо для выявления: интересов пользователей; что они смотрели; что они купили; что вы положили в корзину, но не купили; какие товары с разных сайтов могут быть «товарами-заменителями» в процессе покупки и т.д.
- Отслеживание рекламной активности всех маркетологов (в каждой команде сайта) для последующего анализа.
Это было необходимо для: обогащения профиля каждого посетителя; определение оптимальных рекламных кампаний, связанных с продуктом; определение эффективных рекламных каналов, связанных с продуктом или кампанией и т. д. Список очень велик.
Получилось вполне хорошо.
В дальнейшем можно было делать любые агрегированные отчеты как по продуктам, так и по: аудитории, рекламным кампаниям, источникам трафика и всему прочему, что придет в голову.
По каждой единице товара были данные о ценах, количестве на складе, скидках, акциях и море других данных.
Слава богу ситуации, я аналитик + разработчик + маркетолог + менеджер + имел доступ ко всему, что оцифровывалось в холдинге.
Изначально у меня не было технического задания; Я сделал это для себя, чтобы решить обычные задачи анализа данных.
Технический момент:
- MongoDB использовалась как единая система хранения данных.
- сбор данных в реальном времени на основе JavaScript
- локальный обмен данными между сайтами на базе RabbitMQ
Пока всё как у всех.Учитывая тот факт, что у нас накопилось достаточно знаний о клиентах и товарах, мы решили создать собственную систему рекомендаций для интернет-магазина.Но тут началось
Все получилось великолепно.
Они всё анализировали, но без фанатизма.
Модель выросла в размерах и, как это обычно бывает, пришло время, когда захотелось большего.
Технический пункт 2:
- Репликация MongoDB помогла выжить, но от шардинга сразу отказались.
Этот пункт не прошел в ряде внутренних аспектов.
Хотя коллекция потоков кликов может быть разбросана по сегментам, коллекции профилей пользователей больше нет. Для некоторых отчетов удалось собрать результаты агрегированных запросов из разных шардов, но скорость выполнения оставляла желать лучшего.
Без шардинга работало лучше и стабильнее
- Сбор данных в реальном времени на основе JavaScript — диктатором здесь была комбинация CORS+HTTPS. Случай, когда один пользователь зашёл на один из сайтов группы, и наш сервис «авторизовал» его сразу в мультидоменной зоне (напоминаю, что независимых отдельных сайтов на тот момент было 5), это было технологически красиво и загадочно для коллеги-маркетологи, которые теперь могли видеть всю цепочку посещений сразу на всех сайтах.
- Модель сервиса рекомендаций была написана на Python. Но обучение заняло много времени.
Файл модели занимает несколько десятков ГБ.
- Рекомендательный сервис стандартно работал с использованием собственного API, но узким местом стал ответ сервера, а точнее время, необходимое для получения результата.
Чем больше данных, тем больше модель, чем больше модель, тем медленнее она выдает результат. Ответ должен был учитывать множество факторов, которые менялись каждый час (остатки товара на складе, пользовательские характеристики и мода, всевозможные скидки и т.д.)
У некоторых пользователей скорость ответа превысила 400 мс.
Контентные блоки собирались медленно, и сайт стал заметно скучнеть.
Коллекции MongoDB насчитывают десятки миллионов записей.
Пришло время что-то изменить
Практически все приборы протоколировались на рабочем уровне, и измерялось каждое чихание.Что для чего было изменено:
- Clickhouse на MongoDB
- далее MongoDB на MongoDB + Tarantool
- ЕВА на фляге
- следующая Колба на Соколе
- был отдельный провал с промисами в js и с авторизацией пользователей на всех доменах.
Они не изменили логику; рефакторинг победил
Хорошо, когда работает только один сайт. а когда их n и хочется сразу обработать данные, то не до танцев с бубнами.
Почему МонгоДБ? Характеристики товара постоянно добавлялись, но, к сожалению, некоторые из них не всегда были представлены.
Использование агрегированных запросов очень хорошо вписывается в формат локального технологического стиля работы команды.
Я не хотел создавать таблицы на классическом SQL. Довольно часто изменялись типы и варианты хранимых и обрабатываемых данных.
Сначала я думал, что в качестве основы сервиса возьму кликхаус от Яндекса, но потом отказался от этой идеи, но кликхаус тоже был в нашем ассортименте.
Наступило новое время, 2000 запросов в секунду.
при условии, что через неделю мы выкатим новый функционал и нагрузка увеличится еще больше.
За время машинного обучения я впервые в htop увидел 100% загрузку сразу на 12 ядрах и полный своп на продуктивном сервере.
Zabbix активно сообщал, что MongoDB уже дважды менял мастер в реплике за 10 минут. Все хотели стабильности и предсказуемого государства.
Пришло время что-то изменить 2.0
Количество пользователей увеличилось.Количество клиентов аналогичное.
У нас накопился личный профиль для каждого, кто когда-либо был на каком-либо из сайтов.
Частично сформирована аудитория постоянных посетителей.
Что бы ты мог сделать? Да, любой нестандартный отчет для аналитики + разнообразие контента:
- Выбрать всех пользователей, пришедших по рекламной кампании А, которая была в последнем квартале, из них найти тех, кого интересовали товары из категории N, затем исключить тех, кто покупал только по акциям, исключить тех, кто положил любой товар в корзину и ушел Веб-сайт. Отсортируйте по ним в порядке убывания дохода магазина, если эти пользователи сейчас зашли на сайт магазина и купили товар Z. Примерно так и с другими перламутровыми пуговицами.
- Проанализировать входящий трафик, создать контент-предложение для пользователей с утм-меткой Y, но при этом идентифицировать пользователя ДО момента сборки, исключить тех, кто был на прошлой неделе, но был на сайте S (один из группы сайтов-холдингов) и были заинтересованы в продукте Q — для него генерируем контент, отсортированный по критериям x,y,z
- Тривиально найти тех, кто часто посещает сайт А, иногда заходит на сайт Б (посещал определенный раздел), и чей средний чек в интернет-магазине превышает N рублей.
К нам пришло еще кое-что.
В момент проведения рекламных кампаний интернет-магазин гнулся от нагрузки, что уж говорить о наших API, которые эту нагрузку ловили «стоя рядом».
Решения, принятые вовремя
Мы проанализировали аудиторию и решили собирать контент не для всех, а для групп посетителей.Вся толпа подверглась кластеризации.
Каждый кластер имел свои особенности и «вкус» к покупкам.
Мы делаем кластеризацию каждый день.
Это необходимо для того, чтобы при следующем посещении пользователю был показан именно тот контент, который ему больше всего подходит. От сеанса к сеансу интересы и потребности клиента меняются, и если в прошлый раз он был автоматически отнесен к кластеру №78897, то с учетом его текущих интересов система может перевести его в кластер №9464, который будет иметь более эффективный эффект на последующую конверсию.
После процедуры ежедневной кластеризации запускался следующий этап — обучение модели с учетом новых данных и знаний о покупателях и с учетом товаров, появившихся на полках магазинов или покинувших их навсегда.
Для каждого кластера мы заранее формировали блоки контента и записывали их в память.
Здесь Tarantool вышел на сцену во всей своей красе.
Раньше мы использовали его для хранения быстрых данных, которые затем использовались в машинном обучении.
Это было оптимальное решение, чтобы не мешать MongoDB, которая и так была занята другими задачами.
В спейсах Tarantool хранит данные о товарах и пользовательские данные (необходимые знания о покупателе).
Грубо говоря, сегодня вечером мы «подготовили» контент для каждого кластера аудитории, которая завтра может посетить сайт. Пользователь приходил, мы быстро определяли, знаем ли мы о нем что-нибудь, и если ответ был утвердительным, необходимый пакет контента отправлялся в Nginx. Отдельно для пользователей NoName был собран дефолтный кластер со своим контентом.
Постобработка для персонализации
Мы знали, что есть простые пользователи, а есть те, по которым у нас есть целый массив знаний.Все это хранилось в Tarantool и обновлялось в реальном времени.
На момент сборки страницы мы знали всю историю покупок и брошенных корзин каждого посетителя (если он ранее был нашим клиентом), определяли его кластерную принадлежность, модуль кликстрима давал знания об источнике трафика, мы знали о его предыдущие и текущие интересы.
Построив массив ТОП50 на лету из ранее просмотренных товаров (на любом из сайтов группы), мы «определили моду» и подмешали в контент «вкус» тех товаров, тематика которых чаще всего фигурировала в ТОП50. Этот простой анализ последних просмотренных товаров дал реальную прибыль.
Мы обогатили контент кластера личным контентом.
Результат нашего опыта
- Мы ускорили процесс генерации персонального контента в N раз
- Снижена нагрузка на серверы в 15 раз.
- Мы можем создать практически любой контент лично, учитывая пожелания многих маркетологов, особенности подачи продукта и множество исключений, учитывая данные профиля пользователя и события, которые сейчас происходят на сайте - и все это за ~25мс.
- Конверсия у таких блоков не падает ниже 5,6% — пользователи охотно покупают то, что ближе к их потребностям прямо сейчас.
- Скорость загрузки страниц идеальная — мы удалили контент, не попадающий в кластер, на > 67 %, и это правильно.
- Мы получили инструмент, который согласно задачам маркетологов не только дает ответ «что было раньше», но и помогает фрагментарно создавать контент на ближайшее будущее с учетом интересов и потребностей потенциальных покупателей.
- В профиль каждого покупателя добавлена информация из ДМП, теперь можно делать кластеризацию, в том числе по социально-демографическим, интересам, уровню дохода и прочим вкусностям.
- Наша рекомендательная служба стала лучше, заказов в магазине стало больше
Какая в этом польза?
Мы получили новый опыт, протестировали ряд гипотез, к которым раньше не знали, как подойти, мы не используем сторонние платные решения для рекомендательного сервиса, которые не учитывали все наши особенности и работали на одном домене.Команда получила хороший и интересный кейс, с которым успешно справилась.
Аппетиты растут. сейчас тестируем новую логику сборки контента.
Мы хотим собирать страницы для рекламных кампаний, рассылок и других внешних активностей.
В планах — перевод логики сборки конфигов из ручного режима в машинное обучение.
Сайты будут жить своей жизнью, а мы будем стоять в стороне «с попкорном» и наблюдать за эволюцией подачи контента сайтов на основе мнения ИИ.
Теги: #Машинное обучение #python #tarantool #машинное обучение #наука о данных #NoSQL #электронная коммерция #разработка электронной коммерции #Аномальное программирование #Интеллектуальный анализ данных #mongodb #проекты с высокой нагрузкой #система рекомендаций #restful #falcon #системы рекомендаций # python eve #rest apiful api
-
20 Событий 2014 Года
19 Oct, 24 -
Классная Функция На Яндексе
19 Oct, 24 -
Эмулятор Ритм-Студии Jdrum
19 Oct, 24