Автороцентричное ранжирование. Доклад Яндекса о поиске релевантной аудитории для авторов Дзена +19


Важнее всего для сервиса Яндекс.Дзен — развивать и поддерживать платформу, которая соединяет аудитории с авторами. Чтобы быть привлекательной платформой для хороших авторов, Дзен должен уметь находить релевантную аудиторию для каналов, пишущих на любые темы, в том числе на самые узкие. Руководитель группы счастья авторов Борис Шарчилев рассказал про автороцентричное ранжирование, которое подбирает для авторов наиболее релевантных пользователей. Из доклада можно узнать о том, чем такой подход отличается от подбора релевантных айтемов — более популярного в рекомендательных системах.


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

— Коллеги, всем привет. Меня зовут Боря. Я занимаюсь качеством ранжирования в Дзене. Я уверен, что это один из самых интересных сервисов Яндекса, у нас очень крутое машинное обучение, и в следующие 17 минут я вас в этом постараюсь убедить.

Что такое Дзен? Если совсем просто, Дзен — это сервис персональных рекомендаций. Мы стараемся рекомендовать пользователям релевантный им контент, основываясь на том, что мы знаем об интересах этих пользователей. Наша высокоуровневая цель — чтобы пользователи хотели в Дзене проводить время. И что очень важно — чтобы они об этом времени не жалели.

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



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

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



Важно понимать, что Дзен уже очень большой. По данным Яндекс.Радара, на конец прошлого года у нас число дневных читателей примерно 10–12 млн в день, число читателей в месяц примерно 35 млн в день, и даже по некоторым данным, из того же Яндекс.Радара, мы в прошлом году впервые обошли по аудитории Яндекс.Новости. Это значит, что мы на полном серьезе делаем интернет, у нас задачи очень серьезные, их много, и мы очень ждем вашей помощи.



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

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

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

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

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



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

Нам важно улучшать ранжирование. То есть нам нужно применять и новые модели машинного обучения, и улучшать наши текущие модели в других странах. Мы рекомендуемся не только в России, но и во многих других странах мира.

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

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

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

Давайте рассмотрим это на примере.



Мы выбираем, предположим, из двух карточек, которые мы хотим показать пользователю.

Так устроен мир и так устроен человек, что есть нечто более среднепопулярное, где вероятность клика в среднем процентов 20, а есть что-то более нишевое, например статьи про науку или про космос.

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



Почему это хочется делать? На самом деле, здесь есть две причины. Первая — продуктовая. То есть мы хотим, чтобы Дзен был некоторым срезом интернета. Чтобы всё, что пользователь может найти и чем он интересуется в большом интернете, было представлено в Дзене. И чтобы он получал то, что ему интересно.

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



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

Как здесь быть?



Мы долго думали и придумали новую концепцию. Мы назвали ее автороцентричным ранжированием или показами для автора.

Какова наша цель в обычном ранжировании, которое мы называем пользователецентричным? Найти материал, который наиболее релевантен пользователю. Мы отвечаем на вопрос, что показать пользователю.

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



Как же мы это делаем? Предположим, что у нас есть обычная формула ранжирования. Для простоты предположим, что она предсказывает вероятность клика пользователя на данный айтем, на данную карточку. Что мы сделаем? Давайте теперь для каждой статьи зафиксируем ее и применим нашу модель для этой статьи, в идеале — ко всем пользователям, на практике — к какому-то семплу пользователей. И построим распределение наших scores, то есть оценок вероятности кликнуть на статью, для каждой статьи по пользователям. Теперь для каждой статьи у нас есть такое распределение, как на графике (слайд выше — прим. ред.). После этого отранжируем статьи для пользователя и выберем топ не просто по вероятности клика, а по перцентили, в которую данный пользователь попадает для данной статьи. То есть мы оценим вероятность клика, посмотрим, куда пользователь попадает в этом распределении, и отранжируем по этой величине.



Вот у нас те же две карточки, одна из них более кликабельна, 20%, другая — менее, 1%. Теперь, если взять конкретного пользователя, возможна такая ситуация, что у него на более популярную карточку вероятность клика больше, чем на менее популярную, скажем, 10% против 3%. Но так как в среднем вероятность клика на популярную карточку 20%, а у пользователя 10%, то он в среднем менее релевантен данной публикации, чем средний пользователь Дзена. А в другой ситуации наоборот: у него вероятность клика 3%, но в среднем у статьи 1%. Поэтому он является более релевантной для статьи аудиторией в среднем, чем остальные пользователи Дзена. Поэтому ключевой инсайт здесь в том, что даже если вероятность клика на статью меньше, с помощью такого фреймворка мы имеем шанс показать менее популярную статью, если пользователь входит в наиболее доверенное ядро для данной публикации.



Если пользователи приходят к нам более или менее равномерно, то данный score, по которому мы ранжируем, то есть перцентиль, в который попадает каждый пользователь, будет распределена равномерно по пользователям. Это значит, что если все статьи ранжировать таким образом, то все они соберут более-менее одинаковое количество показов. Не будет выбросов в десятки миллионов показов против 10 показов у каких-нибудь менее релевантных карточек. Таким образом, балансируя пользователецентричное и автороцентричное ранжирование, мы можем добиваться того соотношения счастья пользователей и счастья авторов, которое мы считаем правильным.



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

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



Результаты тоже получаются хорошими. Мы сильно растим счастье обделенных вниманием хороших авторов в Дзене и при этом не просаживаем общие пользовательские метрики. То есть бизнес-задача полностью достигается.

Я сейчас показал один из примеров задач, которыми у нас можно заниматься. Разумеется, этих задач много, и с каждой из них нам нужна ваша помощь. Очень надеемся, что вы захотите у нас работать. Напоследок скажу пару слов о том, чего же мы ждем от стажеров и чего мы от них не ждем. От стажера мы ждем самого главного — умения писать код. У нас в сервисе нет дата-саентистов в чистом виде. У нас все — ML-инженеры, они должны уметь делать полный цикл задач. Они должны уметь и имплементировать свое решение в продакшен, и применять ML. То есть мы ожидаем, что вы умеете писать код на базовом уровне, понимаете подходы, знаете алгоритмы, структуры данных, основы машинного обучения.

Чего мы не ждем от стажеров? В первую очередь, мы не ждем глубокого знания каких-то языков или фреймворков. То есть если вы не знаете, как работают корутины в Python — ничего страшного, мы вас всему научим. И мы не ждем от вас большого опыта. Мы ждем от вас знаний, желания работать. Если нет опыта — ничего страшного. Всему научим, и все будет хорошо. Спасибо!




К сожалению, не доступен сервер mySQL