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

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

Вызовы

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

  1. Набор классов очень велик. Приложениям машинного обучения обычно необходимо прогнозировать только несколько выбранных классов (например, классифицировать электронную почту как спам или не спам), но в электронной коммерции таких часто бывает сотни или тысячи категорий, которые необходимо классифицировать. Чтобы обучить устойчивые модели для этих случаев, вам понадобится особенно большой объем обучающих данных.
  2. Данные о продукте разнообразны и несбалансированы. Один продукт может иметь подробный набор атрибутных данных, который полностью отсутствует в другом продукте (например, цвет, размер или материал футболки, а также срок годности, жирность содержание или объем молока). Учет всех доступных переменных продукта приведет к резкому увеличению числа пропущенных значений, что значительно усложнит сходимость модели. Чтобы справиться с этой проблемой, мы решили сделать ее простой и использовать только названия продуктов, изображения и описания в качестве переменных для прогнозирования, потому что они доступны для большинства продуктов и, возможно, несут наиболее важную информацию.
  3. Каждый интернет-магазин имеет уникальную структуру категорий. В commercetools мы предлагаем облачный API для управления торговыми платформами (работа с процессами, связанными с продуктами, заказами, клиентами, тележками, платежами и т. д.). Наш API разработан с учетом гибкости, поэтому наши клиенты работают в самых разных отраслях (таких как мода, бакалея, сельское хозяйство, товары для дома, зимние виды спорта или ювелирные изделия). При создании нашей системы машинного обучения мы должны убедиться, что рекомендуются только категории, относящиеся к конкретному магазину.
    Один из способов решения этой проблемы - обучить отдельные модели для продуктов и категорий каждого интернет-магазина. но с этим подходом возникает множество проблем: в некоторых магазинах может не хватать данных о товарах для сближения моделей, классы с большей вероятностью будут несбалансированными (например, в магазине модной одежды может быть много данных по категории футболки. но только несколько случаев для бандан), модели необходимо часто переобучать для учета новых добавленных категорий, а инфраструктура для обработки всех этих моделей и их различных версий в производстве может быть довольно сложной.
    По этим причинам. , мы использовали другой подход и обучили одну универсальную модель, которая охватывает широкий спектр категорий и может использоваться всеми нашими клиентами. Чтобы сопоставить эти общие категории с категориями конкретных магазинов, мы используем отдельную модель машинного обучения, которая количественно определяет сходство между словами (т. Е. Чтобы определить, что общая категория джинсы соответствует категории Мода› Мужчины ›Джинсы в магазине A, но Одежда› Брюки в магазине B, подробнее об этом позже). При таком подходе мы теряем некоторую точность для категорий, которые очень зависят от клиента, но мы получаем большую гибкость, больше данных для обработки несбалансированных классов, лучшую поддержку для небольших магазинов и меньшие затраты на обслуживание.

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

Набор классов

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

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

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

Классификатор изображений

Когда дело доходит до классификации изображений, сверточные нейронные сети, несомненно, являются золотым стандартом, в основном из-за их способности идентифицировать и комбинировать низкоуровневые функции (линии, края, цвета) со все более и более абстрактными функциями (квадраты, круги, объекты). , лица). Мы находим аналогичный механизм в зрительной коре головного мозга человека, поэтому этот алгоритм должен что-то делать правильно. С главным прорывом сверточных нейронных сетей в 2012 исследователи последовательно улучшали свою архитектуру в контексте ежегодного конкурса ImageNet, который является чем-то вроде олимпиады компьютерного зрения. В 2017 выигрышный вклад достиг впечатляющей топ-5 точности ~ 97,8%.

Помните, я говорил вам, что нам понадобится особенно большой объем данных для обучения надежной модели для всех этих категорий продуктов? Здесь мы собираемся немного схитрить, применив подход под названием трансферное обучение. Обучение современной сверточной нейронной сети с нуля требует много времени, данных и вычислительных ресурсов, поэтому мы просто возьмем нейронную сеть (Inception v3), которая уже была предварительно обучена на большой набор данных изображений. Эта модель уже многое узнала об извлечении и объединении функций изображения, но еще не знает, для каких категорий мы хотим иметь прогнозы в нашем конкретном случае использования. Чтобы подогнать сеть под наши нужды, мы просто отсекаем последний слой классификации, добавляем новый слой с 723 единицами, соответствующими нашим категориям продуктов, а затем повторно обучаем только эти веса с нашим собственным набором данных, в то время как веса всех остальных моделей замораживаются. Это позволяет нам создавать надежные настраиваемые классификаторы с относительно небольшими усилиями и данными, в нашем случае с набором данных из ~ 130000 изображений (~ 100–200 для каждой категории).

