Рекомендательные Системы На Основе Графов

Всем привет! Меня зовут Александра Зенченко, я ведущий инженер-программист в EPAM. Я разрабатываю решения, которые помогают нашим клиентам повысить эффективность работы и в основном включают в себя часть машинного обучения.

В своем последнем проекте я работал над созданием системы рекомендаций в сфере логистики.

Я хочу поделиться своим опытом и рассказать, как с помощью алгоритмов помочь перевезти груз из Мюнхена в Женеву.



Рекомендательные системы на основе графов



Несколько слов о рекомендательных системах

Наверняка каждый с ними встречался не раз.

Рекомендательные системы — это программы и сервисы, которые пытаются предсказать, что конкретному пользователю может быть интересно/нужно/полезно, и показать это ему.

«Вам нравятся эти кроссовки? Вам также может понадобиться ветровка, пульсометр и еще 15 спортивных вещей».

.

В последние годы бренды очень активно внедряют в свою работу рекомендательные системы, поскольку от такого решения «выигрывает» и продавец, и покупатель.

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



Что нам дано?

Я работал над проектом для крупной глобальной компании, которая предоставляет своим клиентам SaaS-решение для грузовой биржи или платформу грузовой биржи.

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

Они размещают запрос по типу «Есть партия декоративной косметики, которую нужно завтра доставить из Амстердама в Антверпен» и ждем ответа.

С другой стороны, у нас есть люди или компании с грузовиками – грузовыми перевозчиками.

Допустим, они уже выполнили свой стандартный еженедельный рейс с доставкой йогуртов из Парижа в Брюссель.

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

Для этого грузоперевозчики заходят на площадку моего клиента и производят поиск, указывая направление и, возможно, тип груза (или груза), подходящего для фуры.

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



Рекомендательные системы на основе графов

В таких платформах важен баланс спроса и предложения.

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

Баланс довольно сложно поддерживать по ряду причин, например:

  • Закрытые связи между грузоперевозчиком и клиентом.

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

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

  • Наличие грузов, которые никто не хочет перевозить.

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

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

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

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

Эту систему предполагалось интегрировать в уже существующую грузовую биржевую платформу.



Как мы будем «угадывать»?

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

И есть несколько источников, которыми можно оперировать:

  • Во-первых, открытая информация о заявках на грузоперевозки.

  • Во-вторых, платформа предоставляет данные о перевозчике.

    Когда пользователь заключает договор с нашими клиентами, он может указать, сколько у него грузовиков и какого типа.

    Но, к сожалению, после этого эти данные не обновляются.

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

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

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

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

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

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

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

Это довольно легко отследить, ведь подобные предпочтения практически не меняются.

Ниже я привел данные запросов одного из пользователей за 3 дня.

Порядок заполнения следующий: 1 графа – страна отправления, 2 – страна назначения, 3 – регион отправления, 4 – регион назначения.



Рекомендательные системы на основе графов

Видно, что у этого пользователя есть определенные предпочтения в странах и провинциях.

Но так происходит не у всех и не всегда.

Очень часто перевозчик указывает только страну назначения или не указывает регион отправления; например, он находится в Бельгии и может приехать в любую провинцию, чтобы забрать груз.

В целом запросы бывают разных типов: «страна-страна», «страна-регион», «регион-страна» или «регион-регион» (оптимальный вариант).



Испытания алгоритмов

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

На основе этой классификации я начал строить возможные решения.



Рекомендательные системы на основе графов

Я взял фотографию из Hub.forklog.com Многие источники утверждают, что системы совместной фильтрации работают лучше.

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

В общем, это решение было первым вариантом, который я представил клиентам.

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

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

Теперь о контент-ориентированных системах.

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

Вполне хороший вариант, но в нашем случае есть пара нюансов.

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

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

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

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

Чтобы протестировать концепцию, наша команда работала с реальными пользователями: отправляла им рекомендации, а затем собирала отзывы.

В принципе, результат перевозчикам понравился.

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

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

Я продолжал разбираться, с чем мы здесь имеем дело.

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

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

Готовых решений по изготовлению скрытой марковской модели на тот момент я не знал, поэтому решил найти что-то попроще.



Соответствуйте PageRank

Поэтому я обратил внимание на алгоритм PageRank, когда-то созданный основателями Google Сергеем Брином и Ларри Пейджем, который до сих пор используется этой поисковой системой для рекомендации сайтов пользователям.

PageRank представляет все интернет-пространство в виде графа, где каждая веб-страница является своим узлом.

Используя его, вы можете рассчитать «важность» (или ранг) каждого узла.

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

