Rubyで書くアイテムの推薦
前回は評者の相関まで計算しました.
そこで,この値を使って映画の推薦をしてしまおう,という魂胆です.
推薦値の計算
正直,ちょっと長いです.
もっとすっきり書きたかったんですが,何やってるか分かるでしょうか...
module My class Recommender # # 評価者相関と映画評価の積で一番の映画を推薦する # def get_recommendations(critics, me, user_options = {}) options = { :similarity => 'get_pearson_correlation', }.merge(user_options) # 最初に値を参照した際に、nilで返さないように0で初期化する recommendations = Hash.new(0) similarities = Hash.new(0) (others = critics.keys).delete(me) # other(自分以外)ごとの推薦値を算出する others.each do |other| similarity = send(options[:similarity], critics, me, other) # 逆相関の評価者は推薦に使わない next if similarity <= 0 # 映画の評価値と相関値を掛ける critics[other].each do |movie, critic| recommendations[movie] += (critic * similarity) similarities[movie] += similarity end end # 自分が批評済のものは無駄なので削除 # ただし、評価を0点にしていたものは残す recommendations.delete_if { |movie, critic| critics[me].keys.include?(movie) and critics[me][movie] != 0.0 }.map { |movie, critic| # 相関値の総和で正規化する [movie, critic.quo(similarities[movie])] }.sort_by { |movie, recommendation| recommendation }.reverse end end end
実行結果
以下のように呼び出す部分を足して,実行してみます.
recommender = My::Recommender.new puts recommender.get_recommendations(critics, 'Toby') puts '----------' puts recommender.get_recommendations(critics, 'Toby', { :similarity => 'get_euclidean_similarity' })
いざ,実行!
% ./recommender.rb The Night Listener 3.3477895267131 Lady in the Water 2.83254991826416 Just My Luck 2.53098070376556 ---------- The Night Listener 3.50024784014159 Lady in the Water 2.75612429399594 Just My Luck 2.46198848607437
本文のp.17と同じ結果が得られました.