- Видео-презентация (10 минут) + оценка эксперта
- Презентация в Google Slides
- Датасет на kaggle: Instacart dataset
- Описание задачи
- Итоги
- https://github.com/d-01/instacartlib
- Разработанная, согласно техническому заданию, программная библиотека-обертка для ML модели.
- https://colab.research.google.com/drive/1aFc-e_u5W-BrA7cdp6E2qZsgZtiJCGC8
- Демонстрация программной библиотеки в Google Colab
- https://github.com/d-01/graduate-2022-rec-sys/blob/main/submission.csv
- Файл для оценки модели на платформе kaggle
- Private / public score: 0.31839 / 0.32082
- Алгоритм предсказания покупок пользователя:
- Точность по метрике MAP@10 > 0.25
- Время обучения: не более 5 часов.
- Прогнозирование на всех покупателей: не более 15 минут.
- Программная библиотека со следующими функциями:
- Выдать K релевантных товаров по ID одного или нескольких пользователей.
- Добавить новые данные о транзакциях и о товарах.
- Обучить рекомендательную систему заново.
Датасет состоит из 2 файлов:
- transactions.csv (26M, 9) - транзакции покупателей
- products.csv (50k, 6) - товары, отделы, категории
- order_id - уникальный идентификатор заказа
- user_id - уникальный идентификатор пользователя (100 000)
- order_number - порядковый номер заказа в истории покупок пользователя (1-99)
- order_dow - день недели формирования заказа (0-6)
- order_hour_of_day - час дня формирования заказа (0-23)
- days_since_prior_order - число дней с совершения предыдущего заказа данным пользователем
- product_id - уникальный идентификатор товара (49 465)
- add_to_cart_order - порядковый номер товара при добавлении в корзину
- reordered - был ли товар "перезаказан"
- product_id - уникальный идентификатор товара
- product_name - название товара
- aisle_id - уникальный идентификатор категории (134)
- department_id - уникальный идентификатор отдела (21)
- aisle - название категории
- department - название отдела
Next Basket Prediction / Предсказание целевой корзины
Next Basket -- целевая корзина, следующая после последней:
User orders:
1 | 32792 47766 20574 12000 48110 22474 16589 35917 27344 30489 27966 13176
2 | 16797 47526 8479 47766 19051 8138
... | 47766 32792 20574 7781 28874
N | 49451 32792 32139 34688 36735 37646 22829 24852 47209 33276 45613 9681
N+1 | ? ? ? ? ? ? ? ? ? ?
Mean Average Precision at 10 / MAP@10
Если обычная точность (precision) оценивает все релевантные элементы равноценно, то AP@K снижает оценку если релевантный элемент, стоит в списке ниже нерелевантного.
От чего зависит оценка (score) по метрике MAP@K:
- Чем больше релевантных элементов (верных предсказаний), тем выше оценка.
- Любой релевантный элемент, должен быть выше любого нерелевантного, нарушение этого порядка дополнительно снижает оценку.
- Повторяющиеся релевантные элементы учитываются как нерелевантные, т.е. снижают оценку.
От чего не зависит оценка:
- Если поменять местами два релевантных или два нерелевантных элемента оценка не изменится.
- Предсказания ниже первых k, не учитываются.
Генеративная нейросеть
- Предсказание вектора заказа с помощью нейросети (TCN 14k).
Коллаборативная фильтрация
- SVD, 100 (implicit), последние 10 заказов, только из купленных ранее.
TIFU-KNN
- Предсказание с помощью модели TIFU-KNN (k=300, a=0.9): 90% индивидуальный компонент + 10% коллаборативный компонент.
Частотная модель
- Индивидуальный топ 10 из последних 8 заказов + сортировка по AvgCartPos
Классификатор
- Задача бинарной классификации: пара пользователь-товар относится к классу
1
если пользователь добавит товар в целевую корзину,0
-- если нет. - CatBoostClassifier (21 признак) + популярные товары
МЕТОД | MAP@10 |
---|---|
Топ 10 популярных | 0.04858 |
Предсказание вектора корзины с помощью нейросети (TCN 14k) | 0.04938 |
SVD, 128 (surpriselib) | 0.08375 |
SVD, 100 (implicit) | 0.12076 |
SVD, 100 (implicit), последние 10 заказов | 0.13518 |
SVD, 100 (implicit), только из купленных ранее | 0.14569 |
SVD, 100 (implicit), последние 10 заказов, только из купленных ранее | 0.16385 |
Зачет | 0.25000 |
Индивидуальный топ 10 из последних 10 заказов + SVD для сортировки | 0.25777 |
Индивидуальный топ 10 | 0.27455 |
Индивидуальный топ 10 из последних 5 заказов | 0.29526 |
Предсказание с помощью TIFU-KNN (a=1.0) | 0.29716 |
Предсказание с помощью TIFU-KNN (k=300, a=0.9) | 0.30036 |
Индивидуальный топ 10 из последних 11 заказов | 0.30108 |
Индивидуальный топ 10 из последних 10 заказов | 0.30199 |
Индивидуальный топ 10 из последних 9 заказов | 0.30275 |
Индивидуальный топ 10 из последних 7 заказов | 0.30291 |
Индивидуальный топ 10 из последних 8 заказов | 0.30326 |
Индивидуальный топ 10 из последних 10 заказов + сортировка по AvgCartPos | 0.30381 |
Линейный классификатор (12 фичей) | 0.30572 |
Индивидуальный топ 10 из последних 8 заказов + сортировка по AvgCartPos | 0.30716 |
Линейный классификатор (13 фичей) | 0.30856 |
Линейный классификатор (13 фичей) + коллаб. фильтр. по схожим товарам | 0.30868 |
Линейный классификатор (13 фичей) + коллаб. фильтр. по схожим пользователям | 0.30876 |
Линейный классификатор (16 фичей) | 0.31347 |
Линейный классификатор (17 фичей) | 0.31431 |
GBC (21 фича) | 0.31785 |
GBC (21 фича) + популярные товары | 0.31803 |
CatBoostClassifier (21 фича) + популярные товары | 0.31839 |
В следующих разделах дано более подробное описание 5-и моделей.
Простая частотная модель или индивидуальный топ-10 основана на подсчете покупок каждого товара индивидуально для каждого пользователя.
Для каждого пользователя:
- Считаем частоту покупок каждого товара.
- Сортируем купленные товары по частоте и используем топ-10 в качестве предсказаний.
Улучшения:
- Используем не более 8 последних заказов каждого пользователя.
- Дополнительно сортируем товары по средней позиции в корзине пользователя (AvgCartPos).
Участник, занявший 3е место в соревновании Instacart Market Basket Analysis, использовал чисто нейросетевой подход (без фичей, созданных вручную / hand-crafted features) [подробнее].
Второе место занял участник использовав hand-crafted фичи [подробнее].
История пользователя состоит из последовательности заказов. Каждый заказ (корзина) представляется m-hot вектором из 0 и 1. Длина вектора равна числу всех возможных товаров.
Тогда задача сводится к NLP задаче генерации последовательности:
- Слово (embedding) = корзина (m-hot вектор)
- Предложение (sequence) = история заказов (history)
Обучающий датасет: n - 1
заказ (кроме последнего), последний заказ используется как метка.
Тестовый датасет: n - 1
заказ (включая последний), предсказывается следующий (целевой).
Архитектура нейросети: Temporal Convolutional Network (TCN, Bai et al., 2018).
- Подробнее: TCN.md
- Нейросеть работает лучше случайной модели, но точность равносильна примитивной модели, усредняющей входные вектора.
- Нейросеть схлопнулась (collapsed) к константному решению: для любого пользователя один и тот же ответ, состоящий из самых популярных товаров, поэтому точность такая же как "Топ 10 популярных".
- Недостаточный размер нейросети для данный задачи.
- Стоило увеличить число параметров до 14M (увеличить в 1000 раз, 14k * 1000 = 14M).
- Проблемы совместимости нестандартных тензоров (sparse / ragged) и некоторых слоев (Conv1D) в Keras.
- Трудности при выборе функции потерь для задачи multilabel classification:
- Классификация на бесконечное число классов.
- Низкая эффективность обучения, низкая точность.
Long format (26M rows):
Wide format (sparse, 5000M):
- Density: 0.2% (0.001912)
- Sparsity: 99.8% (0.998087)
SVD разложение:
- Точность возрастает, если не учитывать покупки сделанные давно.
- Не смотря на то, что плотность матрицы рейтингов снижается, т.е.:
- Для всех заказов density=0.19%
9459065 / (100000 * 49465) = 0.001912
- Для последних 10 density=0.11%
5470374 / (100000 * 48297) = 0.001133
- Для всех заказов density=0.19%
- Не смотря на то, что плотность матрицы рейтингов снижается, т.е.:
- Область применения коллаборативной фильтрации:
- Предсказание рейтингов (explicit feedback).
- Предсказание однократных покупок (implicit feedback).
- Поиск похожих товаров (item similarity).
- Поиск похожих пользователей (user similarity).
- Не подходит для периодических покупок, уступает простой частотной модели.
Temporal-Item-Frequency-based User-KNN (TIFU-KNN) -- рекомендации для каждого пользователя основаны на сумме двух векторов: индивидуальный компонент (PIF) и коллаборативный компонент.
Способ описанный в научной работе от 31 мая 2020 года (https://arxiv.org/abs/2006.00556):
Рекомендации Основанные на Персонализированной Частотности Товаров
Personalized Item Frequency (PIF) -- векторное представление истории покупок пользователя. Длина вектора равна количеству всевозможных товаров.
Анализ датасета Instacart:
- В среднем 3 из 10 товаров в корзине пользователя заказаны впервые.
- 3 из 4 товаров можно найти в заказах похожих пользователей.
- 11% товаров в корзине не предсказуемы этой моделью, т.к. ни сам пользователь ни похожие пользователи ранее не покупали этот товар.
PIF / Personalized Item Frequency
Каждый заказ (корзина) представляется бинарным m-hot вектором, где 1 стоит напротив добавленных в корзину товаров.
Векторное представление истории покупок пользователя или, просто, вектор пользователя рассчитывается как взвешенная сумма векторов корзин с иерархическим (group + basket) затухающим коэффициентом.
Без затухания:
order | 0 1 2 3 4 5 6 7 8 9 | sum
----- | ------------------------------------------------ | ---
prod1 | 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 | 5.0
prod2 | 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 | 5.0
- Одинаковое значение для товара купленного давно (
prod1=5.0
) и для товара купленного недавно (prod2=5.0
).
С затуханием:
order | 0 1 2 3 4 5 6 7 8 9 | sum
----- | ------------------------------------------------ | ---
prod1 | 0.1 0.2 0.3 0.4 0.5 0.0 0.0 0.0 0.0 0.0 | 1.5
prod2 | 0.0 0.0 0.0 0.0 0.0 0.6 0.7 0.8 0.9 1.0 | 4.0
- Для товара купленного давно значение меньше (
prod1=1.5
), чем для товара купленного недавно (prod2=4.0
).
Предсказание состоит из двух компонентов:
-
Индивидуальный компонент (repeated purchase component) представлен как вектор пользователя
$u_t$ (PIF). -
Коллаборативный компонент представлен как усредненный PIF вектор похожих пользователей (ближайших соседей):
$u_n = \text{avg}(U_{neighbor})$ , где$U_{neighbor}$ вектора ближайших$k$ соседей ($k=300$ ).
Задача:
- Для расчета коллаборативного компонента для каждого из 100 000 пользователей необходимо найти 300 ближайших соседей используя PIF вектора пользователей.
Доп. условия:
- Разряженные вектора (CSR format)
- Длина вектора = 49 465
Время работы примитивной реализации KNN: ≈6 часов.
Для уменьшения времени необходимо использовать алгоритм ANN (Approximate Nearest Neighbour). В этой работе я использовал его открытую реализацию facebookresearch/pysparnn, т.к. она поддерживает разряженные вектора.
Время работы ANN составило 5 минут.
- При
$\alpha=1.0$ , 100% информации берется из истории пользователя. - При
$\alpha=0.9$ , 90% информации берется из истории пользователя (индивидуальный компонент), а 10% из истории 300 похожих пользователей (коллаборативный компонент).
- 70% товаров пользователь заказывал ранее.
- До 20% товаров, заказанных пользователем впервые, можно найти в истории похожих пользователей.
- 10% товаров, заказанных впервые, не встречаются в истории пользователя, ни похожих пользователей.
- Затухающий коэффициент дает прирост в оценке. При
$\alpha=1.0$ без затухающего коэффициента модель равносильна простой частотной модели:- Без коэффициента затухания: 0.27455
- С коэффициентом затухания: 0.29716
Задача сводится к задаче бинарной классификации: для каждой пары пользователь-товар (user-item) модель предсказывает значение 1
, если товар будет перезаказан (есть в целевой корзине), 0
если нет.
Для этого необходимо подготовить два датасета: тренировочный для обучения классификатора и тестовый, на котором выполняется предсказание целевой корзины.
В качестве негативных сэмплов используются товары из истории пользователя, не попавшие в целевую корзину.
- В тренировочном датасете используются 5 предпоследних заказов, а последний в качестве целевого.
На основании таблицы транзакций рассчитываются признаки (features / фичи). Целевой признак: in_target
= 1 если товар есть в целевой корзине, 0 если нет.
- В тестовом датасете используются 5 последних заказов, а следующий (целевой) предсказывается с помощью обученной модели классификатора.
Для каждой пары пользователь-товар выходной вектор содержит значение в интервале [0, 1] выражающее вероятность перезаказа товара Б пользователем А. Для финального предсказания товары сортируются по убыванию вероятности.
Конструирование фичей
В противоположность нейросетевому подходу, где фичи формируются нейросетью, в данном методе фичи создаются специалистом вручную. Конструирование оптимальных фичей требует экспертных знаний в данной прикладной (domain) области (розничная торговля, периодические покупки) и глубокого понимания датасета.
Признаки 3-х типов:
- Признаки пользователя (
u_
user):- Например: число транзакций, число уникальных товаров в истории, число заказов, средний размер заказа, среднее время между заказами и т.д.
- Признаки товара (
i_
item):- Например: сколько пользователей купили этот товар, сколько раз в среднем пользователь покупает этот товар, среднее время между заказами этого товара и т.д.
- Признаки взаимодействия пользователя с конкретным товаром (
ui_
user-item):- Например: сколько раз пользователь купил определенный товар, дней с момента последнего заказа этого товара, средняя позиция товара в корзине и т.д.
-
i_days_delay_global_mid
-- средний интервал между заказами товара Б среди всех пользователей;- Как часто пользователи в среднем перезаказывают товар Б.
-
ui_total_buy_ratio
-- доля заказов пользователя А, в которых есть товар Б;- = 1.0 если товар Б есть в 10 из 10 заказов пользователя А.
- = 0.2 если товар Б есть в 2 из 10 заказов пользователя А.
-
u_n_transactions
-- число транзакций пользователя А;- Отражает активность пользователя.
-
u_unique_items
-- число уникальных товаров в истории покупок пользователя А;- Отражает его склонность пробовать новые товары.
-
ui_total_buy
-- число заказов пользователя А, в которых есть товар Б; -
ui_readyness_mid_abs
-- отклонение пользователя А от привычного интервала перезаказа товара Б.
Показатель readyness
(готовность):
- Например в среднем между заказами товара Б проходит 10 дней, т.е.
ui_days_delay_mid
= 10. - Последний раз пользователь купил товар Б 12 дней назад, т.е.
ui_days_passed
= 12. - Тогда
ui_readyness_mid = (ui_days_passed - ui_days_delay_mid)
= 2- Отрицательные значения = с последнего заказа прошло слишком мало времени, пользователь не готов купить товар.
- Большое значение = прошло больше времени чем обычно, пользователь готов купить товар.
Полное описание всех признаков в приложении.
- На точность предсказаний влияет качество и количество фичей.
- Точность этого способа превосходит простую частотную модель, т.к. позволяет задействовать дополнительную информацию, например об интервале между заказами, времени суток и дне недели.
-
Одни и те же методы не подходят для разных типов товаров:
-
Фильмы, музыка, книжный магазин
- Однократные покупки
- Задача: коллаборативная фильтрация
- Рекомендации на основе похожих пользователей или товаров
-
Гипермаркеты (еда, продовольственные товары)
-
Периодические покупки
-
Задача: генерация следующего набора элементов (NBR / NBP / Sets2sets)
-
Простые модели: подсчет покупок, средний интервал между заказами
-
-
Техника, услуги, одежда
-
Смешанные покупки: однократные + периодические
-
Задача: генерация следующего элемента последовательности (Seq2seq)
-
-
-
Коллаборативная фильтрация подходит для рекомендаций (фильмы, однократные покупки), но не подходит для предсказания периодических покупок
Установка:
pip install https://github.com/d-01/instacartlib/archive/main.zip
Загрузка датасета:
from instacartlib import InstacartDataset
InstacartDataset(verbose=1).download(to_dir='instacart_data')
Инициализация API и загрузка предобученной модели:
from instacartlib import NextBasketPrediction
nbp = NextBasketPrediction(verbose=1)
nbp.add_data('instacart_data')
nbp.load_model('catboost') # or 'gbc'
Получить предсказания / рекомендации для указанных пользователей:
nbp.get_predictions(user_ids=[20001, 85768])
nbp.predictions_to_csv('submission.csv')
submission.csv:
user_id,product_id
1,196 12427 25133 10258 46149 39657 38928 35951 13032 49235
2,47209 19156 1559 18523 33754 16589 21709 24852 39928 22825
3,39190 47766 43961 21903 17668 18599 16797 48523 32402 22035
...
Обучение новой модели:
nbp_new = NextBasketPrediction(verbose=1)
nbp_new.add_data('instacart_data')
nbp_new.train_model()
nbp_new.save_model('model_nbp.dump')
Время обучения модели (Google Colab):
- ≈25 мин. (GBC)
- ≈17 мин. (CatBoost)
- ≈1 мин. (CatBoost, GPU)
Время генерации предсказаний: ≈2 сек.
(п. А = пользователь А; товар Б)
u_n_orders
: число заказов п. А.ui_n_chances
: число заказов п. А после первой покупки товара Б (включительно).ui_total_buy
: число заказов товара Б пользователем А.ui_total_buy_ratio
: =ui_total_buy / u_n_orders
доля заказов п. А в которых есть товар Б.ui_chance_buy_ratio
: =ui_total_buy / u_n_chances
доля заказов п. А, в которых есть товар Б, после первой покупки товара Б.u_n_transactions
: число транзакций пользователя А.u_unique_items
: число уникальных товаров в истории п. А.u_order_size_mid
: средний размер корзины п. А.i_n_popularity
: число пользователей, купивших товар Б хотя бы раз.i_n_orders_mid
: среднее число заказов товара Б среди пользователей, купивших его хотя бы раз.ui_avg_cart_pos
: средняя позиция товара Б. в корзине пользователя А.ui_days_delay_max
: максимальная задержка (дней) между покупками товара Б пользователем А.ui_days_delay_mid
: медианная задержка (дней) между покупками товара Б пользователем А.i_days_delay_global_mid
: медианная задержка (дней) между покупками товара Б среди всех пользователей.ui_days_passed
: прогнозируемое число дней до следующего заказа пользователя А.ui_readyness_max
: дней до следующего заказа п. А сверх своей максимальной задержки между покупками товара Б. Пример:readyness=10
: пользователь А не покупал товар Б больше 10 дней сверх своей обычной задержки.readyness=-10
: пользователь А может "обойтись" без товара Б еще 10 дней.
ui_readyness_max_abs
: модуль значенияreadyness
. Большое значение сигнализирует о нетипичном отклонении в поведении пользователя относительно своего обычного поведения.ui_readyness_mid
: аналогичноui_readyness_max
для медианы.ui_readyness_mid_abs
: аналогичноui_readyness_max_abs
для медианы.ui_readyness_global_mid
: задержка п. А в покупке товара Б сверх общей задержки среди всех пользователей покупающих этот товар.ui_readyness_global_mid_abs
: модуль значенияui_readyness_global_mid
. Большое значение сигнализирует о нетипичном отклонении в поведении пользователя относительно других пользователей.
u_n_orders
: total number of orders made by user.ui_n_chances
: number of orders in which user A had a chance to buy item B. That is a number of orders following the order in which user A bought item B, including the order itself.ui_total_buy
: times user A bought item B.ui_total_buy_ratio
: = ui_total_buy / u_n_ordersui_chance_buy_ratio
: = ui_total_buy / u_n_chancesu_n_transactions
: number of user's A transactions.u_unique_items
: number of unique items in user's A history.u_order_size_mid
: user's A average order size.i_n_popularity
: number of users who purchaised this item at least once.i_n_orders_mid
: number of purchaises on average across all users who purchaised this item at least once.avg_cart_pos
: position of item B in user's A cart on average.ui_days_delay_max
: the longest (in days) user A gone without buying item B.ui_days_delay_mid
: median number of days user A gone without buying item B.i_days_delay_global_mid
: median number of days any user gone without buying item B.ui_days_passed
: days passed since last order (prediction based on medium delay between user's orders).ui_readyness_max
: days passed exceeds max delay for particular item. Example:readyness=10
: means user hasn't bought the item more then 10 days above his longest delay.readyness=-10
: 10 days left until delay exceeds maximum delay, i.e. user probably can go longer without buying this item.
ui_readyness_max_abs
: absolute value of readyness. The bigger the value the more unusual is delay.ui_readyness_mid
: days passed exceeds median delay for particular item.ui_readyness_mid_abs
: absolute value ofui_readyness_mid
.ui_readyness_global_mid
: user readyness relative to global delay for particular item.ui_readyness_global_mid_abs
: absolute value ofui_readyness_global_mid
.
graduate-2022-rec-sys's People
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.