ВВЕДЕНИЕ

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

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

2. Профили пользователей меняются быстро, и необходимо пересчитывать всю модель системы, что требует больших затрат времени и вычислительных ресурсов.

Чтобы решить эти проблемы, мы будем использовать совместную фильтрацию ITEM-ITEM.

Совместная фильтрация ITEM-ITEM

Совместная фильтрация ITEM-ITEM ищет элементы, похожие на уже оцененные пользователем статьи, и рекомендует большинство похожих статей. Но что это означает, когда мы говорим о сходстве предмета-предмета? В этом случае мы не имеем в виду, совпадают ли два элемента по атрибуту, например, перьевая ручка и пилотная ручка, потому что оба являются пером. Напротив, сходство означает то, как люди относятся к двум предметам одинаково с точки зрения симпатии и антипатии.

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

Чтобы вычислить сходство между двумя элементами, мы изучаем набор элементов, которые оценил целевой пользователь, и вычисляем, насколько они похожи на целевой элемент i, а затем выбираем k наиболее похожих элементов. Сходство между двумя элементами рассчитывается путем оценки пользователей, которые оценили оба элемента, а затем с использованием функции косинусного сходства, упомянутой ниже:

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

Начнем с кодирования.

Представленный ниже код может быть не очень легко читать, поэтому перейдите в мой репозиторий GitHub, чтобы получить доступ ко всем кодам рекомендательных систем этой серии.

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

импортировать панды как pd
импортировать numpy как np
импортировать математику

Рейтинги = pd.read_csv («C: \ Users \ Ankur.Tomar \ Desktop \ Courses \ Recommender \ Item-Item \ ii-assignment \ data \\ rating.csv»)
Movies = pd.read_csv («C : \ Users \ Ankur.Tomar \ Desktop \ Courses \ Recommender \ Item-Item \ ii-assignment \ data \\ movies.csv »)
Tags = pd.read_csv (« C: \ Users \ Ankur.Tomar \ Рабочий стол \ Courses \ Recommender \ Item-Item \ ii-assignment \ data \\ tags.csv »)

Вычисление среднего рейтинга и вычитание из каждого рейтинга пользователя для расчета скорректированного рейтинга.

Mean = Ratings.groupby (['movieId'], as_index = False, sort = False) .mean (). Rename (columns = {'rating': 'rating_mean'}) [['movieId', 'rating_mean']]
Рейтинги = pd.merge (Рейтинги, Среднее, on = 'movieId', how = 'left', sort = False)
Рейтинги ['rating_adjusted'] = Рейтинги ['rating'] - Рейтинги [ 'rating_mean']

Вычисление значения сходства для каждого фильма, который пользователь не оценил, с фильмами, которые он оценил, и выбор 20 наиболее похожих фильмов. Обратите внимание, что в целях тестирования я рассчитал значения подобия только для одного пользователя. Добавьте еще один цикл, чтобы рассчитать его для всех пользователей.

movie_data_all_append = pd.DataFrame ()

user_data = Рейтинги [Рейтинги ['userId']! = 320]
independent_movies = np.unique (user_data ['movieId'])
i = 1
для фильма в отдельных_фильмах:

if i% 10 == 0:

print i, «out of», len (independent_movies)

movie_data_all = pd.DataFrame ()

movie_data = Рейтинги [Рейтинги ['movieId'] == фильм]
movie_data = movie_data [['userId', 'movieId', 'rating_adjusted']]. drop_duplicates ()
movie_data = movie_data.rename (columns = {'rating_adjusted': 'rating_adjusted1'})
movie_data = movie_data.rename (columns = {'movieId': 'movieId1'})
movie1_val = np.sqrt ( np.sum (np.square (movie_data ['rating_adjusted1']), axis = 0))

user_data1 = Ratings [Ratings ['userId'] == 320]
independent_movies1 = np .unique (user_data1 ['movieId'])



для фильма1 в отличном_movies1:

movie_data1 = Рейтинги [Рейтинги ['movieId'] = = movie1]
movie_data1 = movie_data1 [['userId', 'movieId', 'rating_adjusted']]. drop_duplicates ()
movie_data1 = movie_data1.rename (columns = {'rating_adjusted': 'rating_adjusted2'})
movie_data1 = movie_data1.rename (columns = {'movieId': 'movieId2'})
movie2_val = np.sqrt (np.sum (np.square (movie_data1 ['rating_adjusted2']), axis = 0))

movie_data_merge = pd.merge (movie_data, movie_data1 [['userId', 'movieId2', ' rating_adjusted2 ']], on =' userId ', how =' inner ', sort = False)

movie_data_merge [' vector_product '] = (movie_data_merge [' rating_adjusted1 '] * movie_data_merge [' rating_adjusted2 '] )

movie_data_merge = movie_data_merge.groupby ([‘movieId1’, ’movieId2 '], as_index = False, sort = False) .sum ()

movie_data_merge ['точка'] = movie_data_merge ['vector_product'] / (movie1_val * movie2_val)

movie_data_all = movie_data_all.append (movie_data_merge, ignore_index = True)


movie_data_all = movie_data_all [movie_data_all ['точка'] ‹1]
movie_data_all = movie_data_all.sort (['dot'], ascending = False)
movie_data_all = movie_data_all.head (20)

movie_data_all_append = movie_data_all_append.append (movie_data_all, ignore_index = True)
i = i + 1

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

movie_rating_all = pd.DataFrame ()

для фильма в различных_фильмах [313: 314]:
movie_nbr = movie_data_all_append [movie_data_all_append ['movieId1'] == movie]
movie_mean = Рейтинги [Рейтинги ['movieId'] == фильм]
mean = movie_mean [«рейтинг»]. mean ()
movie_nbr_dot = pd.merge (user_data1, movie_nbr [['точка', 'movieId2', 'movieId1']], how = 'inner', left_on = ' movieId ', right_on =' movieId2 ', sort = False)
movie_nbr_dot [' wt_rating '] = movie_nbr_dot [' dot '] * movie_nbr_dot [' rating_adjusted ']
movie_nbr_dot [' dot_abs '] = movie_nbr_dot [ 'точка']. abs ()
movie_nbr_dot = movie_nbr_dot.groupby (['movieId1'], as_index = False, sort = False) .sum () [['movieId1', 'wt_rating', 'dot_abs'] ]
movie_nbr_dot ['Рейтинг'] = (movie_nbr_dot ['wt_rating'] / movie_nbr_dot ['dot_abs']) + означает

movie_rating_all = movie_rating_all.append (movie_nbr_dot, ignore_index = True) < br />
movie_rating_all = movie_rating_all.sort (['Рейтинг'], ascending = False)

На этом мы закончили создание системы рекомендаций, основанной на сходстве элементов, которая преодолевает недостатки системы рекомендаций, основанной на пользователях.

Для более глубокого понимания, пожалуйста, пройдите специализированные курсы по системе рекомендаций Университета Миннесоты на Coursera.

Спасибо!