Введение в системы рекомендаций

Системы рекомендаций — это незаметные герои цифровой эпохи, которые облегчают нашу жизнь, предлагая продукты, фильмы, книги и даже музыку, которые могут нам понравиться. Эти системы повсеместны: от раздела «Рекомендуем для вас» на Netflix до предложений «Вам также может понравиться» на Amazon. В этой статье мы погрузимся в мир систем рекомендаций, уделяя особое внимание тому, как создать такую систему с помощью Python и мощной библиотеки scikit-learn.

Типы систем рекомендаций

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

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

Подготовка данных

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

import pandas as pd

movies = pd.read_csv('movies.csv')
ratings = pd.read_csv('ratings.csv')

# Удаление повторяющихся строк
movies.drop_duplicates(inplace=True)
ratings.drop_duplicates(inplace=True)

# Удаление пропущенных значений
movies.dropna(inplace=True)
ratings.dropna(inplace=True)

Предварительная обработка данных

Предварительная обработка данных имеет решающее значение для обеспечения чистоты и готовности данных к анализу.

# Извлечение столбца жанров
genres = movies['genres']

# Создание экземпляра OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder()

# Подбор и преобразование столбца жанров
genres_encoded = encoder.fit_transform(genres.values.reshape(-1, 1))

Создание системы рекомендаций на основе контента

Извлечение признаков

Для системы рекомендаций на основе содержимого нам необходимо извлечь признаки из элементов (в данном случае фильмов). Здесь мы будем использовать жанры фильмов в качестве признаков.

# Использование OneHotEncoder для преобразования жанров в числовой формат
genres_encoded = encoder.fit_transform(genres.values.reshape(-1, 1))

Создание рекомендателя

Мы будем использовать класс NearestNeighbors из scikit-learn для создания нашей системы рекомендаций. Мы будем использовать косинусную близость в качестве метрики для измерения сходства между фильмами.

from sklearn.neighbors import NearestNeighbors

# Создание экземпляра класса NearestNeighbors
recommender = NearestNeighbors(metric='cosine')

# Подгонка закодированных жанров к рекомендателю
recommender.fit(genres_encoded.toarray())

Предоставление рекомендаций

Чтобы давать рекомендации, нам нужно передать индекс фильма, который ранее посмотрел пользователь. Система вернёт индексы наиболее похожих фильмов.

# Индекс фильма, просмотренного пользователем
movie_index = 0

# Количество рекомендаций для возврата
num_recommendations = 5

# Получение рекомендаций
_, recommendations = recommender.kneighbors(genres_encoded[movie_index].toarray(), n_neighbors=num_recommendations)

# Извлечение названий фильмов из рекомендаций
recommended_movie_titles = movies.iloc[recommendations[0]]['title']

Создание системы коллаборативной фильтрации рекомендаций

Коллаборативная фильтрация — ещё один мощный подход, основанный на рекомендациях элементов на основе предпочтений других пользователей.

Подготовка данных

Для коллаборативной фильтрации нам нужно создать матрицу взаимодействия пользователя и элемента.

# Создание матрицы взаимодействия пользователя и элемента
user_item_matrix = ratings.pivot(index='userId', columns='movieId', values='rating')

Обработка пропущенных значений

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

# Заполнение пропущенных значений 0 (при условии, что у не оценённых фильмов рейтинг 0)
user_item_matrix.fillna(0, inplace=True)

Построение коллаборативного фильтра

Мы снова будем использовать класс NearestNeighbors, но на этот раз для поиска похожих пользователей или элементов.

# Создание экземпляра класса NearestNeighbors для коллаборативной фильтрации на основе пользователя
user_recommender = NearestNeighbors(metric='cosine')

# Установка матрицы «пользователь — элемент» для рекомендателя
user_recommender.fit(user_item_matrix)

# Создание экземпляра класса NearestNeighbors для коллаборативной фильтрации элементов
item_recommender = NearestNeighbors(metric='cosine')

# Настройка транспонированной матрицы «пользователь — элемент» для рекомендательной системы
item_recommender.fit(user_item_matrix.T)

Предоставление рекомендаций

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

# Идентификатор пользователя, для которого мы хотим дать рекомендации
user_id = 1

# Количество рекомендаций для возврата
num_recommendations = 5

# Получение рекомендаций для пользователя
_, user_recommendations = user_recommender.kneighbors(user_item_matrix.loc[user_id].values.reshape(1, -1), n_neighbors=num_recommendations)

# Извлечение идентификаторов фильмов из рекомендаций
recommended_movie_ids = user_item_matrix.columns[user_recommendations[0]]

# Альтернативно для коллаборативной фильтрации на основе элементов
_, item_recommendations = item_recommender.kneighbors(user_item_matrix.loc[user_id].values.reshape(1, -1), n_neighbors=num_recommendations)

# Извлечение идентификаторов фильмов из рекомендаций
recommended_movie_ids = user_item_matrix.columns[item_recommendations[0]]

Оценка системы рекомендаций

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

from sklearn.metrics import precision_score, recall_score, f1_score

# Предположим, у нас есть список фактических оценок и прогнозируемых оценок
actual_ratings = [1, 0, 1, 0, 1]
predicted_ratings = [1, 1, 1, 0, 0]

# Расчёт точности, полноты и показателя F1
precision = precision_score(actual_ratings, predicted_ratings)
recall = recall_score(actual_ratings, predicted_ratings)
f1 = f1_score(actual_ratings, predicted_ratings)

print(f"Точность: {precision}, Полнота: {recall}, Показатель F1: {f1}")

Визуализация процесса

Вот простая блок-схема, иллюстрирующая этапы построения системы рекомендаций:

graph TD A("Сбор данных") --> B("Предварительная обработка данных") B --> C("Извлечение признаков") C --> D("Создание модели рекомендаций") D --> E("Предоставление рекомендаций") E --> F("Оценка модели") F --> G("Доработка модели") G --> E

Заключение

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

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