Полное руководство по созданию системы рекомендаций фильмов с использованием Python, Streamlit и Microsoft Azure

Создайте и разместите свою первую систему рекомендаций фильмов в облаке

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

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

В этом руководстве мы рассмотрим процесс создания системы рекомендаций фильмов на основе контента с использованием Python и библиотеки scikit-learn с открытым исходным кодом. Мы будем использовать Streamlit для создания простого веб-приложения для взаимодействия с нашей системой рекомендаций и, наконец, мы развернем наше приложение с помощью Azure.

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

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

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

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

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

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

Весь код и другие ресурсы, использованные для создания системы рекомендаций, доступны в моем репозитории GitHub. Смело смотрите здесь.

Шаг 1. Сбор данных для обучения

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

Google colab — ​​это бесплатная браузерная среда для совместной работы, которая предлагает интерактивную и простую в использовании платформу для написания и выполнения программ на Python. Мы будем использовать его для очистки нашего набора данных и обучения модели рекомендаций.

# Import python libraries
import numpy  as np
import pandas as pd

# Load dataset to pandas dataframe
df = pd.read_csv("tmdb_movies_data.csv")

Чтобы загрузить набор данных, вам необходимо зарегистрировать учетную запись на Kaggle и согласиться с их условиями использования. После этого загрузите набор данных в виде zip-файла. Теперь распакуйте zip-файл и прочитайте набор данных в свой блокнот Colab.

Шаг 2. Предварительная обработка и очистка данных

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

# Select the key columns that'll be used while building the model
movies = df[['id','cast','director','genres','overview','original_title','keywords']]

# Drop any null values from the database
movies.isnull().sum()
movies.dropna(inplace = True)

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

# Function to transform the data to a standard format
def convert(obj):
    s = list(obj)
    for i in range(len(s)):
      if s[i] == '|':
        s[i] = " "

    temp_str = "".join(s)
    temp_list = temp_str.split()

    return temp_list

# Apply the convert function to all the columns
movies['genres'] = movies['genres'].apply(convert)
movies['keywords'] = movies['keywords'].apply(convert)
movies['overview'] = movies['overview'].apply(lambda x:x.split())
movies['cast'] = movies['cast'].apply(convert)
movies['director'] = movies['director'].apply(convert)

# Stem the data to reduce words to their base form
import nltk
from nltk.stem.porter import PorterStemmer
ps = PorterStemmer()

def stem(text):
    y = []
    for i in text.split():
        y.append(ps.stem(i))

    return " ".join(y)

Шаг 3. Создайте модель рекомендации

После того, как мы отфильтровали данные, нам нужно будет преобразовать каждый фильм в вектор. Этот процесс называется векторизацией текста, а подход, который мы здесь будем использовать, называется подходом мешок слов. Также существует множество других методов векторизации текста, таких как TF/IDF и Word2Vec.

# Create a new column that combines all charecteristics of the movie
movies['tags'] = movies['cast'] + movies['genres'] + movies['director'] + movies['overview'] + movies['keywords']

# Create a new dataframe consisting of id, original title, and tags
new_df = movies[['id','original_title','tags']]
new_df['tags'] = new_df['tags'].apply(lambda x:" ".join(x))

# Apply the stem function to the tags column of your dataframe
new_df['tags'] = new_df['tags'].apply(stem)

Затем подгоните модель к набору данных после удаления стоп-слов. Стоп-слова — это небольшие общеупотребительные слова, которые используются в тексте, но несут очень мало смысла.

# Perform text vectorization after disregarding stop words
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_features=10000,stop_words='english')

# Transform the SciPy sparse matrix to NumPy array form
vectors = cv.fit_transform(new_df['tags']).toarray()

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

# Calculate the cosine similarity between the vectors
from sklearn.metrics.pairwise import cosine_similarity

similarity = cosine_similarity(vectors)

После обработки результатов создайте дамп рассола, чтобы сохранить объекты Python для последующего использования при создании приложения. Это делается с помощью пакета python pickle.

# Take the pickle dump of the results for later use
import pickle

pickle.dump(new_df,open('movies.pkl','wb'))
pickle.dump(new_df.to_dict(),open('movie_dict.pkl','wb'))
pickle.dump(similarity,open('similarity.pkl','wb'))

Шаг 4. Разработка внешнего интерфейса

Для разработки внешнего интерфейса нашей системы мы будем использовать Streamlit — мощную библиотеку с открытым исходным кодом, позволяющую создавать интерактивные веб-приложения. Мы также будем использовать встроенные виджеты и функции для создания интерфейса.

Для начала установите streamlit в своей среде и создайте файл с именем app.py. Этот файл будет содержать код для разработки интерфейса веб-приложения и рекомендации фильмов. Это делается путем вычисления косинусного сходства между фильмами и вывода пяти ближайших векторов.

# Fetch the neccesary python modules
import streamlit as st
import pickle
import pandas as pd
import requests