То есть рейтинг каждой страницы зависит от количества и качества ссылок, указывающих на нее.

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

Давайте посмотрим на его формулу:

Рекомендательные системы на основе графов

  • ПР(П) – рейтинг конкретной страницы
  • Н - количество страниц
  • я — другие страницы
  • О — количество исходящих ссылок
  • д – понижающий коэффициент. Когда пользователь что-то ищет, в определенный момент он останавливается, перестает переходить по ссылкам со страницы на страницу и начинает искать что-то другое.

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

    0 ≤ d ≤ 1 – обычно d равно 0,85. В нашей модели я сохранил это значение.

А теперь простой пример расчета PageRank для простого графа, состоящего из трех узлов.

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



Рекомендательные системы на основе графов

Вы можете видеть, что узел A здесь стал самым важным, несмотря на то, что, как и C, на него указывают только два узла.

Но ранг узлов, указывающих на А, выше, чем ранг узлов, указывающих на С.



Предположения и решение

Итак, PageRank описывает марковский процесс без скрытых состояний.

С его помощью мы всегда найдем итоговый вес каждого узла, но не сможем отслеживать изменения в графике.

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

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

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

Узлами графа в нашем случае будут запросы пользователей.

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

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

Например: «Париж – Брюссель» во вторник (А), а в среду Брюссель – Кёльн (Б).

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

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

Вес ребра A-B — это количество случаев, когда пользователь искал B после поиска A. Также очень важно учитывать новизну запросов, потому что пользователь меняет свой шаблон: он может переместить или реорганизовать основной тип перевозки, после которой ему не захочется ехать на пустом грузовике.

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

Стоит учитывать сезонность: мы можем знать, что, например, в сентябре перевозчик чаще ходит во Францию, а в октябре – в Германию.

Соответственно, больший вес можно придать тем услугам, которые «популярны» в определенном месяце.

Кроме того, мы полагаемся на информацию о том, что пользователь искал в последний раз.

Это помогает косвенно предположить, где может находиться грузовик.



Результат



Рекомендательные системы на основе графов

Все реализовано на платформе Google. У нас есть OLTP-приложение, откуда данные запроса поступают и попадают в BigQuery, где формируются дополнительные представления и таблицы, содержащие уже обработанную информацию.

Для ускорения и распараллеливания обработки больших объемов данных была использована библиотека DASK. В нашем решении все данные переносятся в Cloud Storage, потому что DASK работает только с ним и не взаимодействует с BigQuery. В Kubernetes созданы два Jobs, один из которых передает данные из BigQuery в Cloud Storage, а второй дает рекомендации.

Происходит это так: Джоб берет данные о парах запросов из Cloud Storage, обрабатывает их, формирует рекомендации на ближайший день и отправляет обратно в BigQuery. Оттуда уже в формате .

json мы можем передать рекомендации в OLTP-приложение, где их увидят пользователи.

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

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

Вот, например, пользователь, который каждый день делает 14 поисковых запросов «страна-страна».

Мы рекомендовали ему такую же сумму:

Рекомендательные системы на основе графов

Оказалось, что наши варианты полностью совпали с тем, что он искал.

Граф этого пользователя состоит из около 1000 различных запросов, но мы смогли очень точно угадать, что его заинтересует. Второй пользователь в среднем делает 8 разных запросов каждые 2 дня, причем ищет как в формате «страна-страна», так и с указанием конкретного региона отправления.

К тому же страны происхождения и доставки совершенно разные.

Поэтому мы не могли всё «угадать» и точность результатов была ниже:

Рекомендательные системы на основе графов

Обратите внимание, что у пользователя есть 2 графика с разным весом.

В одном точность достигла 38%, а это значит, что около 3 из 8 рекомендованных нами вариантов оказались актуальными.

И, возможно, если мы найдем груз на этих маршрутах, пользователь выберет их.

Последний и самый простой пример.

Каждый день человек совершает около 2 поисков.

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

Точность наших прогнозов составляет 100%.



Рекомендательные системы на основе графов



Производительность в фактах

  • Наши алгоритмы работают на 4 стандартных процессорах и 10 ГБ памяти.

  • Объемы данных — до 1 миллиарда записей.

  • Создание рекомендаций для всех пользователей, которых около 20 000, занимает 18 минут.
  • Библиотека DASK используется для распараллеливания, а библиотека NetworkX — для алгоритма PageRank.
Могу сказать, что наши поиски и эксперименты дали очень хорошие результаты.

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

Теги: #Машинное обучение #Алгоритмы #искусственный интеллект #машинное обучение #системы рекомендаций #pagerank

Вместе с данным постом часто просматривают: