Вы когда-нибудь задумывались, как крупные корпорации, такие как Netflix и Youtube, предоставляют интересные фильмы/видео для просмотра, в то время как Spotify может автоматически создавать список воспроизведения, содержащий песни, которые могут вам понравиться? Да, ответ заключается в использовании рекомендательных систем.

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

Контентная фильтрация и совместная фильтрация

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

Сюрприз

Surprise — одна из библиотек Python на основе scikit для разработки рекомендательных систем с использованием явных рейтинговых данных. Поскольку Surprise является одной из библиотек на основе scikit, ее относительно легко использовать разработчикам, которые хорошо знакомы с библиотеками на основе scikit, такими как scikit-learn. Удобно, что Surprise предоставляет несколько алгоритмов для разработки рекомендательных систем совместной фильтрации, начиная с метода на основе памяти (например, K-ближайшие соседи или KNN) до метода на основе модели (например, разложение по сингулярным значениям или SVD).

Монтаж

Вы можете установить библиотеку Surprise, используя pip с помощью этой команды.

pip install scikit-surprise

Или, если вы больше знакомы с conda, вы можете использовать эту команду.

conda install -c conda-forge scikit-surprise

Набор данных

В этом эксперименте мы будем использовать набор данных MovieLens (уменьшенная версия: https://files.grouplens.org/datasets/movielens/ml-latest-small.zip), который находится в открытом доступе на сайте GroupLens (https:// grouplens.org/datasets/movielens/). Набор данных состоит из 100 000 оценок 9 000 фильмов и 600 пользователей. Мы также будем использовать метаданные фильмов, которые содержат названия фильмов для каждого идентификатора фильма. Во-первых, нам нужно прочитать набор данных, используя приведенный ниже код. Обратите внимание, что мы помещаем набор данных в каталог Набор данных.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
 
ratings_data = pd.read_csv("Dataset/ratings.csv")
movies_data = pd.read_csv("Dataset/movies.csv")

Пример набора данных:

Пример метаданных фильма:

Подготовьте набор обучающих данных-сюрпризов

Прежде чем мы перейдем к части моделирования, нам нужно преобразовать наш набор данных в объект набора данных из библиотеки Surprise. Для этого нам нужно определить объект Reader, чтобы иметь возможность анализировать DataFrame. Нам также необходимо следовать определенному порядку столбцов: идентификатор пользователя, идентификатор элемента и рейтинг.

from surprise import Dataset
from surprise import Reader
 
# Get minimum and maximum rating from the dataset
min_rating = ratings_data.rating.min()
max_rating = ratings_data.rating.max()
 
reader = Reader(rating_scale=(min_rating, max_rating))
data = Dataset.load_from_df(ratings_data[['userId', 'movieId', 'rating']], reader)

Моделирование

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

На этапе проверки мы можем использовать метод 10-кратной перекрестной проверки, который также встроен в библиотеку Surprise. Следовательно, мы могли бы использовать следующие показатели для оценки:

  • Среднеквадратичная ошибка (RMSE)
  • Средняя абсолютная ошибка (MAE)
from surprise import SVD
from surprise.model_selection import cross_validate
 
svd = SVD(n_epochs=10)
results = cross_validate(svd, data, measures=['RMSE', 'MAE'], cv=10, verbose=True)

Запуск кода выше даст аналогичный результат.

Производительность модели можно оценить, отдельно наблюдая средние значения MAE и RMSE.

print("Average MAE: ", np.average(results["test_mae"]))
print("Average RMSE: ", np.average(results["test_rmse"]))

Настройка гиперпараметров

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

from surprise import SVD
from surprise.model_selection import GridSearchCV
 
param_grid = {
  'n_factors': [20, 50, 100],
  'n_epochs': [5, 10, 20]
}
 
gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mae'], cv=10)
gs.fit(data)
 
print(gs.best_score['rmse'])
print(gs.best_params['rmse'])

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

После того, как будут получены лучшие гиперпараметры, мы можем переобучить модель, используя эти гиперпараметры.

from surprise.model_selection import train_test_split
 
# best hyperparameters
best_factor = gs.best_params['rmse']['n_factors']
best_epoch = gs.best_params['rmse']['n_epochs']
 
# sample random trainset and testset
# test set is made of 20% of the ratings.
trainset, testset = train_test_split(data, test_size=.20)
 
# We'll use the famous SVD algorithm.
svd = SVD(n_factors=best_factor, n_epochs=best_epoch)
 
# Train the algorithm on the trainset
svd.fit(trainset)

Рекомендуемые фильмы

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

def generate_recommendation(model, user_id, ratings_df, movies_df, n_items):
   # Get a list of all movie IDs from dataset
   movie_ids = ratings_df["movieId"].unique()
 
   # Get a list of all movie IDs that have been watched by user
   movie_ids_user = ratings_df.loc[ratings_df["userId"] == user_id, "movieId"]
    # Get a list off all movie IDS that that have not been watched by user
   movie_ids_to_pred = np.setdiff1d(movie_ids, movie_ids_user)
 
   # Apply a rating of 4 to all interactions (only to match the Surprise dataset format)
   test_set = [[user_id, movie_id, 4] for movie_id in movie_ids_to_pred]
 
   # Predict the ratings and generate recommendations
   predictions = model.test(test_set)
   pred_ratings = np.array([pred.est for pred in predictions])
   print("Top {0} item recommendations for user {1}:".format(n_items, user_id))
   # Rank top-n movies based on the predicted ratings
   index_max = (-pred_ratings).argsort()[:n_items]
   for i in index_max:
       movie_id = movie_ids_to_pred[i]
       print(movies_df[movies_df["movieId"]==movie_id]["title"].values[0], pred_ratings[i])
 
 
# define which user ID that we want to give recommendation
userID = 23
# define how many top-n movies that we want to recommend
n_items = 10
# generate recommendation using the model that we have trained
generate_recommendation(svd,userID,ratings_data,movies_data,n_items)

Вывод должен быть похож на следующий результат.

Наконец, мы можем получить первые n рекомендаций по элементам для определенного идентификатора пользователя.

Ключевые выводы

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

Рекомендации

[1] https://surprise.readthedocs.io/en/stable/
[2] https://towardsdatascience.com/how-you-can-build-simple-recommender-systems-with -сюрприз-b0d32a8e4802