Создайте свой собственный рекомендатель фильмов за считанные минуты с помощью Python и SentenceBERT.

Просматривая Netflix или Prime Video, вы, должно быть, натолкнулись на раздел, который предлагает вам фильмы и телешоу на основе вашей истории просмотров или тенденций в вашем местоположении в данный момент. Вы когда-нибудь задумывались, как это делается? Использование механизма рекомендаций фильмов.

В этом посте я покажу вам, как создать свой собственный рекомендатель фильмов с нуля. Будет немного теории, которая поможет вам понять, что делается, и много практической работы. Итак, приступим!

Как правило, рекомендательные фильмы относятся к одному из следующих типов:

  1. На основе рекомендаций - простая система, основанная на самых популярных видео в регионе пользователя. Да, вы уже догадались - самая популярная страница YouTube.
  2. На основе контента - находит похожие фильмы на основе таких показателей, как сюжет фильма, жанр, актеры, язык и т. Д.
  3. Совместная фильтрация - на основе истории / шаблона просмотра пользователя. Например, Netflix использует комбинацию контентной и совместной фильтрации.

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

Набор данных

Мы будем использовать Набор данных фильмов на Kaggle. Нет необходимости загружать весь набор данных; просто скачайте файл movies_metadata.csv. Этот файл содержит информацию о более чем 45 тысячах фильмов, включая название фильма, рейтинг, жанр, обзор, актеров и многое другое. Загружаем файл с помощью следующего кода:

import pandas as pd
movies = pd.read_csv("movies_metadata.csv", usecols = [5,9,20])
movies_head()

Прежде чем приступить к созданию рекомендателя, давайте немного очистим набор данных. Некоторые фильмы не имеют обзора (рис. 2). Мы также нумеруем фильмы в наборе данных, присваивая им индексы. Цикл for в приведенном ниже коде в основном присваивает номер (от 0 до количества фильмов) каждому фильму в наборе данных. Мы также определим две вспомогательные функции для получения имени фильма и связанного с ним индекса в наборе данных. Эти функции будут использоваться позже рекомендателем при предложении фильмов.

def get_title(index):
    return movies[movies.index == index]["title"].values[0]
def get_index(title):
    return movies[movies.title == title]["index"].values[0]
movies['index'] = [i for i in range(0, len(movies))]
movies = movies.dropna()

Система рекомендаций

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

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

Хорошо, теперь вернемся к кодированию! Теперь загружаем модель SentenceBERT. Параметр внутри SentenceTransformer () - это имя предварительно обученной модели. Полный список предварительно обученных моделей можно найти здесь.

Примечание. Процесс загрузки и установки может занять некоторое время.

!pip install sentence-transformers
from sentence_transformers import SentenceTransformer
bert = SentenceTransformer('bert-base-nli-mean-tokens')

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

sentence_embeddings = bert.encode(movies['overview'].tolist())

Теперь, когда у нас есть векторы, нам нужно вычислить сходство между ними. Как мы это делаем? Просто, используя косинусное подобие. Используя косинусное сходство, мы можем получить оценку сходства между двумя векторами. Оценка 0 указывает на отсутствие сходства, а оценка 1 указывает на полное сходство. Используя приведенный ниже код, мы вычисляем оценку сходства между каждым фильмом в нашем наборе данных.

similarity = cosine_similarity(sentence_embeddings)

Переменная подобия - это двумерный массив. Каждая строка соответствует фильму и содержит сходство этого фильма со всеми другими фильмами в наборе данных.

Вуаля, вот и все. Поздравляем, ваш рекомендатель готов! Давайте проверим это в действии.

notOver = True
while(notOver):
    user_movie = input("Enter the movie for which you want recommendations: ")
# Generate Recommendations
    recommendations = sorted(list(enumerate(similarity[get_index(user_movie)])), key = lambda x:x[1], reverse = True)
    print("The top 3 recommendations for" + " " + user_movie + " " + "are: ")
    print(get_title(recommendations[1][0]), get_title(recommendations[2][0]), get_title(recommendations[3][0]), sep = "\n")
    decision = input("Press 1 to enter another movie, 0 to exit")
    if(int(decision) == 0):
        print("Bye")
        notOver = False

Приведенный выше код находит в наборе данных 3 фильма, наиболее похожих на введенный нами фильм.

Примечание. Введенный вами фильм должен присутствовать в наборе данных. Посмотрим, какие рекомендации мы получим по «Истории игрушек».

Рекомендации для нашей модели выглядят вполне достойно! И «Свечи», и «Белоснежка» - фильмы для детей. Предложение секунд - это комедия, что и есть история игрушек (ну, частично). Попробуйте другие фильмы, и вы будете удивлены, увидев, насколько хорошо рекомендует эта модель!

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

Спасибо, что прочитали этот пост, и не стесняйтесь использовать код из моего Блокнота Jupyter, если вам нужна помощь. Ваше здоровье!