# Recommend movies based on content
def recommend(movie):
    movie_index = movies[movies['original_title'] == movie].index[0]
    distances = similarity[movie_index]
    movies_list = sorted(list(enumerate(distances)), reverse=True, key=lambda x: x[1])[1:6]

    recommended_movies = []
    recommended_movies_poster = []

    # Fetch the posters for each recommended movie
    for  i in movies_list:
        movie_id = movies.iloc[i[0]].id
        recommended_movies.append(movies.iloc[i[0]].original_title)
        recommended_movies_poster.append(fetch_poster(movie_id))

    return recommended_movies,recommended_movies_poster

# Load the necessary python pickle files
movies_dict = pickle.load(open('pickle/movie_dict.pkl','rb'))
movies = pd.DataFrame(movies_dict)

similarity = pickle.load(open('pickle/similarity.pkl','rb'))

Далее мы будем получать постеры этих фильмов с помощью TMDb API. Вы можете создать свой собственный API, войдя на сайт TMDb Developers API-3. Не забудьте заменить ключ API (в строке 3 ниже) своим собственным ключом.

# Fetch posters from the TMDb database
def fetch_poster(movie_id):
    response = requests.get('https://api.themoviedb.org/3/movie/{}?api_key=ENTER_API_KEY_HERE&language=en-US'.format(movie_id))
    data = response.json()
    return "https://image.tmdb.org/t/p/w500/" + data['poster_path']

# Web app's hero section - Display Title, Dropdown
st.title("Movie Recommender System")

selected_movie_name = st.selectbox(
'Select a movie to recommend',
movies['original_title'].values)

# Output recommendations with posters
if st.button('Recommend'):
    name, posters = recommend(selected_movie_name)
 
    col1, col2, col3, col4,  col5 = st.columns(5)
    with col1:
        st.text(name[0])
        st.image(posters[0])
    with col2:
        st.text(name[1])
        st.image(posters[1])
    with col3:
        st.text(name[2])
        st.image(posters[2])
    with col4:
        st.text(name[3])
        st.image(posters[3])
    with col5:
        st.text(name[4])
        st.image(posters[4])

Как только наш внешний интерфейс будет готов, мы можем запустить приложение локально, открыв терминал и введя команду: «streamlit run app.py». Эта команда может занять до 30 секунд, прежде чем откроется приложение Streamlit на локальном хосте: 8501.

Шаг 5. Разверните веб-приложение в Azure

Теперь, когда наша система рекомендаций готова к работе, пришло время поделиться ею со всем миром. Для этого мы будем использовать Microsoft Azure. Если у вас еще нет учетной записи Microsoft Azure, вы можете подписаться на бесплатную пробную версию здесь.

Теперь загрузите свои файлы в репозиторий GitHub. Когда ваш репозиторий будет готов, перейдите на панель инструментов Azure, перейдите к службам приложений и выберите вариант создания.

В окне создания ресурса введите уникальное имя для вашего приложения, выберите стек среды выполнения как «Python 3.7» и установите в поле региона любой регион, ближайший к вам. Затем измените тарифный план, щелкнув размер изменения и выбрав уровень B1 в SpecPicker. Оставьте для других полей значения по умолчанию.

Нажмите «Далее» и перейдите в раздел развертываний. Включите параметр непрерывного развертывания в настройках действий GitHub. Подключите свою учетную запись к Azure, выберите свое имя пользователя GitHub в качестве имени организации и выберите созданный вами репозиторий. В поле ветки выберите основную ветку.

Вам не нужно вносить какие-либо изменения в сеть и мониторинг, поэтому просто нажмите «Проверить + Создать». Просмотрев внесенные вами изменения, нажмите кнопку «Создать» и дождитесь завершения развертывания. Тем временем вы заметите, что в нашем репозитории начинает выполняться новый рабочий процесс GitHub.

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

python -m streamlit run app.py — server.port 8000 — server.address 0.0.0.0

Обратите внимание, что файлы pickle, используемые при разработке системы рекомендаций, превышают ограничение размера файла GitHub. Чтобы загрузить их, вам нужно будет использовать Git LFS.

Каждый пользователь получает до 1 ГБ бесплатного хранилища и полосы пропускания. Если вы превысите этот предел, вам нужно будет приобрести дополнительную квоту, иначе ваше веб-приложение не сможет получить файлы рассола, и веб-приложение покажет ошибку.

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

Заключение и заключительные мысли

Если вам удалось достичь этого, поздравляем вас с созданием вашей самой первой системы рекомендаций и размещением ее в Azure.

Вы можете дополнительно оптимизировать производительность своей системы рекомендаций, точно настроив ее параметры или переключившись на более динамичные алгоритмы. Вы также можете развернуть свое приложение на Python после контейнеризации приложения с помощью реестра контейнеров Docker и Azure, но это урок для другого дня.

На этом мы подошли к концу этой статьи. Если у вас есть какие-либо вопросы или вы считаете, что я допустил какую-либо ошибку, пожалуйста, не стесняйтесь обращаться ко мне! Вы можете связаться со мной через Email или LinkedIn. А пока удачного обучения.

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Присоединяйтесь к нашему сообществу Discord и следите за нами в Twitter, LinkedIn и YouTube.

Узнайте, как привлечь внимание к своему стартапу с помощью Circuit.