Создание рекомендательного сервиса на Ruby

757fb0d5ec7560b6f25f5bd98eadc020?s=47 Jan Bernacki
December 15, 2012

Создание рекомендательного сервиса на Ruby

757fb0d5ec7560b6f25f5bd98eadc020?s=128

Jan Bernacki

December 15, 2012
Tweet

Transcript

  1. Saturday, December 15, 12

  2. СОЗДАНИЕ РЕКОМЕНДАТЕЛЬНЫХ СЕРВИСОВ НА RUBY АНАТОЛИЙ МАКАРЕВИЧ @MAKARONI4 СЕРГЕЙ ТОЛУБАЕВ

    @RELEU Saturday, December 15, 12
  3. VKONTAKTE.RU Saturday, December 15, 12

  4. AMAZON.COM Saturday, December 15, 12

  5. LASTFM.COM IMHONET.RU Saturday, December 15, 12

  6. > 160 000 000 ТОВАРОВ В AMAZON > 4 500

    000 РЕПОЗИТОРИЕВ В GITHUB > 10 000 000 КНИГ IN GOODREADS Saturday, December 15, 12
  7. ПРОБЛЕМА ВЫБОРА Saturday, December 15, 12

  8. МОТИВАЦИЯ ПОВЫШЕНИЕ ПРОДАЖ ~ 10% UX Saturday, December 15, 12

  9. ДВИЖОК РЕКОМЕНДАЦИЙ ДАННЫЕ ПОЛЬЗОВАТЕЛЕЙ ЮЗЕР С ЧАСТЬЮ РЕЙТИНГОВ ЮЗЕР СО

    ВСЕМИ РЕЙТИНГАМИ Saturday, December 15, 12
  10. ДВИЖОК РЕКОМЕНДАЦИЙ ДАННЫЕ ПОЛЬЗОВАТЕЛЕЙ ЮЗЕР С ЧАСТЬЮ РЕЙТИНГОВ ЮЗЕР СО

    ВСЕМИ РЕЙТИНГАМИ THIS IS SCIENTIFIC! Saturday, December 15, 12
  11. 1 1 1 0.23 1 0.56 0.47 Saturday, December 15,

    12
  12. MEMORY BASED MODEL BASED ГИБРИДНЫЕ ТИПЫ РЕКОМЕНДАЦИЙ Saturday, December 15,

    12
  13. MEMORY BASED ПОХОЖИЕ ПОЛЬЗОВАТЕЛИ ДЕЙСТВУЮТ СХОДНЫМ ОБРАЗОМ Saturday, December 15,

    12
  14. MEMORY BASED ПОХОЖИЕ ПОЛЬЗОВАТЕЛИ ДЕЙСТВУЮТ СХОДНЫМ ОБРАЗОМ Saturday, December 15,

    12
  15. MEMORY BASED ПОХОЖИЕ ПОЛЬЗОВАТЕЛИ ДЕЙСТВУЮТ СХОДНЫМ ОБРАЗОМ Saturday, December 15,

    12
  16. СРАВНИТЬ ПОЛЬЗОВАТЕЛЯ СО ВСЕМИ ВЫБРАТЬ K ПОХОЖИХ ВЫЧИСЛИТЬ НЕИЗВЕСТНЫЕ ДАННЫЕ

    ВЫБРАТЬ N САМЫХ ВЕРОЯТНЫХ Saturday, December 15, 12
  17. МАТЕМАТИЧНО! cos(  u 1 ,  u 2 )

    =  u 1 •  u 2  u 1 ∗  u 2 = u 11 ∗u 21 +...+ u 1n *u 2n u2 11 +...+ u2 1n + u2 21 +...+ u2 2n COSINE MEASURE ПОХОЖЕСТЬ Saturday, December 15, 12
  18. КОСИНУС ТРИГОНОМЕТРИЧНО! Saturday, December 15, 12

  19. USER 1 USER 2 УГОЛ МЕЖДУ ВЕКТОРАМИ - ПОХОЖЕСТЬ Saturday,

    December 15, 12
  20. ПОХОЖЕСТЬ w uv = (r ui − r u )(r

    vi − r v ) (r ui − r u )2 i∈I ∑ (r vi − r v )2 i∈I ∑ i∈I ∑ КОЭФФИЦИЕНТ КОРРЕЛЯЦИИ ПИРСОНА Saturday, December 15, 12
  21. ВОССТАНОВЛЕНИЕ ДАННЫХ ВЗВЕШЕННАЯ СУММА РЕЙТИНГОВ P ai =  r

    a + (r ui −  r u )*w au u∈ U ∑ w au u∈ U ∑ Saturday, December 15, 12
  22. ВОССТАНОВЛЕНИЕ ДАННЫХ СРЕДНИЙ РЕЙТИНГ P ui = r un w

    iu n∈N ∑ w in n∈N ∑ Saturday, December 15, 12
  23. ЮЗЕРЫ Saturday, December 15, 12

  24. РЕПОЗИТОРИИ ЮЗЕРЫ Saturday, December 15, 12

  25. 1 1 1 1 1 1 1 1 1 1

    1 1 РЕПОЗИТОРИИ ЮЗЕРЫ Saturday, December 15, 12
  26. 1 1 1 1 1 1 1 1 1 1

    1 1 РЕПОЗИТОРИИ ЮЗЕРЫ 1 1 USER Saturday, December 15, 12
  27. 1 1 1 1 1 1 1 1 1 1

    1 1 РЕПОЗИТОРИИ ЮЗЕРЫ 0.408 0.353 0.499 0.816 1 1 USER Saturday, December 15, 12
  28. 1 1 1 1 1 1 1 1 1 1

    1 1 РЕПОЗИТОРИИ ЮЗЕРЫ 0.408 0.353 0.499 0.816 1 1 USER Saturday, December 15, 12
  29. 1 1 1 1 1 1 1 1 1 1

    1 1 РЕПОЗИТОРИИ ЮЗЕРЫ 0.408 0.353 0.499 0.816 1 0.23 1 0.53 0.47 ЮЗЕРЫ Saturday, December 15, 12
  30. ПРОБЛЕМЫ РАЗРЯЖЕННОСТЬ ДАННЫХ МАСШТАБИРУЕМОСТЬ СИНОНИМИЧНОСТЬ ДАННЫХ Saturday, December 15, 12

  31. TRICKS AND TIPS ОТСЕИВАНИЕ НЕАКТИВНЫХ ПОЛЬЗОВАТЕЛЕЙ ОБРЕЗАНИЕ ШУМОВ ОБРАТНАЯ ЧАСТОТА

    w' ui = w ui * w ui ρ r' = r *log( f f j ) Saturday, December 15, 12
  32. ОЦЕНКА КАЧЕСТВА MAE = p i, j − r i,

    j i, j ∑ n NMAE = MAE r max − r min RMSE = 1 n (p i, j − r i, j )2 i, j ∑ Saturday, December 15, 12
  33. ИСТОЧНИКИ ДАННЫХ HTTP:/ /WWW.GROUPLENS.ORG/ HTTP:/ /WWW.IEOR.BERKELEY.EDU/~GOLDBERG/JESTER-DATA/ HTTP:/ /WWW.INFORMATIK.UNI-FREIBURG.DE/~CZIEGLER/BX/ HTTP:/ /UCDATA.BERKELEY.EDU:7101/NEW_WEB/VOTEWORLD/VOTEWORLD/DATASETS.HTML

    HTTP:/ /WWW.KSI.MS.MFF.CUNI.CZ/~PETRICEK/DATA/ Saturday, December 15, 12
  34. ДАЕШЬ РЕКОМЕНДАЦИИ! PG PLUGIN GEM ‘RECOMMENDIFY’ MYRRIX APACHE MAHOUT Saturday,

    December 15, 12
  35. ДАЕШЬ РЕКОМЕНДАЦИИ! PG PLUGIN GEM ‘RECOMMENDIFY’ MYRRIX APACHE MAHOUT Saturday,

    December 15, 12
  36. ПРАКТИКА Saturday, December 15, 12

  37. Saturday, December 15, 12

  38. Saturday, December 15, 12

  39. Saturday, December 15, 12

  40. АРХИТЕКТУРНО! Saturday, December 15, 12

  41. 1. FETCHING GITHUB Saturday, December 15, 12

  42. EM::SYNCHRONY EM Synchrony использует возможнсти Fibers для асинхронности Спасибки, @igrigorik

    Saturday, December 15, 12
  43. ЗАГРУЗКА ДАННЫХ require 'em-synchrony' require 'em-synchrony/em-http' require 'em-synchrony/fiber_iterator' class Fetcher

    def fetch_starred_repos users EM.synchrony do EM::Synchrony::FiberIterator.new(users, 10).each do |user| http = EM::HttpRequest.new(user.starred_url).get # store repos # ... end EM.stop end end end Saturday, December 15, 12
  44. 2. РЕКОМЕНДАЦИИ Saturday, December 15, 12

  45. JRUBY & MAHOUT def recommend user_id connection = init_connection model

    = org.apache.mahout.cf.taste.impl.model.jdbc. PostgreSQLJDBCDataModel.new(connection, 'stars', 'user_id', 'repo_id', 'preference', 'created_at') data = org.apache.mahout.cf.taste.impl.model.jdbc. ReloadFromJDBCDataModel.new(model) similarity = org.apache.mahout.cf.taste.impl.similarity. TanimotoCoefficientSimilarity.new(data) neighborhood = org.apache.mahout.cf.taste.impl.neighborhood. NearestNUserNeighborhood.new(5, similarity, data) recommender = org.apache.mahout.cf.taste.impl.recommender. GenericBooleanPrefUserBasedRecommender.new(data, neighborhood, similarity) recommendations = recommender.recommend user_id, 30 update_recommendations connection, recommendations, user_id connection.close end http://goo.gl/dEAp9 JAVA CODE! Saturday, December 15, 12
  46. 3. ИНТЕРФЕЙС Saturday, December 15, 12

  47. WEBSOCKET ..или ~60 строк ruby кода Saturday, December 15, 12

  48. СОХРАНЯЕМ СВЯЗИ class WsServer < EventMachine::WebSocket::Connection @@relations = {} class

    << self def notify(token, message) if channels = @@relations[token] channels.each { |c| c.push message } end end def link(token, channel) @@relations[token] ||= [] @@relations[token] << channel end def unlink(token, channel) @@relations[token].delete(channel) @@relations[token].empty? && @@relations.delete(token) end end end Saturday, December 15, 12
  49. ОПРЕДЕЛЕНИЕ ПОЛЬЗОВАТЕЛЯ class WsServer def initialize(options) super(options) onmessage do |token|

    return if @token token.chomp! @channel = EM::Channel.new @channel.subscribe do |message| send(message) end self.class.link(token, @channel) @token = token end onclose do self.class.unlink(@token, @channel) if @token end end end Saturday, December 15, 12
  50. ДОСТАВКА СООБЩЕНИЙ EventMachine.run do Signal.trap("INT") { EventMachine.stop } Signal.trap("TERM") {

    EventMachine.stop } redis = EM::Hiredis.connect redis.psubscribe('messages:*') redis.on(:pmessage) do |key, channel, message| token = channel[/messages:(.*)/, 1] WsServer.notify(token, message) end EventMachine.start_server('0.0.0.0', 1666, WsServer, {}) end Saturday, December 15, 12
  51. РЕКОМЕНДАТОР def recommend user_id # ... end while array =

    $redis.blpop("recommendations") id = array.last.to_i recommend(id) redis.publish("messages:#{id}", 'iamdone') sleep 0.5 end Saturday, December 15, 12
  52. 4. ЗАПУСКАЕМ! Saturday, December 15, 12

  53. RUNIT gistflow.com/tags/runit Saturday, December 15, 12

  54. http://gitfm.com Более 2000 пользователей и более 80000 stars Saturday, December

    15, 12
  55. http://gitfm.com Ruby JavaScript Python PHP Java Objective-C C C++ Shell

    VimL Perl Clojure CoffeeScript C# Erlang Scala Emacs Lisp Haskell 0 7500 15000 22500 30000 Saturday, December 15, 12
  56. Saturday, December 15, 12

  57. GISTFLOW QUIZ OCTOBOSS STICKER ДЛЯ ПОБЕДИТЕЛЯ MONTH ON CODESCHOOL http://gistflow.com/posts/568

    Saturday, December 15, 12
  58. УЛЫБАЙТЕСЬ :) Saturday, December 15, 12

  59. ВОПРОСЫ? @makaroni4 @releu спрашивайте на gistflow.com Saturday, December 15, 12