Привет. Меня зовут Алексей Жиряков, и я техлид backend-команды витрины онлайн-кинотеатра KION. Этот текст написан по мотивам моего выступления на МТС True Tech Day.
В KION мы формируем персональную витрину для каждого юзера в условиях достаточно высокой нагрузки: в пике более 600 запросов в секунду. Время ответа на запрос при этом минимально: около 160 мс. Конечно, мы используем Machine Learning (ML), но есть и другие инструменты — например, бизнес-правила, и их около 50. О различных нюансах работы KION в связке с ML и не только расскажу в двух постах. Сегодня обсудим работу витрин и полок KION, объясню, как мы строим персональную витрину, внедряем ML в баннерную полку и просчитываем тренды. Следующий пост будет про обучение нейронки и бизнес-правила. Жду вас под катом!
Сразу после запуска онлайн-кинотеатра пользователь попадает на главную витрину: там он видит популярные фильмы, новинки, топ за неделю, разные подборки. А еще там есть вкладки «Фильмы», «Сериалы» — это тоже витрины, но уже по форматам. Еще одна разновидность — телевитрина. Как раз сейчас мы над ней активно работаем: переходим с вендорного решения на свой бэк и уже запустили AB-эксперимент.
Витрины состоят из полок. Чтобы пользователю было интереснее, мы сделали несколько видов:
-
баннерная карусель — самая первая полка на главном экране. У нее больше всего просмотров;
-
VOD-полки (англ. Video on Demand, то есть «видео по запросу»). Пример на скрине выше — «Специально для вас». То есть это обычная полка с видеоконтентом, там могут быть фильмы и сериалы;
-
полка с Originals. Тут фильмы и сериалы, которые снял KION, а еще проигрываются трейлеры;
-
суперполки. Каждая из них состоит из обложек. Они могут вести как на другую полку, так и на определенный тайтл — что это, расскажу ниже, так как с этим словом в этом тексте вы еще много раз встретитесь.
Тайтл — это уникальное обозначение единицы контента, например фильма или сериала. У сериалов есть сезоны, а у сезонов — эпизоды, и это все один тайтл. То есть сериал обозначается одним тайтлом, даже если у него много сезонов и серий.
Вернемся к теме. Сейчас нагрузка на сервис составляет 600 RPS. При этом мы делаем уникальную персональную витрину для каждого пользователя, а не просто «ходим» в кэш или базу данных. То есть готовим персональную выдачу на каждый запрос, применяем больше 50 бизнес-правил — подробнее о них расскажу ниже. И все это быстрее, чем за 300 миллисекунд.
Ради чего все это? Мы хотим растить такой показатель, как TvTu — время на пользователя в системе. А еще увеличивать конверсию в осознанное смотрение и retention (удержание). Другими словами, мы делаем все, чтобы нас смотрели больше, дольше и как можно чаще возвращались.
ML в онлайн-кинотеатре KION
А вот теперь переходим к машинному обучению. Оно дает +5% к смотрению. Изначально мы выбрали эволюционный путь развития. Каждую фичу «катим» через AB-эксперименты, иногда — ABC.
Что вообще такое эволюционный путь развития? На витрине мы выбираем точки взаимодействия между пользователем и ML. Определяем нашу цель. Дальше готовим MVP, модель, ручку, проводим AB-эксперименты, смотрим на результат. Если метрики «красятся», тогда мы принимаем решение, как выкатывать готовый продукт или функцию в прод.
Например, на главной витрине наши цели — это поиск, точки взаимодействия, баннерная карусель, общая VOD-витрина. Внутри нее — полка. Если зайти в карточку фильма, здесь тоже будет полка. Это точка взаимодействия юзера и ML.
Как мы собираем персонализированное предложение
Когда пользователь запускает KION или переключается между витринами, запрос от юзера приходит на бэк. В KION есть такой сервис — Blender: он как раз и работает с запросами пользователя. Компонует витрину, «ходит» за разными источниками, применяет больше 50 бизнес-правил. Например, вырезать просмотренные или контент, который нельзя показывать для этого устройства. Бывает, что фильмы нельзя демонстрировать на смартфонах или планшетах, можно только на больших устройствах по требованию правообладателя. Потом запрос возвращается.
Перед нами стоит еще один сервис Media Gateway, который проксирует запрос, получает наш результат и обогащает его информацией: ссылки на картинки, рейтинг, метки купленности. Еще, например, подставляет ссылку на баннер с нужным разрешением для определенного устройства. То есть мы не думаем о вещах в духе «в каком разрешении отдать баннер» — Media Gateway делает все за нас. Blender собирает, компонует витрину, применяет бизнес-правила и оперирует только тайтлами.
Нужно понимать, что ML не генерирует полки, названия и не снимает фильмы — он работает с той фактурой, которая уже есть. У нас больше тысячи полок — ML берет готовые полки и персонально ранжирует их как по вертикали, так и по горизонтали для каждого запроса.
Изначально полки были ручные, но тут есть проблема: при таком наполнении фильмы часто «моргают». Что это значит? Например, лицензия на фильм или мультик закончилась и пропала из полки, потом она может появиться, и если, к примеру, в полке осталось меньше трех тайтлов после фильтрации, она будет вообще удалена с витрины. Такие короткие полки мы удаляем, поэтому витрина KION всегда заполнена.
За редакторскими полками нужно следить, поэтому мы пришли к автополкам: редакция пишет правила, мы реализуем. Служба интерпретирует это правило и наполняет нужные полки. Таких уже больше тысячи.
Если в систему был заведен новый тайтл, наша служба понимает, что появилась новинка. То есть контент после транскодирования, подготовки всех баннеров попал к нам через Kafka. Мы понимаем, в какие полки его нужно поставить, ставим — и он появляется на витрине.
Есть простые полки, например «Русские комедии» — категоризация контента по жанрам. Пример более сложной автополки — «Популярно сейчас». Для нее мы берем статистику смотрения за семь дней, анализируем данные из поиска за семь дней, смотрим, что больше всего ищут. Все это объединяем в эту полку. И да, еще раз добавлю, что она персонализированная, то есть для каждого она своя. Ну а мы ранжируем тот контент, который туда запишем.
Как строим персональную витрину
У нас есть шаблон с «прибитыми» (закрепленными) полками. Для разных платформ их можно закреплять по-разному. В свободные слоты мы делаем запрос за VOD персональной полкой. Дальше получаем ответ, фильтруем его и расставляем уже полученные полки в том порядке, который нам вернул ML. «Прибитые» полки тоже ML-ные — например, баннерная полка или «Популярно сейчас». VOD-полки ставятся в свободные слоты.
Сейчас в проде у нас модель для VOD-полок, где первые три полки персональные, а остальные отсортированы релевантно по социально-демографическим кластерам. Персонализация все актуальнее: пользователи больше любят разнообразие и высокий рейтинг.
Победил симбиоз между человеком и ML
Не так давно мы внедрили ML в баннерную полку. Провели несколько серий AB-экспериментов — в результате победил симбиоз между человеком и ML. Так что на первые пять мест для фильмов на главной мы выставляем контент, выбранный нашей редакцией. На витринах «Фильмы» и «Сериалы» — три места за редакцией. Остальное заполняет ML из тех баннеров, которые есть за всю историю.
При формировании витрины и полок применяется градиентный бустинг. Учитываются статистика смотрения, взаимодействия пользователя, фичи новизны, тренды, устаревания и пенальти показов.
Фичи новизны — это три флага: «вышел сегодня», «на этой неделе», «двумя неделями ранее», то есть более новый контент модель должна подбрасывать повыше. А еще есть тренды.
Кое-что о трендах
Теперь о том, как мы просчитываем тренды. Берем конверсию в осознанное смотрение (когда человек зашел и посмотрел больше, чем N минут) за определенное количество дней. Просчитываем все это за нужный срок. Потом выполняем ту же операцию за такой же период, только за предыдущую дату, делим и получаем тренд. Это все подается в модели для «обучение устаревания» или «пенальти показов». Когда выходит новый тайтл, его смотрят больше, потом меньше. Если это все еще новинка, ее подбрасывают зрителю до тех пор, пока интерес не угаснет.
У нас есть статистика смотрения: для всех тайтлов мы считаем разницу между показами и просмотрами — и подаем это на вход модели.
А еще ML в карточке фильма учитывает популярность, метатеги, и там используется DSSM-нейронка. Наши молодые ученые говорят, что должно быть две полки — «Похожие» и «Смотрят также», ведь это разные вещи.
На сегодня все. Скоро вернусь со второй частью поста: в нем расскажу, как мы обучаем нейронки, какие у нас есть позитивные фичи и с чем возникают сложности, а еще — о том, как работают бизнес-правила.
Автор: Aleksey999