Как реализовать систему рекомендаций на сайте просмотра кино

5939f3e972e5dc27b3e6be9c4f89e811.jpg

Привет, Хабр!

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

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

Сбор и предобработка данных

Несколько типов источников данных:

  1. Информация о пользователях и их действиях:

    • Журналы активности пользователей (логи) на вашем сайте или платформе.

    • Данные о профилях пользователей, включая предпочтения и интересы.

Пример кода для сбора данных о пользовательских действиях:

# Пример с использованием Python и библиотеки для работы с логами
import pandas as pd

# Загрузка журнала активности пользователей
user_activity_log = pd.read_csv('user_activity.log')
  1. Информация о контенте:

    • Каталог фильмов, сериалов или товаров.

    • Описание контента, ключевые слова, жанры.

Пример кода для загрузки данных о фильмах:

# Пример загрузки данных о фильмах из базы данных
import sqlite3

conn = sqlite3.connect('movies.db')
query = "SELECT * FROM movies"
movies_data = pd.read_sql_query(query, conn)

Процесс сбора и хранения данных

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

Пример кода для загрузки данных с использованием API:

# Пример запроса данных с использованием API
import requests

api_url = "https://api.example.com/data"
response = requests.get(api_url)

if response.status_code == 200:
    data = response.json()
    # Обработка данных
else:
    print("Ошибка при запросе данных.")

Хранение данных часто выполняется с использованием реляционных баз данных, NoSQL хранилищ или облачных решений, таких как Amazon S3.

Пример кода для хранения данных в SQLite базе данных:

# Пример создания SQLite базы данных и сохранения данных
import sqlite3

conn = sqlite3.connect('recommendation_data.db')
data.to_sql('user_activity', conn, if_exists='replace')

Методы предобработки данных для анализа

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

  1. Устранение пропусков и дубликатов: Пропущенные значения могут исказить анализ, поэтому их нужно заполнить или удалить. Также следует удалить дубликаты.

Пример кода для удаления дубликатов:

data = data.drop_duplicates()
  1. Шкалирование и нормализация данных: Нормализация данных важна для сравнения разных признаков и избегания искажений.

Пример кода для нормализации данных:

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
data['rating'] = scaler.fit_transform(data['rating'].values.reshape(-1, 1))
  1. Извлечение признаков: Выделение ключевых признаков из данных, таких как жанры фильмов или история взаимодействий пользователя.

Пример кода для извлечения признаков из текста:

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(data['description'])

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

Методы аналитики данных

Анализ пользовательского поведения может предоставить ценные инсайты для построения рекомендательных систем. Три примера использования статистического анализа:

  1. Анализ распределения рейтингов:

import numpy as np
import matplotlib.pyplot as plt

# Создаем случайный датасет рейтингов фильмов
ratings = np.random.randint(1, 6, 1000)

# Строим гистограмму распределения
plt.hist(ratings, bins=5, alpha=0.75, rwidth=0.85, color='b')
plt.xlabel('Рейтинг')
plt.ylabel('Количество оценок')
plt.title('Распределение рейтингов пользователей')
plt.show()

d061eb9229418729ff819db369340f99.png

  1. Корреляционный анализ:

import pandas as pd

# Создаем датасет с рейтингами двух пользователей для фильмов
data = {
    'Пользователь A': [4, 3, 5, 2, 1],
    'Пользователь B': [5, 4, 4, 1, 2]
}
df = pd.DataFrame(data)

# Вычисляем корреляцию между оценками пользователей
correlation_matrix = df.corr()

print(correlation_matrix)

Результат:

                Пользователь A  Пользователь B
Пользователь A          1.0000          0.7698
Пользователь B          0.7698          1.0000
  1. Анализ времени сеансов просмотра:

import pandas as pd

# Создаем датасет с временем начала сеансов просмотра фильмов
data = {
    'Время начала': ['2023-09-13 18:30:00', '2023-09-13 19:45:00', '2023-09-14 14:15:00'],
    'Пользователь': ['Пользователь A', 'Пользователь B', 'Пользователь A']
}
df = pd.DataFrame(data)

# Преобразуем столбец времени в формат datetime
df['Время начала'] = pd.to_datetime(df['Время начала'])

# Группируем данные по пользователям и анализируем среднее время между сеансами
user_sessions = df.groupby('Пользователь')['Время начала'].diff().mean()

print(user_sessions)

Результат:

0 days 19:45:00

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

Кластеризация помогает группировать пользователей с похожими интересами. Вот три примера использования методов кластеризации:

  1. Кластеризация на основе оценок:

import numpy as np
from sklearn.cluster import KMeans

