Rubyで書くピアソン相関
前回のユークリッド距離に続いて「ピアソン相関によるスコア」です.
ピアソン相関の計算
正しくは,ピアソンの積率相関係数というらしいです.
巻末のp.342にある定義をそのまま実装しました.
sum_xy(x*yの部分和)を求めるのに,zipで書いてあるところがちょっと分かりにくいかもしれません.
なお,sqrtを使うにはMathモジュールが必要です.
お忘れなく.
require 'mathn' include Math module My class Recommender # # 任意の2人のピアソン相関を算出する # def get_pearson_correlation(critics, person1, person2) # 2人が批評している映画を抽出 movies = critics[person1].keys & critics[person2].keys return 0 if movies.empty? # 映画ごとの評価値を得る critics_person1 = movies.map { |movie| critics[person1][movie] } critics_person2 = movies.map { |movie| critics[person2][movie] } get_pearson(critics_person1, critics_person2) end private # # ピアソン相関定義 # def get_pearson(x, y) n = x.size sum_x = x.inject(0) { |sum, i| sum + i } sum_y = y.inject(0) { |sum, i| sum + i } sum_x_square = x.inject(0) { |sum, i| sum + (i ** 2) } sum_y_square = y.inject(0) { |sum, i| sum + (i ** 2) } sum_xy = x.zip(y).inject(0) { |sum, i| sum + (i.first * i.last) } numerator = sum_xy - (sum_x * sum_y.quo(n)) denominator = sqrt((sum_x_square - (sum_x ** 2).quo(n)) * (sum_y_square - (sum_y ** 2).quo(n))) denominator == 0 ? 0 : numerator.quo(denominator) end end end
実行結果
以下のように呼び出す部分を足して,実行してみます.
recommender = My::Recommender.new puts recommender.get_pearson_correlation(critics, 'Lisa Rose', 'Gene Seymour')
いざ,実行!
% ./recommender.rb 0.39605901719067
本文のp.14と同じ結果が得られました.