Rubyで書く相関値順のリスト

これまでに作ったユークリッド距離とピアソン相関を使って,相関値によるリストを作成します.
このリストにより評者のランク付けが可能になります.

ランキングの仕方

やっていることは単純です.
オプションの渡し方だけ注意が必要です.
Rubyでは名前付き引数が無いので,オプションの類はHashで渡すようにします.
受け取ったメソッド内では,デフォルト値をHash#mergeで上書きしています.
オプションで指定されなかった値はデフォルト値が使われるので便利です.

module My
  class Recommender
    #
    # 相関の大きい順のリストを得る
    #
    def top_matches(critics, me, user_options = {})
      options = {
        :similarity => 'get_pearson_correlation',
        :how_many => 5
      }.merge(user_options)

      # 各要素が[相関値,名前]となるリストを作成する
      # ただし.自分自身との相関値は不要なので削除する
      critics.keys.map { |name|
        [send(options[:similarity], critics, me, name), name]
      }.delete_if { |similarity, name|
        name == me
      }.sort.reverse.slice(0...options[:how_many])
    end
  end
end

実行結果

以下のように呼び出す部分を足して,実行してみます.

recommender = My::Recommender.new
puts recommender.top_matches(critics, 'Toby', { :how_many => 3 })

いざ,実行!

% ./recommender.rb
0.99124070716193
Lisa Rose
0.924473451641905
Mick LaSalle
0.893405147441565
Claudia Puig

本文のp.15と同じ結果が得られました.


ちなみに相関値をユークリッド距離に変えると...

puts recommender.top_matches(critics, 'Toby', { :similarity => 'get_euclidean_similarity', :how_many => 3 })
% ./recommender.rb
0.307692307692308
Mick LaSalle
0.285714285714286
Michael Phillips
0.235294117647059
Claudia Puig

とLisa Roseさんは圏外へ...
ピアソン相関とは違う順になります.