Считаете ли вы иногда, что приложения для электронной коммерции усложняют покупателям принятие решения о том, что покупать? Вы когда-нибудь тратили бесчисленные часы на просмотр меню ресторана на Swiggy только для того, чтобы заказать один и тот же бирьяни в 128-й раз?

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

Американский психолог Барри Шварц в своей книге «Парадокс выбора — почему больше означает меньше» рассказывает об этом драматическом взрыве выбора для покупателей, который парадоксальным образом становится проблемой, а не решением. . Одержимость выбором побуждает пользователей искать то, что заставляет их чувствовать себя хуже. Следовательно, ограничение выбора иногда может быть способом заставить клиентов принимать решения быстро, а также иметь приятный фактор для общего опыта.

Это убеждение было дополнительно подкреплено многочисленными призывами от Twitterati решить вопрос «что заказать?», учитывая множество вариантов, которые мы предлагаем в Swiggy.

Проблема под рукой

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

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

Но подождите, почему до сих пор никто не создал механизм персонализированных рекомендаций по предметам?!

Множество проблем

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

Масштаб и субъективность

  • Само количество позиций, которые мы могли бы порекомендовать клиентам, на порядок превышает количество ресторанов. Вдобавок к этому, если мы хотим порекомендовать комбинацию элементов, число возможностей, то есть ∑(nCk), может легко возрасти. Здесь «n» — это общее количество блюд в меню ресторана, а «k» — это количество рекомендуемых блюд. Но большинство этих комбинаций были бы бессвязными и бесполезными для большинства клиентов.
  • Кроме того, то, что представляет собой бесплатную пару предметов (комбо), может быть в первую очередь субъективным. Например, покупатель из Южной Индии может счесть Пулав и Досу подходящей комбинацией для завтрака, но покупатель из Северной Индии может счесть это абсурдным.

Доступность товара

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

Свежесть и сезонность

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

Микро-персонализация

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

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

Варианты дизайна

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

  • Две корзины с товарами. Мы ограничиваем набор корзин-кандидатов максимум двумя отдельными товарами, чтобы контролировать масштаб. Учитывая, что значительная часть заказов на платформе состоит из двух товаров, это ограничение на количество товаров в корзине-кандидате сужает целевую аудиторию на очень незначительную величину.
  • Создание корзин из заказов на платформе. Один из способов создания корзин из двух позиций для заданного ресторана – это использование различных комбинаций позиций в меню. Но это может привести к взрыву комбинаций, и большинство из них будут несвязными парами. Вместо этого мы рассматриваем тележки с двумя товарами, заказанные на Swiggy, как вселенную тележек-кандидатов вместо того, чтобы использовать генеративный подход.
  • Выявление непоследовательных тележек с помощью Food Intelligence (FI). Мы заметили, что многие из заказанных клиентами тележек с двумя товарами образуют непоследовательные пары. Например, клиент может заказать что-то вроде карри и закуски, потому что у него дома есть рис или роти. Но мы бы не хотели рекомендовать такую ​​пару к еде, а вместо этого рекомендуем роти и карри. Вручную создавать согласованные пары блюд или разрабатывать правила с помощью гурманов для фильтрации несогласованных пар — не масштабируемое предложение. Следовательно, нам нужен какой-то способ генерации этих правил алгоритмическим способом. К счастью для нас, у нас есть собственная система Food Intelligence, которая обеспечивает иерархическую классификацию каждого элемента по различным уровням, таким как семейство блюд, категория блюд и т. д. Пример такой классификации показан ниже. Мы использовали механизм FI для создания правил фильтрации непоследовательных корзин. Мы обсудим детали этой методологии в следующем разделе.

  • Увеличение набора кандидатов с помощью модели перекрестных продаж.Чтобы обеспечить некоторый уровень знакомства с вариантами, показанными клиенту, мы создаем тележки-кандидаты на основе собственной истории заказов клиента. Для этого мы используем уже построенную модель перекрестных продаж (автор Shivam Shah), которая прогнозирует бесплатные позиции для каждой позиции в меню ресторана. В качестве примера: если клиент в прошлом заказывал Вег бирьяни в магазине Бехруз, мы создаем корзину-кандидат, содержащую тот же бирьяни. em> и рекомендации по перекрестным продажам, скажите "Gulab Jamoon", чтобы создать комбинацию Biryani и Gulab Jamoon.
  • Решение проблемы микроперсонализации с помощью оценки растительности. Несмотря на то, что выбор продуктов питания очень индивидуален, мы пытаемся в некоторой степени решить проблему микроперсонализации, введя методологию условного расчета «оценки растительности» для клиентов в ресторане. и уровень геохеша. Это гарантирует, что мы не будем в конечном итоге рекомендовать невегетарианские блюда чисто вегетарианским клиентам или даже рекомендовать таким клиентам вегетарианские блюда из преимущественно невегетарианских торговых точек.

Как это сделать

Наша цель — рекомендовать персонализированные тележки клиентам на уровне foodot-gehash, обеспечивая при этом разнообразие и свежесть.

Мы подошли к этой задаче, разбив условие задачи на две части:

  • Генерация правил для определения действительных тележек
  • Поиск и ранжирование корзин кандидатов

Создание правил для определения действительных тележек

