Совместная фильтрация на основе элементов — это система рекомендаций, использующая сходство между элементами с использованием оценок пользователей.
Фундаментальное предположение для этого метода заключается в том, что пользователь дает одинаковые оценки похожим фильмам. Рассмотрим следующую таблицу рейтингов фильмов.
В этом примере рейтинг 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_1
2, а оценка для 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. .