- PVSM.RU - https://www.pvsm.ru -
Gitfm.com [1] – сервис персональных рекомендаций Github репозиториев на основе коллаборативной фильтрации starred репозиториев пользователя.
Под катом описание архитектуры и двухдневная хроника, т.к. проект был создан с нуля за 48 часов в рамках конкурса RailsRumble2012.
Пару дней назад мы с коллегами из Evrone [2] приняли решение, что будем участвовать в RailsRumble2012. Суть конкурса простая – на команду из 4ох человек выдается один приватный репозиторий в Github и один
Выбирали идею классическим брейнштормом – в Campfire (т.к. мы все живем в разных городах – Минск, Москва, Прага и Хельсинки) по очереди выставляли идеи и по 30 секунд каждый писал, что о ней думает. В итоге, отказавшись от трекера полезных дел, агрегатора отзывов о товарах и еще пары совсем стартаперских идей мы сошлись на Gitfm.
Мы уже во всю обсуждали архитектуру приложения. Не буду вдаваться в подробности, вот результат:
Основное приложение написано на Ruby on Rails. Из особенностей могу указать, что для быстрого скачивания пользовательских данных мы используем EM Synchrony [4], для управления генерацией рекомендаций используем Resque [5]. Возможность отмечать репозитории как starred в Github с нашего сайта реализуется с помощью гема octokit [6]. Мы написали в Github и попросили увеличить лимит API запросов для нашего приложения – через несколько часов нам ответили и увеличили квоту до 300 000 запросов в день.
Я очень советую использовать EM Synchrony для сбора данных, кроулинга, вот несколько отличных примеров использования:
gistflow.com/posts/213-check-pages-status-with-em-synchrony-crawler [7]
stackoverflow.com/questions/11000029/nested-iterators-for-em-synchrony-in-ruby [8]
Rails приложение по запросу рекомендаций кладет id пользователя в специальную Redis очередь, из которой демон по очереди их вытаскивает и обрабатывает. Демон написан на jRuby потому что мы используем в качестве рекомендательного движка Apache Mahout [9], т.е. используем алгоритмы коллаборативной фильтрации. В качестве меры близости мы взяли коэффициенты Танимото [10], для оценки репозиториев мы используем бинарные данные, т.е. по сути наши пользователи ставят оценки 0 или 1. В будущем, естественно, мы будем учитывать watched репозитории, форки, частоту обновления репозитория. За 2 дня лично я открыл для себя просто новый мир, настолько интересной мне кажется эта область. С удовольствием делюсь с вами полезными ссылками по теме:
habrahabr.ru/post/150399/ [11]
www.igvita.com/2007/01/15/svd-recommendation-system-in-ruby/ [12]
www.igvita.com/2009/09/01/collaborative-filtering-with-ensembles/ [13]
jaydonnell.com/blog/2011/10/21/collaborative-filtering-using-jruby-and-mahout/ [14]
code.google.com/p/unresyst/wiki/CreateMahoutRecommender [15]
Для передачи данных между приложениями мы использовали редис. Для отправки сообщения о завершении создания рекомендаций был написан специальный сервер – клиент в браузере заходит на страницу и мы открывает подключение к нашему серверу, который слушает каналы редиса по паттерну «messages:*» и хранит связи id — connections. То есть воркеру достаточно послать сообщение на «messages:#{user_id}» и оно дойдет через сокет-сервер до клиента в браузер. Подробнее можно почитать тут:
github.com/igrigorik/em-websocket [16]
github.com/mloughran/em-hiredis [17]
github.com/gimite/web-socket-js [18]
На данный момент в нашей базе 2413 пользователей, из них 1070 зарегистрировались сегодня, 84762 репозитория, обработано 2789 запросов на рекомендации.
В планах у нас – отойти от бинарной модели рекомендаций, сделать возможность убрать репозитории из списка рекомендованных, развернуть отдельный сервер для генерации рекомендаций (сейчас ничего нельзя трогать в проекте, пока его не оценило жюри).
На последок вариант октокэта, нарисованный тоже в рамках RailsRumble специально для GitFM:
Над проектом работали makaroni4 [19], releu [20], ognevsky [21] и kirs [22] из компании Evrone [2].
Автор: makaroni4
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ruby/17293
Ссылки в тексте:
[1] Gitfm.com: http://Gitfm.com
[2] Evrone: http://evrone.ru
[3] VPS: https://www.reg.ru/?rlink=reflink-717
[4] EM Synchrony: https://github.com/igrigorik/em-synchrony
[5] Resque: https://github.com/defunkt/resque
[6] octokit: https://github.com/pengwynn/octokit
[7] gistflow.com/posts/213-check-pages-status-with-em-synchrony-crawler: http://gistflow.com/posts/213-check-pages-status-with-em-synchrony-crawler
[8] stackoverflow.com/questions/11000029/nested-iterators-for-em-synchrony-in-ruby: http://stackoverflow.com/questions/11000029/nested-iterators-for-em-synchrony-in-ruby
[9] Apache Mahout: http://mahout.apache.org/
[10] коэффициенты Танимото: http://habrahabr.ru/post/104901/
[11] habrahabr.ru/post/150399/: http://habrahabr.ru/post/150399/
[12] www.igvita.com/2007/01/15/svd-recommendation-system-in-ruby/: http://www.igvita.com/2007/01/15/svd-recommendation-system-in-ruby/
[13] www.igvita.com/2009/09/01/collaborative-filtering-with-ensembles/: http://www.igvita.com/2009/09/01/collaborative-filtering-with-ensembles/
[14] jaydonnell.com/blog/2011/10/21/collaborative-filtering-using-jruby-and-mahout/: http://jaydonnell.com/blog/2011/10/21/collaborative-filtering-using-jruby-and-mahout/
[15] code.google.com/p/unresyst/wiki/CreateMahoutRecommender: http://code.google.com/p/unresyst/wiki/CreateMahoutRecommender
[16] github.com/igrigorik/em-websocket: https://github.com/igrigorik/em-websocket
[17] github.com/mloughran/em-hiredis: https://github.com/mloughran/em-hiredis
[18] github.com/gimite/web-socket-js: https://github.com/gimite/web-socket-js
[19] makaroni4: http://habrahabr.ru/users/makaroni4/
[20] releu: http://habrahabr.ru/users/releu/
[21] ognevsky: http://habrahabr.ru/users/ognevsky/
[22] kirs: http://habrahabr.ru/users/kirs/
Нажмите здесь для печати.