Сегодня я расскажу о том, как можно использовать данные о пользователях из социальных сетей для рекомендаций веб-страниц на холодном старте. Все приведенные в статье результаты носят чисто экспериментальный характер и в настоящий момент мы не реализованы в продакшене. Здесь, как и в прошлой статье, будут использоваться элементы текстмайнига для анализа текстового контента веб-страниц.
Сначала немного статистики для того, чтобы показать важность настоящего исследования. Около 50% пользователей нашей системы регистрируются с привязкой аккаунтов социальных сетей vkontakte (VK) и facebook (FB). Причем из зарегистрированных через социальные сети 71% приходится на VK и 29% на FB.
API FB и API VK позволяют извлекать некоторые данные об интересах и предпочтениях пользователя. Но не все так просто, как может показаться. Для получения данных пользователя нужно получить особые права, согласие на которые дает сам пользователь при регистрации в системе. Здесь возникает тонкий момент. С одной стороны, мы ходим вытянуть как можно больше информации о пользователе. С другой стороны, просить слишком много прав — наглость, которая может отпугнуть пользователя. Нужно найти компромисс — тонкое равновесие между полезностью получаемых данных для улучшения рекомендаций и «суммой» кредита доверия от пользователя, который соглашается, чтобы мы залезли в его персональные данные.
Путем долгих проб и ошибок для себя мы такой компромисс нашли, но эта задача сугубо индивидуальна для каждого проекта, так как учитываются множество «за» и «против», специфичных для системы.
В настоящей статье я расскажу о том, как можно использовать теги пользователей из следующих категорий: games, books, music, movies и television. Такой выбор полей был связан с тем, что в них хранятся теги в чистом виде и можно привязать каждое из этих полей к соответствующим категориям Surfingbird. Вероятно, в ближайшее время я также расскажу, как можно обрабатывать и другие, не столь очевидные поля, такие как languages (на каких языках говорит пользователь), devices (hardware и sofware, которыми он пользуется), education (место и уровень образования), bio или about (информация о себе), feeds (посты пользователя).
Сразу хочу оговориться, что первая проблема, с которой мы столкнемся, это сильная разреженность данных. Информация в полях games, books, music, movies или television на настоящий момент доступна для порядка 15% пользователей. Но здесь можно сказать, что, во-первых, способы получить теги пользователя не ограничиваются API FB и VK. Например, в будущем мы также можем дать возможность указывать их при регистрации и корректировать в своем профиле. Во-вторых, даже если для небольшой доли тех, кто честно указал свои интересы, мы сможем с первых показов давать рекомендации, которые «приятно удивят», то это повысит общую лояльность к системе и значит наши усилия не напрасны.
Есть некотрые отличия в структуре данных, возвращаемых API FB и VK. Данные FB лучше структурированы. Например, каждый исполнитель или фильм хранятся в отдельных полях. В VK они пишутся произвольным текстовым полем, что затрудняет выделение тегов:
Пример JSON'а от FB:
{ "books" : { "data" : [ { "category" : "Book",
"created_time" : "2013-02-17T17:41:14+0000",
"id" : "110451202473491",
"name" : "«Мифы экономики» Сергей Гуриев"
},
{ "category" : "Book",
"created_time" : "2013-02-04T20:40:10+0000",
"id" : "165134073508051",
"name" : "Джордж С. Клейсон "Самый богатый человек в Вавилоне""
},
...
"television" : { "data" : [ { "category" : "Tv show",
"created_time" : "2012-06-12T04:52:42+0000",
"id" : "184917701541356",
"name" : "Бизнес-секреты с Олегом Тиньковым"
} ],
...
}
...
}
Пример JSON'а от VK:
{
"books" : "Все тома Александра Беляева, Троепольский "Белый Бим, черное ухо", Жюль Верн "Путешествие к центру Земли", "Дети капитана гранта", "Пятнадцатилетний капитан", Екзюпери "Маленький принц", Всеволод Нестайко "Тореадоры з Васюкивкы", Ярослав Стельмах "Химеера лисового озера або Мытькозавр з Юркивкы", Джонатан Свифт "Гуливер", Чайковский "За сестрою"",
"games" : "Sims 1, 2, 3, весёлая ферма 2 готовим пиццу",
"movies" : "Ночь в музее, папины дочки, моя прекрасная няня, Дрэйк и Джордж, не такая, слон и принцесса, icarli, типа крутые легавые, ледниковый период 3, труп невесты, Sponge Bob, вейсайд, детство Гриппи, Аватар, Назад в будущее, назад в будущее 2, назад в будущее 3, Чарли и шоколадная фабрика, Дневники Вампира!!!!!",
...
}
После некоторых усилий теги все-таки удается извлечь и из неструктурированных данных VK. Вот верхушка полученного списка самых популярных тегов:
Далее из тегов, которые встречаются более двух раз, строится словарь тегов. Теперь нужно научиться находить релевантные страницы для каждого тега в словаре. Наиболее естественный способ — это научиться считать количество вхождений тегов в текстовый контент страниц. Однако рекомендовать только по частоте встречаемости неправильно, так как в тегах часто встречаются слова типа «все», «не читаю», «не люблю игры» и так далее. Для решения этой проблемы рассчитываются веса TF-IDF для тегов, причем на множестве пользователей и на корпусе текстов веб-страниц отдельно, так как сквозной подсчет TF-IDF не позволит учесть распределение по пользователям вовсе из-за несорзмерной разницы в объеме текстовой информации в профилях пользователей и текстах веб-страниц.
В результате расчета весов TF-IDF, у нас получаются известными для каждого пользователя и для каждой веб-страницы вектора весов для всех тегов из словаря. Если тег не встречается у пользователя или в контенте страницы, то вес считается нулевым.
Для того, чтобы оценить сходство интересов пользователя и контента веб-страницы, достаточно посчитать скалярное произведение соответствующих векторов весов TF-IDF. Другой, более ленивый вариант, использовать встроенную в СУБД, которую Вы используете, функцию полнотекстового поиска. Например, PostgreSQL успешно справляется с задачей поиска релевантных текстов по тегам пользователя, а также численно оценивает сходство, что позволяет решить задачу ранжирования. По сути, движок полнотекстового поиска проделает все те же самые действия, что были описаны выше, только несколько иными методами. Минусом такого подхода является необходимость построения в БД полнотекстового индекса по всему контенту. Плюсом же полнотекстового поиска в этой задаче является отсутствие необходимости строить словарь тегов и пересчитывать встречаемость тегов в текстах.
Ниже приведен пример рекомендаций для пользователя со следующими тегами в категории игры: Assassins Creed, Mass Effect, Dragon Age: Origins, Heavy Rain.
Итак, мы научились оценивать сходство пользователя (на основе его тегов) и веб-страницы (на основе ее контента). Это является основным кирпичиком, необходимым для построения рекомендаций. Однако, это далеко не все. Мы не учли здесь рейтинги веб-страницы. Ведь рекомендовать сильно непопулярные страницы, даже если они подходят по контенту, не хочется. Затем, нужно правильно скомбинировать полученный алгоритм с уже работающими в системе, но об этом уже в следующих сериях…
Автор: vleksin