Мы использовали библиотеку TensorFlow на Python для реализации этого подхода и провели обучение модели на Google Cloud ML Engine (с измененным кодом из этого примера). Код, который мы написали поверх этого, в основном занимается загрузкой изображений с URL-адресов, преобразованием их в jpeg, масштабированием, сортировкой по подпапкам для каждой категории, удалением дубликатов или недопустимых файлов, а также загрузкой узких мест и обученных моделей в Google Storage. По-прежнему существует некоторая ручная работа, связанная с двойной проверкой всех изображений, потому что, к сожалению, не все изображения, назначенные продукту, являются репрезентативными изображениями для категории, которую вы хотите, чтобы ваша сеть изучила (изображения инструкций по использованию, общие логотипы компании, низкое качество изображения и т. д.).

Текстовый классификатор

Затем мы построили наш классификатор для названий продуктов.

После удаления дубликатов, неинформативных имен и балансировки нашего набора данных мы получили ~ 230000 образцов (~ 300 для каждой категории). Чтобы упростить работу с именами и уменьшить их размерность, мы сначала пропустим их через конвейер предварительной обработки (в основном используя библиотеки re и spacy):

  1. Все буквы в нижнем регистре.
  2. Удаление знаков препинания и специальных символов (например, *, | или .). Мы оставляем дефисы, чтобы сохранить информацию в таких футлярах, как «футболки».
  3. Удаление игнорируемых слов (, и, в и т. Д.), Поскольку мы не ожидаем, что они будут иметь много прогнозируемых ценить.
  4. Лемматизация слов (≈поиск основы слова) для устранения вариации изгиба слова (т.е. мы хотим, чтобы наша модель знала, что «яблоки» и «яблоко» относятся к одному и тому же).

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

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

  1. Мешок слов: каждая выборка преобразуется в n-мерный вектор, соответствующий набору уникальных слов в наборе данных, со значениями соответствующих частот слов в текущей выборке. Легко сделать, но игнорирует синтаксис и приводит к очень разреженным векторам (≈ многомерное пространство с большим количеством нулей), что усложняет обучение модели.
  2. TF-IDF (частота встречаемости терминов в документе, обратная частота). Подобно мешку слов, но количество вхождений слов в текстовой выборке выше, когда слова встречаются редко в остальная часть набора данных, поскольку эти слова, вероятно, будут более описательными для образца. Кроме того, слова с высокой общей частотой в наборе данных могут быть исключены из лексикона. В результате можно уменьшить как влияние неинформативных слов, так и размерность векторного пространства.
  3. Word2Vec: решает проблему разреженности путем обучения двухслойной нейронной системы, которая предсказывает контекст для данного слова (т. е. слово «Nike» будет чаще стоять рядом со словом «обувь», чем «бананы». ). Это сложнее вычислить, но удается создать текстовое представление малой размерности, которое кодирует тонкие семантические сходства между словами и на котором легче обучать классификаторов.

Наилучших результатов мы достигли с TF-IDF. Хотя Word2Vec определенно превосходит TF-IDF в задачах, включающих сложные семантические отношения между образцами текста, для нашего варианта использования это излишек, поскольку названия продуктов довольно упрощены и практически не содержат синтаксиса.

После предварительной обработки и векторизации мы, наконец, можем построить наш фактический классификатор текста. Мы проверили точность прогнозов для ряда моделей машинного обучения в библиотеке scikit-learn: Naive Bayes, Logistic Regression, k-Nearest Neighbours , Случайные леса, Поддержка векторных машин и Повышение градиента. Логистическая регрессия с векторизацией TF-IDF показала наилучшие результаты, что еще раз показывает, что вам не всегда нужны самые изощренные и сложные методы для достижения наилучших результатов.

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

Соответствие категорий

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

Сейчас мы можем получить общие прогнозы категорий, но нам все еще нужен механизм для сопоставления этих категорий с категориями конкретных магазинов, чтобы мы не засыпали наших клиентов (то есть разные интернет-магазины, использующие наш API) рекомендациями категорий, которые они не определили. . Если наша модель говорит, что этот продукт относится к категории браслеты, нам нужно знать, к каким категориям в магазине подходит этот запрос, поскольку могут быть некоторые различия. Для этой задачи мы использовали библиотеку gensim для обучения модели Word2Vec на большом корпусе статей в Google News, который обычно используется для оценки сходства слов. Поскольку вычисление сходства между всеми категориями моделей и всеми категориями магазинов с этой моделью может занять некоторое время, мы предварительно вычисляем эти сходства и сохраняем их в базе данных, которая обновляется каждую ночь.

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

Мы достигли нашей наивысшей точности, превышающей 90%, для магазинов модной или ювелирной промышленности, в то время как наша самая низкая точность (70–80%) была для магазинов в сфере бакалейных товаров и товаров для дома, что в основном связано с тем, что последние отрасли имеют значительную больший набор категорий и большее разнообразие их данных.

API

Чтобы раскрыть наше приложение, мы написали HTTP API в библиотеке flask. У нас есть две конечные точки: одна для прогнозов общей модели, а другая - для прогнозов для конкретного магазина. Общая конечная точка в основном используется для тестирования поведения наших классификаторов для разных изображений, имен или описаний:

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

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

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

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