# Создаем случайный датасет оценок фильмов
ratings = np.random.randint(1, 6, (100, 5))

# Применяем метод K-средних для кластеризации пользователей
kmeans = KMeans(n_clusters=3)
kmeans.fit(ratings)

# Выводим центры кластеров
print(kmeans.cluster_centers_)

Результат:

[[2.65217391 3.13043478 4.43478261 2.65217391 4.43478261]
 [4.26829268 2.70731707 3.26829268 3.34146341 2.07317073]
 [2.02777778 3.41666667 1.72222222 3.08333333 3.16666667]]
  1. Кластеризация на основе жанров фильмов:

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans

# Создаем датасет с жанрами фильмов
data = {
    'Фильм': ['Фильм 1', 'Фильм 2', 'Фильм 3'],
    'Жанры': ['комедия', 'боевик', 'драма']
}
df = pd.DataFrame(data)

# Преобразуем жанры в числовые признаки с помощью TF-IDF
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(df['Жанры'])

# Применяем метод K-средних для кластеризации фильмов по жанрам
kmeans = KMeans(n_clusters=2)
kmeans.fit(tfidf_matrix.toarray())

# Выводим принадлежность фильмов к кластерам
print(kmeans.labels_)

Результат:

[1 0 0]
  1. Кластеризация на основе истории оценок:

import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# Создаем датасет с историей оценок пользователей
data = {
    'Пользователь': ['Пользователь A', 'Пользователь B', 'Пользователь C'],
    'Фильм 1': [4, 2, 5],
    'Фильм 2': [3, 4, 1],
    'Фильм 3': [5, 2, 3]
}
df = pd.DataFrame(data)

# Масштабируем данные
scaler = StandardScaler()
scaled_data = scaler.fit_transform(df.iloc[:, 1:])

# Применяем метод K-средних для кластеризации пользователей
kmeans = KMeans(n_clusters=2)
kmeans.fit(scaled_data)

# Выводим принадлежность пользователей к кластерам
print(kmeans.labels_)

Анализ временных рядов и трендов в предпочтениях пользователей

Анализ временных рядов помогает выявить изменения в пользовательских предпочтениях.

Анализ временных рядов и трендов в предпочтениях пользователей

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

  1. Создание временного ряда для оценок фильмов:

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

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Создаем искусственный временной ряд оценок фильмов
date_rng = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
user_ratings = np.random.randint(1, 6, size=(len(date_rng)))

# Создаем DataFrame
df = pd.DataFrame({'Date': date_rng, 'User_Rating': user_ratings})
df.set_index('Date', inplace=True)

# Визуализируем временной ряд
plt.figure(figsize=(12, 6))
plt.plot(df.index, df['User_Rating'], marker='o')
plt.title('Временной ряд оценок фильмов')
plt.xlabel('Дата')
plt.ylabel('Оценка пользователя')
plt.grid(True)
plt.show()

d3edb7b88c298c1f0cfd54c0dd6f4b04.png

  1. Выявление сезонных паттернов в предпочтениях пользователей:

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

# Сглаживание скользящим средним для выявления сезонных паттернов
window_size = 7  # размер окна
df['Smoothed_Rating'] = df['User_Rating'].rolling(window=window_size).mean()

# Визуализируем сглаженный временной ряд
plt.figure(figsize=(12, 6))
plt.plot(df.index, df['Smoothed_Rating'], label=f'Smoothed (Window Size={window_size})', color='red')
plt.title('Сглаженный временной ряд оценок фильмов')
plt.xlabel('Дата')
plt.ylabel('Сглаженная оценка')
plt.grid(True)
plt.legend()
plt.show()

7c34248d37c90f84fcd491ae61254b86.png

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

Машинное обучение в системах рекомендаций

Коллаборативная фильтрация и контентная фильтрация представляют собой два ключевых подхода к построению систем рекомендаций.

  1. Коллаборативная фильтрация основана на идее, что пользователи, которые проявили похожие предпочтения в прошлом, будут иметь схожие предпочтения в будущем. Этот метод основан на анализе взаимодействий пользователей с контентом, таким как оценки, отзывы или история просмотров. Давайте рассмотрим пример реализации коллаборативной фильтрации с использованием библиотеки Python surprise:

from surprise import Dataset, Reader
from surprise import KNNBasic
from surprise.model_selection import cross_validate

# Создаем датасет
reader = Reader(rating_scale=(1, 5))
data = Dataset.load_from_df(df[['user_id', 'movie_id', 'rating']], reader)

# Используем алгоритм коллаборативной фильтрации
sim_options = {'name': 'cosine', 'user_based': False}
algo = KNNBasic(sim_options=sim_options)

