Руководство по изучению и внедрению рекомендательных систем в Python

Что такое рекомендательная система?

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

Какие бывают типы рекомендательных систем?

Два наиболее распространенных типа:

  1. Информационные рекомендательные системы
  2. Совместная фильтрация

Что такое система рекомендаций, основанная на содержании?

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

Что такое совместная фильтрация?

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

  1. CF на основе памяти
  2. CF на основе модели

Как реализовать CF на основе элементов с помощью Python

Набор данных, используемый для этой демонстрации, является подмножеством набора данных MovieLens. Будет создана базовая система рекомендаций, которая предложит фильмы, наиболее похожие на конкретный фильм.

Импорт библиотек

Основные пакеты для работы с данными, такие как NumPy и pandas, импортируются. Наряду с этим импортируются библиотеки визуализации matplotlib и seaborn.

>>> import numpy as np
>>> import pandas as pd
>>> import matplotlib.pyplot as plt
>>> import seaborn as sns
>>> sns.set_style('white')
>>> %matplotlib inline

Чтение данных

Присваиваются имена столбцам и считываются данные:

>>> column_names = ['user_id', 'item_id', 'rating', 'timestamp']
>>> df = pd.read_csv('dataset/df.data', sep='\t', names=column_names)
>>> df.head()

Теперь названия фильмов добавляются к DataFrame.

>>> titles = pd.read_csv("dataset/movie_title")
>>> titles.head()

>>> df = pd.merge(df,titles,on='item_id')
>>> df.head()

Визуализация

DataFrame для оценок создается на основе его общего количества и среднего значения. Среднее значение рассчитывается путем вызова функции mean():

>>> ratings = pd.DataFrame(df.groupby('title')['rating'].mean())
>>> ratings.head()

Итого рассчитывается путем вызова функции count():

>>> ratings['total_ratings'] = pd.DataFrame(df.groupby('title')['rating'].count())
>>> ratings.head()

Теперь можно визуализировать гистограммы для средних оценок и общих оценок, выставленных пользователями:

>>> ratings['rating'].hist(bins=50)

Таким образом, средние оценки находятся в диапазоне от 1 до 5, и их распределение можно увидеть там, где среднее значение находится рядом с рейтингом 3,5.

>>> ratings['total_ratings'].hist(bins=50)

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

>>> sns.jointplot(x='rating',y='total_ratings',data=ratings,alpha=0.5)

Этот график показывает соотношение между средними оценками и общими оценками.

Постройте систему

Идентификатор пользователя и названия фильмов извлекаются и превращаются в индекс и столбец соответственно. Таким образом, можно представить оценку каждого фильма для каждого фильма.

>>> final_df = df.pivot_table(index='user_id',columns='title',values='rating')
>>> final_df.head()

Теперь выбран один фильм (История игрушек), который относится к жанру фэнтези. Получены оценки пользователей:

Теперь связь между другими фильмами и Историей игрушек выясняется с помощью метода corrwith():

>>> similar_to_toy = final_df.corrwith(toy_ratings)

Эти корреляции представлены в форме DataFrame, а нулевые значения отбрасываются.

>>> corr_toy = pd.DataFrame(similar_to_toy,columns=['Correlation'])
>>> corr_toy.dropna(inplace=True)
>>> corr_toy.head()

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

>>> corr_toy.sort_values('Correlation',ascending=False).head()

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

>>> corr_toy = corr_toy.join(ratings['total_ratings'])
>>> corr_toy.head()

>>> corr_toy[corr_toy['total_ratings']>100].sort_values('Correlation',ascending=False).head()

Итак, это фильмы, похожие на История игрушек. Все эти фильмы тоже относятся к категории фантастических.

См. набор данных и записную книжку на GitHub.