0. Импорт библиотек
Подключение к облаку:
from google.colab import drive
drive.mount('/content/gdrive')
Импорт библиотек:
import pandas as pd
import numpy as np
from scipy.sparse import csr_matrix
from sklearn.neighbors import NearestNeighbors
1. Загрузка данных и первичная работа с ними
Загрузка таблиц с данными:
movies = pd.read_csv('/content/gdrive/MyDrive/recomend/movies.csv')
ratings = pd.read_csv('/content/gdrive/MyDrive/recomend/ratings.csv')
Создание pivot таблицы:
user_item_matrix = ratings.pivot(index = 'movieId', columns = 'userId', values = 'rating')
Заполнение пропусков (в этом случае нулями):
user_item_matrix.fillna(0, inplace = True)
Подсчёт количества оценок у каждого пользователя и каждого фильма соответственно:
users_votes = ratings.groupby('userId')['rating'].agg('count')
movies_votes = ratings.groupby('movieId')['rating'].agg('count')
Создание масок для заполненных элементов таблиц user и item соответственно:
user_mask = users_votes[users_votes > 50].index
movie_mask = movies_votes[movies_votes > 10].index
Создание маски для заполненных элементов таблицы user-item:
user_item_matrix = user_item_matrix.loc[movie_mask,:]
user_item_matrix = user_item_matrix.loc[:,user_mask]
Преобразование разреженной матрицы в формат csr:
csr_data = csr_matrix(user_item_matrix.values)
Сброс индекса для удобного поиска по фильму (минимальное значение movieId равно 1):
user_item_matrix = user_item_matrix.rename_axis(None, axis = 1).reset_index()
2. Обучение модели k-ближайших соседей:
knn = NearestNeighbors(metric='cosine', algorithm='brute', n_neighbors=15, n_jobs=-1)
knn.fit(csr_data)
3. Прогнозы
Определение id нужного фильма в таблице movies (через название фильма):
movie_search = movies[movies['title'].str.contains('Matrix')].iloc[0]['movieId']
Определение id этого же фильма в созданной матрице:
movie_id = user_item_matrix[user_item_matrix['movieId'] == movie_search].index[0]
Предикт обученной моделью:
distances, indices = knn.kneighbors(csr_data[movie_id], n_neighbors=11)
distances = list(distances)[0][1:]
indices = list(indices)[0][1:]
# в параметр n_neighbors нужно передавать число, на единицу большее того, сколько ближайших элементов мы хотим вывести, так как первым элементом всегда будет тот же фильм, ближайшие к которому мы хотим вывести
# distances содержит косинусные расстояния между элементами, indiceis - их индексы в созданной матрице