Совместная фильтрация на основе элементов — это система рекомендаций, использующая сходство между элементами с использованием оценок пользователей.

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

В этом примере рейтинг Movie_1 by User_1 пуст. Давайте предскажем этот рейтинг, используя совместную фильтрацию на основе элементов.

  • Шаг 1. Найдите наиболее похожие (ближайшие) фильмы к фильму, рейтинг которого вы хотите спрогнозировать.

Есть несколько способов найти ближайшие фильмы. Здесь я использую косинусное сходство. При использовании подобия косинуса замените отсутствующее значение на 0. Посмотрите на график ниже. ось X представляет рейтинги по User_0, а ось Y — рейтинги по User_1. Затем мы можем найти точки для каждого фильма в пространстве. Например, Movie_3 соответствует точке (5,2) в пространстве.

Косинусное подобие использует cos(θ) для измерения расстояния между двумя векторами. По мере увеличения θ cos (θ) уменьшается (cos (θ) = 1, когда θ = 0, и cos (θ) = 0, когда θ = 90). Следовательно, чем меньше значение θ, тем два вектора считаются более близкими (сходство становится больше). Поскольку θ1 — наименьшее, а θ3 — наибольшее, Movie_3 находится ближе всего к Movie_1, а Movie_2 — дальше всего.

Примечательно, что сходство между фильмами определяется ВСЕМИ ПОЛЬЗОВАТЕЛЯМИ. Например, сходство между Movie_1 и Movie_3 рассчитывается с использованием рейтингов User_0 и User_1.

  • Шаг 2. Рассчитайте средневзвешенное значение оценок пользователя для наиболее похожих фильмов.

Пользователь ставит одинаковые оценки похожим фильмам. Поэтому, когда мы прогнозируем рейтинг фильма пользователем, разумно использовать средний рейтинг аналогичных фильмов пользователем. Установите количество ближайших соседей равным 2. Затем мы используем Movie_3 и Movie_0, чтобы предсказать рейтинг для Movie_1 на User_1.

Оценка для Movie_3 от User_12, а оценка для Movie_0 от User_1 — 3. Если Movie_3 и Movie_0 похожи на Movie_1 на том же расстоянии, мы можем оценить рейтинг для Movie_1 на User_1 как 2,5. Однако, если Movie_3 считается более близким к Movie_1, вес для Movie_3 должен быть больше, чем для Movie_0. Следовательно, прогнозируемый рейтинг для Movie_1 будет ближе к рейтингу для Movie_3, как показано на рисунке ниже. Используя косинусное сходство в качестве веса, прогнозируемый рейтинг равен 2,374.

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

Для лучшего понимания здесь используется набор данных с 10 фильмами и 10 пользователями. (числа выбираются случайным образом).

df

  • 10 фильмов и 10 пользователей
  • 0 представляет отсутствующие значения.
  • Процент пользователей, оценивающих фильмы, составляет 50% (даны только 50 оценок). В реальных наборах данных фильмов этот процент становится меньше 10%.

Я предполагаю, что пользователь не смотрел фильм, если пользователь не оценил фильм.

Вычислить ближайших соседей

NearestNeighbors() в sklearn.neighbors библиотеке можно использовать для вычисления расстояния между фильмами с помощью косинусного сходства и поиска ближайших соседей для каждого фильма.

from sklearn.neighbors import NearestNeighborsknn = NearestNeighbors(metric='cosine', algorithm='brute')
knn.fit(df.values)
distances, indices = knn.kneighbors(df.values, n_neighbors=3)

Число ближайших соседей (n_neighbors) устанавливается равным 3. Поскольку это включает в себя сам фильм, обычно он находит два ближайших фильма, кроме самого фильма.

indices[Out] array([[0, 7, 5],
             [1, 3, 7],
             [2, 1, 6],
              ....
             [9, 0, 7]])

indices показывает индексы ближайших соседей для каждого фильма. Каждая строка соответствует строке в df. Первый элемент в строке — наиболее похожий (ближайший) фильм. Как правило, это сам фильм. Второй элемент является вторым ближайшим, а третий - третьим ближайшим. Например, в первой строке [0,7,5] ближайший к movie_0 фильм — это он сам, второй ближайший фильм — movie_7, а третий — movie_5.

distances[Out] array([[0.00000000e+00, 3.19586183e-01, 4.03404722e-01],        [4.44089210e-16, 3.68421053e-01, 3.95436458e-01],        [0.00000000e+00, 5.20766162e-01, 5.24329288e-01],
 ....
[1.11022302e-16, 4.22649731e-01, 4.81455027e-01]])

distances показывает расстояние между фильмами. Меньшее число означает, что фильм ближе. Каждое число в этом массиве соответствует числу в массиве indices.

Пример. Предсказание рейтинга фильма пользователем

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

Для практики предскажите рейтинг для movie_0 по user_7. Сначала найдите ближайших соседей для movie_0, используя NearestNeighbors().

Наиболее похожими на movie_0 фильмами являются movie_7 и movie_5, а расстояние от movie_0 составляет 0,3196 и 0,4034 соответственно.

Формула для расчета прогнозируемого рейтинга выглядит следующим образом:

R(m, u) = {∑ ⱼ S(m, j)R(j, u)}/ ∑ ⱼ S(m, j)

  • R(m, u): оценка фильма m пользователем u
  • S(m, j): сходство между фильмом m и фильмом j
  • j ∈ J, где J — множество фильмов, похожих на фильм m

Эта формула просто подразумевает, что прогнозируемый рейтинг фильма m пользователем u представляет собой средневзвешенное значение рейтинги похожих фильмов пользователя u. Вес каждого рейтинга (S(m, k)/∑ ⱼ S(m, j)) становится больше, когда фильм m и фильм k ближе. Знаменатель этого члена делает сумму всех весов равной 1.

Давайте предскажем рейтинг для movie_0 на user_7, R(0,7):

R(0,7)=[S(0,5)∗R(5,7)+S(0,7)∗R(7,7)]/[S(0,5)+S(0,7)]

Поскольку расстояния между movie_0 и movie_5 и между movie_0 и movie_7 составляют 0,4034 и 0,3196, сходство равно

  • S(0,5) = (1–0.4034)
  • S(0,7) = (1–0.3196).

Поскольку R(5,7) = 2 и R(7,7) = 3, предсказанное R(0,7) равно 2,5328. .