Как получить рекомендации из матрицы взаимодействий
Что проверяют
Умеете ли вы пройти путь от сырой матрицы «пользователь × объект» до списка top-k, а не только назвать коллаборативную фильтрацию. Следом спрашивают, как оценивать качество офлайн и что делать с новыми пользователями.
Как отвечать
Сначала уточните данные. Явные оценки и неявные сигналы (просмотры, покупки) решаются по-разному: в неявных нет отрицательных примеров, ноль означает «не видел», а не «не понравилось». Матрица почти всегда разреженная, храните её в scipy.sparse.csr_matrix: плотный массив на миллионе пользователей в память не поместится.
Дальше методы по возрастанию сложности:
- популярность: обязательный бейзлайн, который часто трудно обогнать;
- item-based kNN: косинусная близость между столбцами матрицы, скор объекта это сумма его близостей к объектам из истории пользователя. Просто, объяснимо, хорошо работает на неявных данных;
- матричная факторизация: пользователь и объект получают векторы размерности от 32 до 256, оценка это их скалярное произведение. Для неявных данных классика ALS с весами уверенности, есть в библиотеке
implicit; - линейные модели вроде EASE: решение в замкнутой форме через обращение матрицы объект на объект, сильный результат на каталогах среднего размера.
Сам вывод: scores = user_vec @ item_factors.T, затем уже просмотренному выставить минус бесконечность и взять top-k через np.argpartition вместо полной сортировки.
Оценка: разбиение по времени, а не случайное, метрики precision@k, recall@k, NDCG@k, плюс покрытие каталога. Холодный старт закрывают контентными признаками или популярным в сегменте.
Где спотыкаются
Запускают TruncatedSVD на матрице с нулями как на полной. Нули трактуются как реальные оценки, модель учится предсказывать «не видел», а заполнение пропусков средним только размывает сигнал.
Забывают исключить уже купленное. Модель рекомендует пользователю то, что у него уже есть, и офлайн-метрики выглядят отлично.
Делят данные случайно: в тест попадает прошлое, в обучение будущее, и офлайн-результат не повторяется в A/B-тесте.