Skip to content

tvorogme/recommendation_system

Repository files navigation

scrot

GoTo Code Health Code Climate MIT

Предисловие

Перед нами стояла задача проанализировать новостной портал и научиться автоматически рекомендовать пользователям новости, которые с большей вероятностью им понравятся. Предложенная задача - реальная задача с которой столкнулись специалисты по анализу данных компании E-contenta при разработке рекомендательного движка для новостного сайта. Часть данных была анонимизирована, как обычно делают компании, отдавая свои данные внешним аналитикам.

Данные

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

Как мы это делали

Метрика

Всё началось с выбора метрики, потому что есть очень много возможностей прострелить себе ноги оптимизируя не ту метрику. Для того, чтобы выбрать хорошую метрику, мы использовали эту статью. В итоге мы выбрали MAP@K.

MAP@K

Важно заметить, что в метрике K = 10 ~ количество новостей, которое нужно рекомендовать.

Topic Modeling

Мы начали с подбора алгоритма Topic Modeling-a. После долгих споров в команде и нескольких проверок и сравнений мы выбрали NMF - разложение неотрицательных матриц, которое по принцыпу похож на LDA, но при сравнении NMF - показал лучший результат. О том, как использовать NMF в python можно прочитать тут

Для того, чтобы загнать текст в NMF модель его сначала нужно векторизовать. Мы использовали tf–idf текст туда поступал из мешка слов. (можно использовать n-граммы - тогда результат, возможно, будет лучше).

В итоге с помощью Topic Modeling-a мы построили матрицу в которой была вероятность отношения всех новостей к какой-либо теме из 40.

Бинарный классификатор

С помощью логов мы так же построили график просмотров от времени с начала выхода новости, по которому можно увидеть, что популярность новости падает после пяти часов. Таким образом, мы поняли, что пользователю, в основном, не инетересны новости срок жизни которых превышает 5 часов. По данным логов мы построили сеанс человека - 4 новости, который он читал подряд по времени. С помощью бинарного классификатора мы предсказываем на сколько четвёртая новость подходит первым трём.

После того, как мы попробовали разные алгоритмы для бинарной классификации мы выбрали Random Forest Classifier поскольку он показал лучший результат из всех. В качестве фичей для бинарного классификатора мы использовали 160 фичей Topic Modeling-a (по 40 на каждую новость) и 3 коэффициента Отиаи для 1, 2, 3 новости с 4. Этот коэффициент понять какие пользователи читают одни и те же новости.

Первый результат готов, что дальше

После того, как мы написали 40 штук IPython тетрадок, с разными результатами мы решили переписать всё в нормальный вид и сделать демо версию, где пользователь будет выбирать 3 новости, которые он прочитал, а мы ему будем возвращать рекомендации. И в итоге у нас это получилось! Весь переписанный код находится в этом репозитории. Данные логов распространять нам не разрешили, поэтому здесь их нет.

Спасибо организаторам GoTo и компании E-contenta за предоставленную задачу.