10 月 19 2008

[Ruby] 集合知プログラミング 03

Published by haga at 23:44 under ruby

オライリー「集合知プログラミング」のPythonサンプルコードをRubyに翻訳していく作業ログ。3回目。

2.3.4 評者をランキングするのサンプルコードをRuby化

def top_matches( prefs, person, n=5, similarity=:sim_pearson)
  scores = prefs.keys.select{|i| i != person}.map do |other|
    [ method(similarity).call(prefs,person,other), other ]
  end
  return scores.sort.reverse[0...n]
end

p top_matches( critics, 'Toby', 3 )
# => [[0.99124070716193, "Lisa Rose"], [0.924473451641905, "Mick LaSalle"], [0.66284898035987, "Claudia Puig"]]


2.4 アイテムを推薦するのサンプルコードをRuby化

def get_recommendations( prefs, person, similarity=:sim_pearson )
  totals = {}
  sim_sums = {}
  prefs.keys.each do |other|
   
    # 自分自身とは比較しない
    next if other == person
    sim = method(similarity).call( prefs, person, other )
    # 0以下のスコアは無視
    next if sim <= 0
   
    prefs[other].each do |item|
      item_name = item[0]
      # まだ見てない映画の得点のみ算出
      if !prefs[person].key?(item_name) or prefs[person][item_name] == 0
        # 類似度 * スコア
        totals[item_name] ||= 0
        totals[item_name] += prefs[other][item_name] * sim
        # 類似度を合計
        sim_sums[item_name] ||= 0
        sim_sums[item_name] += sim
      end
    end
  end

  # 正規化したリストを作る
  rankings = []
  totals.each do |item_name,total|
    rankings <<[ total / sim_sums[item_name], item_name ]
  end
 
  # ソート済みのリストを返す
  return rankings.sort.reverse
 
end

p get_recommendations( critics, 'Toby' )
# => [[3.27445961524987, "The Night Listener"], [2.95467531335197, "Lady in the Water"], [2.34855517312818, "Just My Luck"]]


引数similarityで、使用する類似性関数を切り替える。Rubyでは

method(:method_name).call


というような形で、シンボルまたは文字列でメソッド名を指定することでメソッドをコールできます。 http://www.ruby-lang.org/ja/man/html/Object.html#method

オリジナルのPythonのサンプルコードではタプルオブジェクトが多用されているが、Rubyでは配列に置き換えている。

Trackback URI | Comments RSS

Leave a Reply