Rubyで書く似ている製品探し

これまで,評価者をキーとしたデータセットを使って計算をしてきましたが,
アイテム(この場合は映画)をキーとした相関を知ることはできるでしょうか.
この点に注目したのが「似ている製品」の章です.

アイテムをキーにした評価データへの変換

元のデータがvalueにHashを含むHashになっているので,ちょっと面倒です.
データ構造にHash使わなきゃいいんじゃねえかという気もしてきました.

module My
  class Recommender
    #
    # criticsを映画名をキーにしたハッシュに変換
    #
    def invert(critics)
      # HashのvalueにHashを持たせて初期化する
      inverted_critics = Hash.new({})

      critics.each do |person, movies|
        movies.each do |movie, critic|
          inverted_critics[movie] = inverted_critics[movie].merge({ person => critic })
        end
      end
      inverted_critics
    end
  end
end

実行結果

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

recommender = My::Recommender.new
movies = recommender.invert(critics)
puts recommender.top_matches(movies, 'Superman Returns')

いざ,実行!

% ./recommender.rb
0.657951694959769
You, Me and Dupree
0.487950036474269
Lady in the Water
0.111803398874989
Snakes on a Plane
-0.179847194799054
The Night Listener
-0.422890031611031
Just My Luck

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


また,

puts recommender.get_recommendations(movies, 'Just My Luck')

とすると...

% ./recommender.rb
Michael Phillips
4.0
Jack Matthews
3.0

こちらも本文通りの結果が得られます.