Привет, я Хадсон Эткин, учащийся средней школы из района Залива. В настоящее время я работаю над бесплатным веб-приложением для поиска фильмов под названием Trailerly (www.trailer.ly, посмотрите 🙏). Мы показываем трейлеры фильмов в ленте в стиле TikTok с алгоритмом, который подстраивается под ваши вкусы. Я сделал это для таких людей, как я, которые так долго ищут фильм, что в итоге вообще ничего не смотрят. Я пытаюсь создать опыт, который порекомендует вам отличный фильм как можно быстрее. Это означает, что основой Trailerly является алгоритм рекомендаций фильмов, поэтому мне нужно было сделать это правильно.

Проблема холодного старта очень распространена в рекомендательных алгоритмах. Это когда алгоритм не может сделать выводы для пользователей или элементов, о которых у него недостаточно данных. В контексте рекомендации фильмов есть две основные области недостаточности данных: новые пользователи и новые фильмы. Старые фильмы имеют множество оценок от многих пользователей, а новые — нет. У опытных пользователей приложения есть множество рейтингов, на которых можно обучать алгоритм, но у новых пользователей их нет. Изучив, как другие создавали алгоритмы рекомендаций фильмов, я понял, что проблема большей части литературы о том, как создать систему рекомендаций фильмов, заключается в том, что вся она основана на совместной фильтрации с набором данных MovieLens. Набор данных MovieLens представляет собой набор данных из 25 миллионов рейтингов фильмов с ограничением по состоянию на 2017 год. Это означает, что для фильмов, созданных после даты окончания, рейтинги отсутствуют. Без моих собственных оценок, восполняющих этот пробел в новых фильмах, совместная фильтрация с этим набором данных непригодна для любого полноценного продукта. Это исключило совместную фильтрацию. Оценив, какие данные у меня есть и как я хочу, чтобы работал алгоритм, я решил попытаться создать модель линейной регрессии. Используя данные о фильме, я мог бы обучить модель на основе оценок пользователей, чтобы определить их предпочтения по всем различным характеристикам фильма (дата выпуска, доход, жанры).

Вот как я это создал:

Сбор и фильтрация данных

Первое, что мне нужно было сделать, это собрать данные. TMDB (themoviedb.org) имеет общедоступный API для краудсорсинговых данных о фильмах. Я использовал эту базу данных для данных о фильмах в Trailerly. Я настроил программу Python для увеличения 900 000 идентификаторов фильмов TMDB и записи данных для этого фильма в строку файла данных (csv). Большинство неизвестных и малоизвестных фильмов мне бесполезны, поэтому я включал только те фильмы, у которых был указан бюджет и доход. Уже одно это сократило количество фильмов с 900 000 до 12 000. После фильтрации фильмов без сертификации или отсутствия важных данных у меня осталось около 5000 фильмов. Я также скорректировал все денежные значения с учетом инфляции, используя пакет python cpi (индекс потребительских цен).

Настройка кадра данных фильма для инфляции

Создать список числовых функций

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

Дата выпуска: # дней с 1980 года.
Доход
Среднее число голосов
Подсчет голосов
Сертификация (1=G, =PG, 3=PG-13, 4=R)
Продолжительность
Жанры (каждый жанр имел характеристику, равную 0 или 1)
Бюджет
ROI
Актер 1,2,3 Возраст
Актер 1,2,3 Популярность
Актер 1,2,3 Количество фильмов
Актер 1,2,3 Блокбастер (Средний доход от фильмов)
Средний доход продюсерских компаний

Затем я преобразовал нечисловые данные в числовые, чтобы они соответствовали этим функциям. https://colab.research.google.com/drive/1vk7wvOoT2GXTfK8x_RfrCrzMCS0THUZ9?authuser=2#scrollTo=aZ1xFc0REGTy

Линейная регрессия