# Оцениваем модель с помощью кросс-валидации
cross_validate(algo, data, measures=['RMSE', 'MAE'], cv=5, verbose=True)
  1. Контентная фильтрация основана на анализе характеристик контента, таких как жанр, актеры, режиссеры и другие метаданные. Примером может служить рекомендация фильмов на основе жанра:

def content_based_recommendations(user_profile, movies, top_n=10):
    # Вычисляем схожесть между профилем пользователя и фильмами
    similarities = cosine_similarity(user_profile, movies)
    
    # Получаем топ N рекомендаций
    top_indices = similarities.argsort()[-top_n:][::-1]
    recommended_movies = [movies[i] for i in top_indices]
    return recommended_movies

Разработка рекомендательных моделей, таких как матричные разложения и нейронные сети

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

  1. Матричные разложения — это метод, который разбивает данные о взаимодействии пользователей с контентом на две матрицы: пользователи-факторы и факторы-контент. Одним из популярных алгоритмов для матричных разложений является Alternating Least Squares (ALS):

from pyspark.ml.recommendation import ALS
from pyspark.ml.evaluation import RegressionEvaluator

# Инициализация модели ALS
als = ALS(maxIter=5, regParam=0.01, userCol="user_id", itemCol="movie_id", ratingCol="rating")

# Обучение модели
model = als.fit(train_data)

# Предсказание рейтингов для тестовых данных
predictions = model.transform(test_data)

# Оценка качества модели
evaluator = RegressionEvaluator(metricName="rmse", labelCol="rating", predictionCol="prediction")
rmse = evaluator.evaluate(predictions)
  1. Нейронные сети стали все более популярными в системах рекомендаций благодаря своей способности извлекать сложные зависимости между пользователями и контентом. Пример простой рекомендательной нейронной сети:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, Flatten, Dense

# Создание модели
model = Sequential()
model.add(Embedding(input_dim=num_users, output_dim=50, input_length=1))
model.add(Flatten())
model.add(Dense(1, activation='linear'))

# Компиляция модели
model.compile(optimizer='adam', loss='mean_squared_error')

# Обучение модели
model.fit([user_ids, movie_ids], ratings, epochs=5, batch_size=64)

Оценка и улучшение качества рекомендаций с использованием машинного обучения

Оценка качества рекомендаций играет важную роль в разработке систем. Один из распространенных методов — использование метрик, таких как RMSE (среднеквадратичная ошибка) или MAE (средняя абсолютная ошибка), чтобы измерить точность моделей. После оценки моделей, можно приступить к их улучшению, используя техники, такие как оптимизация гиперпараметров и обогащение данных.

Пример использования метрик и оптимизации гиперпараметров:

from surprise import accuracy
from surprise.model_selection import GridSearchCV

# Создание сетки гиперпараметров
param_grid = {'n_epochs': [5, 10, 15], 'lr_all': [0.002, 0.005, 0.01], 'reg_all': [0.4, 0.6, 0.8]}

# Подбор лучших гиперпараметров
gs = GridSearchCV(SVD, param_grid, measures=['rmse', 'mae'], cv=3)
gs.fit(data)

# Получение лучших параметров и оценка качества
best_params = gs.best_params['rmse']
best_rmse = gs.best_score['rmse']

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

Персонализация рекомендаций

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

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

# Создание профиля пользователя на основе истории просмотров и оценок
def user_profile(user_id, user_history):
    user_profile = {}
    for movie_id, rating in user_history:
        user_profile[movie_id] = rating
    return user_profile

# Генерация персонализированных рекомендаций для пользователя
def personalized_recommendations(user_id, user_history, all_movies):
    user_profile_data = user_profile(user_id, user_history)
    recommended_movies = []

    for movie_id in all_movies:
        if movie_id not in user_profile_data:
            recommended_movies.append(movie_id)
    
    recommended_movies.sort(key=lambda movie_id: user_profile_data.get(movie_id, 0), reverse=True)
    return recommended_movies

Применение алгоритмов ранжирования для учета индивидуальных предпочтений

Для учета индивидуальных предпочтений пользователей можно использовать алгоритмы ранжирования, которые учитывают более сложные зависимости между контентом и пользователями. Один из таких алгоритмов — популярный «RankNet» из библиотеки TensorFlow:

from tensorflow import keras
from tensorflow.keras import layers

# Создание модели RankNet
def create_ranknet_model(input_dim):
    model = keras.Sequential()
    model.add(layers.Dense(64, activation='relu', input_dim=input_dim))
    model.add(layers.Dense(32, activation='relu'))
    model.add(layers.Dense(1, activation='linear'))
    return model

