PyCon 2018: Системы рекомендаций SVD на практике в Python

задняя часть Python внешний интерфейс алгоритм продукт PyCon

введение

Вслед за поисковыми системами рекомендательные системы изменили способ взаимодействия пользователей с веб-сайтами и имеют важные приложения для повышения вовлеченности пользователей и разнообразия рекомендуемых продуктов. 35% прибыли Amazon поступает от его системы рекомендаций, а 75% пользователей Netflix выбирают фильмы на основе системы рекомендаций.

Система рекомендаций — очень большая тема.В этой статье представлен широко используемый алгоритм совместной фильтрации на основе моделей — SVD (Singular Value Decomposition), который используется в python.

Предположим, мы используем m пользователей, n элементов, и оценки каждого пользователя для каждого элемента могут формировать двумерную матрицу m*n. Конечно, в этой матрице будет много неизвестных значений, может быть, пользователь не использовал продукт, или пользователь не оценил его после использования. Как показано ниже

Пустое место на рисунке — это неизвестное значение. Далее нам нужно предсказать неизвестное значение на основе известного значения в этой неполной двумерной матрице, то есть предсказать рейтинг каждого пользователя по каждому элементу.

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

Далее, это проблема того, как предсказать неизвестные значения через известные значения, Здесь мы используем разложение матрицы, как показано на рисунке

Средняя матрица может быть разделена на произведение двух матриц слева и сверху.Это разложение по сингулярным числам.Матрицу всегда можно разделить на две матрицы для умножения.Принцип SVD можно увидетьэтот блог, принцип метода SVD, применяемый в рекомендательной системе, может относиться кэтот блог, Ниже мы в основном говорим о том, как использовать его в python.

Инициализировать и построить модель

Сначала вам нужно установить библиотеку сюрпризов, используя следующую команду

pip install scikit-surprise

Предположим, теперь у нас есть такие данные (примечание:load_movielensФункция не встроена в библиотеку, нужно взять файл данных и определить самостоятельно, подробности смотрите в исходниках автора по ссылке в конце статьи)

movielens_df: pd.DataFrame = load_movielens()
movielens_df.head(5)

        user_id	    movie_title	            rating
36649	User 742	Jerry Maguire (1996)	4
2478	User 908	Usual Suspects, The (1995)	3
82838	User 758	Real Genius (1985)	4
69729	User 393	Things to Do in Denver when You're Dead (1995)	3
36560	User 66	    Jerry Maguire (1996)	4

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

from surprise import SVD
from surprise import Dataset, Reader
from surprise.model_selection import cross_validate, train_test_split

Вот началось формальное моделирование

первый шаг: инициализацияreader, указав шкалу оценки от 1 до 5

reader = Reader(rating_scale=(1, 5))

второй шаг: Инициализировать данные, входящие данные могут иметь только 3 столбца, которые должны быть в следующем порядке [user_id, product_id, rating]

data = Dataset.load_from_df(movielens_df, reader)

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

третий шаг: Разделить обучающий набор и тестовый набор, 75% образцов используются в качестве обучающего набора, 25% образцов используются в качестве тестового набора.

trainset, testset = train_test_split(data, test_size=.25)

здесьtrainsetТипsurprise.dataset.TrainsetТип, мы можем просмотреть основную информацию о данных

trainset.n_users # 943
trainset.n_items # 596

Это означает, что в выборке, которую мы хотим использовать для обучения, всего 943 пользователя и 596 элементов.

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

model = SVD(n_factors=100)
model.fit(trainset)

Здесь необходимо пояснить, что 100 неявных признаков означают, что исходная матрица 943*596 будет разделена на два произведения матриц 943*100 и 100*596,n_factorsЗначение можно указать произвольно, если оно не превышает 596, но установка разных значений будет соответствовать разным моделям, и вам нужно выбрать значение, которое улучшит результаты.

Мы также можем посмотреть на две матрицы, разделенные

model.pu.shape # (943, 100)
model.qi.shape # (596, 100)

Рекомендации по результатам моделирования

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

Укажите пользователя и название фильма

a_user = "User 196"
a_product = "Toy Story (1995)"
model.predict(a_user, a_product)

# Prediction(uid='User 196', iid='Toy Story (1995)', r_ui=None, est=3.93380711688207, details={'was_impossible': False})

корреляция между фильмами

Здесь нам нужно написатьget_vector_by_movie_titleиcosine_distanceФункция (подробнее см. исходный код автора по ссылке в конце статьи)

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

toy_story_vec = get_vector_by_movie_title('Toy Story (1995)', model)
wizard_of_oz_vec = get_vector_by_movie_title('Wizard of Oz, The (1939)', model)

similarity_score = cosine_distance(toy_story_vec, wizard_of_oz_vec)
similarity_score
# 0.9461284008856982

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

Найдите фильмы, которые больше всего похожи на фильм

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

get_top_similarities('Star Wars (1977)', model)

	vector cosine distance	movie title
0	0.000000	            Star Wars (1977)
1	0.262668	            Empire Strikes Back, The (1980)
2	0.295667	            Return of the Jedi (1983)
3	0.435423	            Raiders of the Lost Ark (1981)

использованная литература

1.Видео Даниэль Пиратон — Практическое руководство по декомпозиции сингулярных значений в Python — PyCon 2018

2.неожиданная справочная документация

3.Код соответствия видео