Я выбрал для этого алгоритма линейную регрессию, потому что у большинства пользователей не хватит рейтинга для обучения чему-то более сложному, а модель линейной регрессии работает быстро и должна быть достаточно точной. Используя некоторых пользователей MovieLens в качестве тестовых данных, я создал набор данных всех фильмов, которые оценил пользователь, включая каждую из функций и их рейтинг. Затем я использовал 80% данных для обучения модели линейной регрессии научного набора с использованием Python, а затем перекрестно проверил модель этого человека на остальных 20% данных, чтобы протестировать ее. В конечном итоге это привело к довольно высокой средней абсолютной ошибке и среднеквадратической ошибке, чуть более 1 для большинства пользователей. Это означает, что в среднем оценки, полученные моей моделью, были на +/- 1 ниже фактической оценки, которую дал пользователь. Рейтинги выставляются по шкале от 1 до 5, так что это не очень хорошо.

Оптимизация модели

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

Чтобы найти коллинеарные переменные, я создал корреляционную таблицу Пирсона со всеми функциями набора данных.

Выделив значения корреляции больше 0,5 или меньше -0,5, я смог выделить любые переменные, коррелирующие друг с другом. Мне удалось удалить актеров 1, 2 и 3, популярность, средний доход компаний, бюджет, подсчет голосов и рентабельность инвестиций. Затем, чтобы выяснить, какие переменные действительно имеют значение и влияют на рейтинг, я нашел 10 пользователей с рейтингом > 100 и приличным MAE и нашел корреляцию между каждой из переменных и рейтингом. Я усреднил абсолютное значение всех корреляций, чтобы определить, насколько сильно рейтинг зависит от каждой из характеристик. Это позволило легко определить, какие переменные сильно коррелируют с рейтингом, а какие нет. В итоге мне не удалось избавиться от каких-либо переменных, но было интересно посмотреть, что имеет значение, а что нет. Характеристики с низкими значениями корреляции (менее 0,1), такие как возраст актера или сертификат, не имеют большого значения для рейтинга. Признаки с высокими значениями корреляции (более 0,15) имеют большое значение для рейтинга. Неудивительно, что характеристикой, наиболее коррелирующей с рейтингом, было среднее число голосов, что имеет смысл, поскольку люди любят смотреть хорошие фильмы. ROI и количество голосов также тесно коррелировали с рейтингом. Самым важным жанром при определении рейтинга стала драма.

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

Получение оценок пользователей

Из-за особенностей моего приложения, за исключением онбординга, пользователю никогда не приходится давать какие-либо явные оценки. Как и в случае с TikTok, мне пришлось определять рейтинг на основе их взаимодействия с трейлерами в их ленте. Взвесив дизлайки, закладки, лайки и время просмотра, я смог получить представление о том, что они думают о фильме, который им только что показали, и использовать это значение в качестве рейтинга для обучения своей модели. Проблема холодного запуска имеет два аспекта: недостаточно данных, которые можно использовать для рекомендации меньших и новых фильмов, а также недостаточно данных для нового пользователя моего сайта. Перейдя на алгоритм линейной регрессии, основанный на деталях фильма, первая проблема была решена, потому что для каждого нового фильма мне не нужны оценки других пользователей, мне нужны только детали фильма. Чтобы решить вторую проблему, я попытался сопоставить пользователя, использующего совместную фильтрацию, с весьма предсказуемым пользователем MovieLens, чтобы использовать его модель. Я думал, что это даст более точные рекомендации, поскольку пользователь MovieLens оценил больше фильмов. Однако после некоторого тестирования алгоритм ухудшился (поскольку из-за скудных данных о пользователе Trailerly сопоставить его с действительно похожим пользователем MovieLens так же сложно, как и обучить точную модель на его данных), поэтому я взял это из. Оказывается, модель линейной регрессии относительно хорошо справляется со второй проблемой холодного запуска сама по себе. Несмотря на то, что пользователь оценил очень мало фильмов, алгоритм все равно способен учитывать его предпочтения и улучшается с каждым просмотренным трейлером.

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

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

Добавление обнаружения

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

В целом в результате получился вполне удовлетворительный алгоритм для www.trailer.ly. Попробуйте и убедитесь сами!

Спасибо за прочтение :)