Slide 1

Slide 1 text

Ruby 與推薦系統

Slide 2

Slide 2 text

About me tka http://twitter.com/tkalu http://blog.tka.lu 任職於 Handlino.com

Slide 3

Slide 3 text

Ruby 與推薦系統

Slide 4

Slide 4 text

推薦系統 from Amazon.com

Slide 5

Slide 5 text

推薦系統 from icook.tw

Slide 6

Slide 6 text

推薦系統 from www.books.com.tw

Slide 7

Slide 7 text

傳說中的實作方式 ● 亂數 ● 庫存最多的 ● 利潤最高的

Slide 8

Slide 8 text

推薦系統的分類 ● Content based ● Collaborative Filtering – Item Based – User Based

Slide 9

Slide 9 text

會講的內容 ● Ruby 建立簡易 Collaborative Filtering 推薦系統的方式 – 使用 Recommendify – 使用 Recommendable – 使用 JRuby + Mahout

Slide 10

Slide 10 text

不會講的內容 ● Content based 推薦系統 ● 推薦系統裡面的演算法細節 ● Apache Mahout 的調整與分散運算

Slide 11

Slide 11 text

取得大量測試資料 ● GroupLens – http://grouplens.org ● MovieLens – http://www.movielens.org/ ● MovieLens Data Sets – http://grouplens.org/node/12 – MovieLens 1M - Consists of 1 million ratings from 6000 users on 4000 movies.

Slide 12

Slide 12 text

測試專案 ● https://github.com/tka/recommender-demo – rails 4 – recommendify & recommendable 範例 ● https://github.com/tka/jruby-mahout-demo – JRuby 搭配 Mahout – user based, Item based, MySQL 串接範例

Slide 13

Slide 13 text

Ruby Library 介紹

Slide 14

Slide 14 text

Recommendify 簡介 ● https://github.com/paulasmuth/recommen dify ● Item based ● jaccard similarity ● 從指定的 Item 取得推薦的 Item

Slide 15

Slide 15 text

Recommendify 使用方式 class MyRecommendify < Recommendify::Base max_neighbors 10 input_matrix :movie_items, :native => true, :similarity_func => :jaccard, :weight => 5.0 end recommender.movie_items.add_set("order1", ["movie23", "movie65"]) recommender.movie_items.add_set("order2", ["movie14", "movie23"]) recommender.process! recommender.process_item!("movie23") recommender.for("product23")

Slide 16

Slide 16 text

Recommendify 缺點 ● Item 之間的關係有所異動時 , 需要重新將資料倒 入 redis 內 , 例如某個使用者多 like 了一部電 影 , 這時後就需要重新把所有的資料倒入 redis 後才能算出新的結果 ● MovieLens 1M 的資料在 i5 2.5GHz 的機器上 倒入 redis 約需 40 分鐘 , 從 redis 的資料算出 所有推薦內容大約需 90 秒

Slide 17

Slide 17 text

Recommendable 簡介 ● https://github.com/davidcelis/recommend able ● User based ● jaccard similarity ● 可直接搭配 ActiveRecord 使用 ● 從指定的 User 取得推薦 Item ● 從指定的 User 取得相似的 User

Slide 18

Slide 18 text

Recommendable 使用方式 class User < ActiveRecord::Base belongs_to :occupation has_many :ratings has_many :movies, through: :ratings recommends :movies end user.like( Movie.where(:name => "Toy Story (1995)").first ) Recommendable::Helpers::Calculations.update_similarities_for(user.id) Recommendable::Helpers::Calculations.update_recommendations_for(user.id) user.similar_raters user.recommended_movies

Slide 19

Slide 19 text

Recommendable 缺點 ● 只有 User 觸發 like/dislike 之類的事件時會 更新該 User 的推薦 Item – 需自行呼叫函式更新特定 User 的推薦資料方能確保 資料準確 ● 第一次倒 MovieLens 1M 到 redis 需 25min, 且有異動時不須重倒 , 但是更新一個 User 的推薦資料需要 50 秒左右

Slide 20

Slide 20 text

JRuby +Mahout 介紹

Slide 21

Slide 21 text

Mahout 簡介 ● http://mahout.apache.org/ ● Java 實作 ● 支援許多演算法 ● 可搭配 hadoop 進行分散式運算

Slide 22

Slide 22 text

JRuby-Mahout 簡介 ● https://github.com/vasinov/jruby_mahout ● 只支援 Mahout 推薦系統功能中的部份功能 ● 還在早期開發階段 , 缺少文件 ● 實作了 PostgreSQL 直接串接 , 但是 MySQL 串接尚未實作

Slide 23

Slide 23 text

JRuby-Mahout 簡介 ● https://github.com/vasinov/jruby_mahout ● 支援多種演算法 ● 可從指定的 Item 取得推薦 Item ● 可從指定的 User 取得推薦 Item ● 可從指定的 User 取得相似 User

Slide 24

Slide 24 text

JRuby-Mahout 使用方式 recommender = JrubyMahout::Recommender.new( "TanimotoCoefficientSimilarity", 5, "GenericUserBasedRecommender", false) recommender.data_model = JrubyMahout::DataModel.new("file", { :file_path => "ratings.csv" }).data_model recommender.recommend(2, 10, nil) 以 User Based 模式計算 MovieLens 1M 中所針對 User 推薦的 Item 約費時 8 分鐘 以 Item Based 模式計算 MovieLens 1M 中所針對 Item 推薦的 Item 約費時 50 秒

Slide 25

Slide 25 text

JRuby-Mahout 串接 MySQL 範例 dataSource = com.mysql.jdbc.jdbc2.optional.MysqlDataSource.new; dataSource.setServerName("127.0.0.1"); dataSource.setUser("user"); dataSource.setPassword("password"); dataSource.setDatabaseName("recommender-demo_development"); dataModel = org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel.new( dataSource, "ratings", "user_id", "movie_id", "rate", "created_at"); recommender = JrubyMahout::Recommender.new("LogLikelihoodSimilarity", 5, "GenericUserBasedRecommender", false) recommender.data_model = dataModel

Slide 26

Slide 26 text

JRuby-Mahout 缺點 ● 還在早期開發階段 , 缺少文件 ● 需要 Java ● 需要較多 Mahout 知識配合 ● 需自行規劃與 Rails 的整合 ● 實作了 PostgreSQL 串接 , 但是 MySQL 串接尚未 實作 ● 使用 MySQL 直接串接時計算速度會慢約 500 倍

Slide 27

Slide 27 text

結論

Slide 28

Slide 28 text

Q&A