# Обучение модели RankNet
def train_ranknet_model(model, X, y, epochs=10):
    model.compile(loss='mse', optimizer='adam')
    model.fit(X, y, epochs=epochs, batch_size=32)

Стратегии обучения моделей с учетом обратной связи пользователей

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

Пример обновления модели на основе обратной связи:

# Обновление рекомендательной модели с учетом новой оценки пользователя
def update_recommendation_model(model, user_id, movie_id, new_rating):
    # Получение существующих оценок пользователя
    user_history = get_user_history(user_id)

    # Добавление новой оценки к истории пользователя
    user_history.append((movie_id, new_rating))

    # Пересчитывание профиля пользователя и персонализированных рекомендаций
    user_profile_data = user_profile(user_id, user_history)
    personalized_recommendations = personalized_recommendations(user_id, user_history, all_movies)

    # Обновление модели с новой информацией о пользователе
    model.update_with_user_data(user_id, user_profile_data, personalized_recommendations)

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

Оценка и тестирование системы

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

  1. RMSE (Root Mean Square Error): Эта метрика измеряет разницу между реальными и предсказанными значениями. Чем ближе RMSE к нулю, тем лучше.

from sklearn.metrics import mean_squared_error
import numpy as np

# Пример вычисления RMSE
actual_ratings = [4, 3, 5, 2, 1]
predicted_ratings = [3.8, 2.9, 4.9, 2.2, 1.2]
rmse = np.sqrt(mean_squared_error(actual_ratings, predicted_ratings))
  1. Precision и Recall: Эти метрики из области информационного поиска могут быть применены для оценки качества рекомендаций. Precision измеряет точность рекомендаций, а Recall — полноту.

# Пример вычисления Precision и Recall
relevant_items = [1, 2, 3, 4, 5]
recommended_items = [1, 3, 6, 7, 8]
precision = len(set(relevant_items) & set(recommended_items)) / len(recommended_items)
recall = len(set(relevant_items) & set(recommended_items)) / len(relevant_items)
  1. MAP (Mean Average Precision): Эта метрика используется для оценки качества рекомендаций, особенно в задачах, связанных с ранжированием.

# Пример вычисления MAP
def average_precision(relevant_items, recommended_items):
    # Рассчитываем Average Precision для одного пользователя
    precision_at_k = []
    for k in range(1, len(recommended_items) + 1):
        if recommended_items[k - 1] in relevant_items:
            precision_at_k.append(len(set(relevant_items) & set(recommended_items[:k])) / k)
    return sum(precision_at_k) / len(relevant_items)

# Среднее значение Average Precision для всех пользователей
average_precisions = [average_precision(user['relevant_items'], user['recommended_items']) for user in users]
map_score = sum(average_precisions) / len(users)

Эксперименты с пользователями и A/B-тестирование

Проведение экспериментов с пользователями и A/B-тестирование позволяют оценить реакцию пользователей на изменения в системе рекомендаций. Это важно для определения эффективности новых алгоритмов и функций.

Пример проведения A/B-тестирования:

import random

# Разделение пользователей на группы A и B
users = get_all_users()
group_a_users = random.sample(users, len(users) // 2)
group_b_users = list(set(users) - set(group_a_users))

# В группе A используется старая модель рекомендаций
# В группе B используется новая модель рекомендаций

# Сбор данных о поведении пользователей и анализ результатов

Регулярное обновление системы с учетом обратной связи

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

Пример обновления рекомендательной модели с учетом обратной связи:

def update_recommendation_model(model, user_id, movie_id, new_rating):
    # Получение существующих оценок пользователя
    user_history = get_user_history(user_id)

    # Добавление новой оценки к истории пользователя
    user_history.append((movie_id, new_rating))

    # Пересчитывание профиля пользователя и персонализированных рекомендаций
    user_profile_data = user_profile(user_id, user_history)
    personalized_recommendations = personalized_recommendations(user_id, user_history, all_movies)

    # Обновление модели с новой информацией о пользователе
    model.update_with_user_data(user_id, user_profile_data, personalized_recommendations)

Заключение

В заключение, разработка систем рекомендаций — это постоянное стремление к совершенству, которое удовлетворяет как потребности пользователей, так и амбиции разработчиков.

Напомню, что подробные практические знания по построению рекомендательных систем и анализу данных вы можете получить на курсах OTUS. В каталоге по ссылке вы найдете всю линейку курсов по аналитике. А в календаре сможете найти ссылки для регистрации на бесплатные мероприятия, которые проходят регулярно.

© Habrahabr.ru