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

Влияние поиска по векторной сходству на потребительские расходы

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

Проблема

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

Проблема заключается в том, что отдел маркетинга давит на них, чтобы они предоставили более стратегические методы нацеливания на клиентов, независимо от географических регионов. Мы предполагаем, что конкретные клиенты могут быть более склонны использовать определенные предложения на основе своей истории покупок. Если мы сможем предложить им это в режиме реального времени, например, скидку 10 процентов на сопутствующий товар (за корзину), то мы, возможно, сможем увеличить объем продаж.

Сначала я решил взглянуть на анонимизированные данные о заказах в их кластере Apache Cassandra. Ясно, что в данных определенно есть некоторые закономерности, с некоторыми клиентами, регулярно покупающими одни и те же товары (в основном продукты питания). Может быть, есть способ использовать эти данные?

Улучшение опыта

У нас есть одно преимущество: наши клиенты взаимодействуют с нами через несколько каналов. Некоторые люди пользуются веб-сайтом, некоторые – мобильным приложением, а некоторые все еще заходят в один из наших 1000 магазинов. И более половины этих клиентов в магазине одновременно используют мобильное приложение.

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

Пример: у пары есть собака. Обычно один из супругов покупает корм для собаки. Но иногда это делает другой супруг. Эти события на уровне отдельного клиента не образуют каких-либо закономерностей.

Но когда они агрегируются на уровне домохозяйства, они образуются. Фактически, они постоянно покупают несколько 6-фунтовых рулонов “HealthyFresh – куриного сырого корма для собак” каждую неделю. Судя по рекомендуемым размерам порций, у них также либо полдюжины маленьких собак, либо одна большая, вероятно, последняя.

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

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

Вычисление векторов для поиска похожих товаров

Поиск похожих товаров означает, что нам нужно вычислить векторы сходства для наших товаров. Есть несколько способов сделать это. В интересах создания минимально жизнеспособного продукта, мы можем сосредоточиться только на названиях продуктов и построить модель обработки естественного языка (NLP) на основе подхода “мешок слов”.

В этом подходе мы берем каждое слово из всех названий продуктов и даем каждому уникальному слову запись. Это наш словарь. Векторы сходства, которые мы создаем и храним с каждым продуктом, становятся массивом единиц и нулей, указывающих, обладает ли текущее название продукта этим словом, как показано ниже в таблице 1. Мы можем использовать платформу, такую как TensorFlow, для создания и обучения нашей модели машинного обучения (ML).

Таблица 1: Словарь NLP “мешка слов” для названий продуктов в категории “Товары для домашних животных”, показывающий, как собирается каждый вектор.

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

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

Для правильной работы векторного поиска, нам потребуется создать вторичный индекс, привязанный к хранилищу (SASI) в таблице:

CREATE CUSTOM INDEX ON pet_supply_vectors(product_vector) USING 'StorageAttachedIndex';

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

Это запускает алгоритм приближенного поиска ближайшего соседа (ANN) с использованием вектора, хранящегося с текущим продуктом. Это вернет как текущий продукт, так и следующий ближайший сосед (ближайший сосед) по векторному поиску, благодаря условию LIMIT 2.

В приведенном выше запросе мы используем вектор из продукта “HealthyFresh – Chicken raw dog food”, предполагая, что клиент либо только что добавил его в свою корзину онлайн, либо отсканировал его с помощью своего телефона. Мы обрабатываем это событие и составляем следующее сообщение:

  • customer_id: a3f5c9a3
  • device_id: e6f40454
  • product_id: pf1843
  • product_name: “HealthyFresh – Chicken raw dog food”
  • product_vector: [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Затем мы отправляем это сообщение на тему Apache Pulsar. Мы потребляем из темы и используем вышеуказанные данные, чтобы вызвать конечную точку getPromotionProduct нашего микросервиса Promotions. Это запускает указанный выше запрос, возвращая оба варианта “HealthyFresh”. Мы игнорируем данные для product_vector, которые совпадают на 100% (продукт, который у нас уже есть) и запускаем акцию на устройстве для вкуса “HealthyFresh – Beef”:

Выводы и следующие шаги

После того, как мы запустили эту логику в течение нескольких недель, наша команда Promotions связалась с нами и сообщила, что наши методы срабатывают дополнительную продажу примерно в 25% случаев. Хотя соблазнительно назвать это “победой”, определенно есть еще некоторые вещи, над которыми мы могли бы поработать, чтобы улучшить результаты.

Мы выбрали подход “мешка слов” для обработки естественного языка, чтобы быстро создать (программное) продукт. Я прочитал хорошие отзывы о разных алгоритмах обработки естественного языка, таких как “Word2Vec”, которые могут быть более эффективными в долгосрочной перспективе. Наша модель также была ориентирована только на построение словаря из слов, составляющих названия продуктов. Возможно, расширение входных данных модели для включения других деталей продукта (например, размер, цвет, бренд) может помочь настроить результаты немного.

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