Для создания правил определения действительных тележек мы рассматриваем семейства блюд, предоставляемые движком FI. Из исторических заказов мы смотрим на лучшие семейные пары блюд, которые заказываются на платформе на уровне города, на уровне обеденного зала. Предполагается, что предпочтения в еде остаются однородными в пределах города и резко различаются между городами. Например, Идли и кофе могут быть главным семейным блюдом во всем Бангалоре, а Джалеби и Фафда — в Ахмадабаде.

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

Поиск корзин кандидатов

Мы генерируем корзины-кандидаты для клиента из 2-х источников:

  1. Общие заказы платформы
  2. Собственная история заказов клиента

Для создания корзин из заказов платформы мы смотрим на все заказы на 1 и 2 товара, размещенные за последние 30 дней, которые составляют значительную часть заказов. Мы фильтруем эти заказы, используя правила семейства блюд и показатели совместного заказа, созданные ранее, чтобы отфильтровать непоследовательные корзины.

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

На втором этапе мы строим индекс приблизительного ближайшего соседа (ANN) из вложений корзины-кандидата для каждого геохэша5.

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

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

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

Рейтинг корзин-кандидатов

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

  1. Оценка схожести корзины с встраиванием клиента
  2. Абсолютная разница между медианой GMV клиента и ресторана
  3. Абсолютная разница между оценкойвегетарианства клиента и ресторана
  4. Географическое расстояние между клиентом и рестораном

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

Производственная настройка

В этом разделе мы даем обзор производственной настройки для персонализированной системы рекомендаций корзины. На рисунке ниже представлена ​​схематическая диаграмма, на которой показан поток вызовов для предоставления рекомендаций в приложении во время сеанса. Платформа обработки и анализа данных (DSP) — одна из основных возможностей Swiggy, обеспечивающая развертывание моделей и получение логических выводов в реальном времени в масштабе. В этом случае генерация и ранжирование набора кандидатов не выполняются посредством логического вывода в реальном времени. Вместо этого рекомендации на уровне клиента, геохэша и слота для еды предварительно вычисляются в автономных заданиях и хранятся в базе данных с быстрым доступом, такой как DynamoDB. Во время обслуживания в режиме реального времени доступ к этим рекомендациям по корзине осуществляется через конечную точку модели Nashorn и возвращается в вызывающую службу, которая затем обрабатывается с помощью постобогащений уровня представления, таких как изображение и цена, связанные с корзиной.

Swiggy предлагает рабочий процесс

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

Рабочий процесс 1

  1. Создание правил FI
  2. Создавайте клиентские вложения
  3. Вычислительные функции, чтобы зафиксировать вегетативность и премиальность клиентов
  4. Создавайте тележки-кандидаты из истории заказов для каждого клиента, используя кросс-продажи.

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

Рабочий процесс 2

  1. Получить тележки, которые были заказаны на платформе
  2. Создавайте индексы «Приблизительный ближайший сосед» (ANN) с помощью библиотеки Spotify Annoy.
  3. Получить приблизительные тележки ближайших соседей на уровне слота клиента-геохеш-еды
  4. Совокупные корзины из собственной истории заказов клиента, полученные из раздражающего индекса и популярные корзины в геохеше клиента.
  5. Удалить повторяющиеся пары блюд и несколько тележек из одного ресторана (удалить дубликаты)
  6. Ранжируйте тележки-кандидаты, используя различные параметры из магазина функций.

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

Поскольку ANNOY от Spotify не имеет реализации spark, мы написали свои собственные обертки для параллельного построения индексов и выводов из них. Спасибо P Shyam Sunder за помощь в этом.

Время показа

С построенной частью головоломки DS, в сочетании с некоторыми замечательными людьми из интерфейса, бэкэнда, UX и продуктового маркетинга, мы запустили A / B-тестирование в нескольких городах. Первые данные показывают обнадеживающие признаки и значительное сокращение «времени на выполнение заказа», указывая на то, что Swiggy Suggests фактически устраняет парадокс выбора. Вот короткое демонстрационное видео для всех неудачливых людей, которые не были частью A/B 😛

Улучшения текущего подхода

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

  1. В настоящее время рекомендации для всех клиентов рассчитываются каждый день и помещаются в базу данных. Но может случиться так, что только часть клиентов увидит рекомендации для определенного слота еды. Следовательно, выполнение выборки ближайшего соседа в режиме онлайн с последующей подсчетом очков в реальном времени было бы естественным улучшением подхода, который мог бы сэкономить значительные затраты на хранение и вычисления.
  2. Мы могли бы улучшить магазин функций с помощью информации о истории посещений клиента с различными корзинами, что могло бы помочь улучшить рейтинг вещей.
  3. Кроме того, могут быть внесены улучшения для построения клиентских вложений и алгоритма приближенного ближайшего соседа, которые могут улучшить поисковый набор.
  4. Подход к онлайн-обучению, который адаптируется к отзывам клиентов в режиме реального времени, можно опробовать с помощью многоруких бандитов для ранжирования.

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

А пока, Свигги каро фир джо чахе каро 😀

Благодарности

Благодарим Ashay Tamhane и Jairaj Sathyanarayana за вклад в создание конвейера машинного обучения и Shubha Shedthikere за подробное рассмотрение блога.