Эволюция списка рекомендаций в SmartProgress
Выборка наиболее интересного пользовательского контента для пользователей — актуальная задача для многих проектов, и мы не исключение. В этой статье я хочу рассказать про то как мы решали эту задачу с момента старта проекта и до сегодняшнего дня на примере списка целей в SmartProgress.
Этап 1: Модерация.
Это наиболее простой способ организации процесса отбора пользовательского контента. Поэтому на старте проекта мы прибегли именно к данному способу. Его главный плюс — быстрота и простота внедрения. Что может быть проще — пройтись по списку нового контента и отметить наиболее интересные, а потом в выборке учесть данную отметку. Но и минусы такого решения значительные:1) Требуется человек для постоянного отслеживания новых целей. И этому человеку нужно постоянно платить зарплату. Либо тратить свое время на данную операцию.2) Модератор отбирает цели по субъективному признаку — так как он думает, и не факт, что другие пользователи разделяют его мнение.3) При таком отборе создается единый список целей, который показывается всем пользователям, а у всех пользователей вкусы и предпочтения разные, и то что одним пользователям может быть интересно, другим — совершенно безразлично.
Этап 2: Следим за предпочтениями пользователей.
Для реализации учета предпочтений пользователей, нам потребовалось гораздо лучше продумать схему объединений целей, чем просто список категорий. Для этого мы внедрили понятие группы целей. Группа целей — это список всех целей пользователей объединенные одной конкретной темой, например — «Продвижение и развитие в интернете» или «Переезд за границу». Таких групп у нас уже создано более ста штук. Более подробно про группы, и как мы их делали можете почитать в наших статьях: Похожие цели. Новый инструмент для поиска единомышленниковElasticSearch и поиск наоборот. Percolate API
Теперь большинство целей у нас состоят в группах. А зная какие цели ставит пользователь и на какие цели он подписывается — знаем его предпочтения. Получаем список групп, в которых состоят эти цели — и показываем другие цели из данных групп.
В итоге список рекомендаций стал более персонализированным, учитывающий предпочтения и интересы каждого пользователя.
Но отслеживая данную рекомендательную систему мы обнаружили несколько проблем, которые все еще актуальны для неё:1) Не равномерное распределение целей по группам. Т.е. если пользователь подписался на 1 цель в группе А, в которой целей гораздо больше чем в других группах, то у пользователя будут преобладать в рекомендациях цели из группы А.2) При недостаточном потоке новых целей по его релевантным группам — рекомендации застаиваются. Т.к. при такой системе списка целей мы искусственно ограничиваем выборку целей только предпочтениями пользователя, то мы для пользователя снижаем поток нового контента, и пользователь постоянно в своей рекомендации видит одни и те же цели.
Этап 3: Не показываем цели. Которые пользователь уже смотрел.
Что бы пользователю не замыливать глаз одними и теми же целями, мы решили скрывать из выдачи цели, которые пользователь уже просмотрел. Для этого мы добавили таблицу `goals_ignore`, в которую заносятся цели, которые пользователь посмотрел, а так же, которые упорно игнорирует. Т.е. если пользователю в списке рекомендаций показали 10 раз цель и он в неё так и не зашел, значит она ему не интересна и больше показывать её данному пользователю не нужно — заносим в `goals_ignore`.
Тем самым удалось добиться того, что список рекомендаций начал отчищаться от целей, которые пользователь уже посмотрел или не хочет смотреть.
Этап 4: Вероятностная выборка целей. Показываем в первую очередь самое интересное.
Для этого мы ввели показатель CTR для цели, который высчитывался из соотношения открытия цели к её просмотрам в списке рекомендаций. И стали сортировать список рекомендаций по данному показателю. Тем самым пользователь в первую очередь видит самые интересные цели. Но при такой схеме, менее интересные цели опускаются все ниже и ниже и возможность добраться до них постоянно уменьшается. Поэтому мы решили привнести определенную случайность в выборку целей. Что бы менее интересные цели все равно имели шанс оказаться на первых строках списка и тем самым откорректировать свой ctr, в случае ошибочного его занижения.Для этого мы по крону запускаем скрипт высчитывания случайного коэфициента целей на основе их ctr.
UPDATE goals SET order_random = ((list_click/list_view)*RAND ())
И уже по параметру order_random сортируем выдачу.Благодаря этому, список рекомендаций стал ротироваться и на первые позиции списка стали показываться цели, которые давно опустились глубоко вниз. Помимо улучшения списка рекомендаций для пользователей этот шаг дал новый толчек старым целям. Пользователи заходили в забытые цели, приносили активность и авторы снова возвращались в свои цели.
Этап 5. Следим за степенью предпочтения пользователей.
Если пользователь ставит больше целей в одной группе или подписывается больше на цели определенной группы, значит данная группа целей ему интересна больше других, значит и в рекомендациях ему нужно соответственно больше показывать цели из данной группы.
И так, с помощью этапов 3–5 нам удалось решить проблемы описанные для списка рекомендаций из второго этапа, а именно:1) Не равномерное распределение целей по группам2) Застой списка целей при недостаточном потоке новых.
Но обнаружилась новая проблема. Мы не знаем предпочтений новых пользователей, которые только что зарегистрировались и не поставили не одной цели и не подписались на чужие.
Этап 6. Не знаешь какие у пользователя предпочтения — спроси его.
После регистрации, мы показываем пользователям — путеводитель по сайту, который помогает им быстрее разобраться с интерфейсом. В него добавили небольшой опросник, в котором попросили отметить категории, которые для пользователя наиболее интересны. И на ответах пользователя стали строить его список рекомендаций до момента набора определенного числа подписок, после чего переключаем пользователя на нашу стандартную систему рекомендаций.
В итоге средняя глубина просмотров выросла на 15% с 3,9 до 4,5. А средняя продолжительность пребывания на 36% с 5,5 мин. до 7,5 мин.