2章 その2

p.11より、2人の全ての映画評価から類似性を計算する

pythonのsum関数は、配列を渡すと要素が数値だったら全て足して結果を返すらしい)
recommendation.rbにsim_distance関数を追加

class Critics
  
  # Person1とperson2の距離を基にした類似性スコアを返す
  def sim_distance(prefs, person1, person2)
    # 2人とも評価しているアイテムのリストを得る
    si = { }
    prefs[person1].keys.each{ |item|
      puts item
      si[item] = 1 if prefs[person2].key?(item)
    }
    
    # 両者ともに評価しているものが1つもなければ0を返す
    return 0 if si.length == 0
    
    # すべての差の平方を足し合わせる
    sum_of_squares = 0
    prefs[person1].keys.each{ |item|
      if prefs[person2].key?(item)
        p1 = prefs[person1][item]
        p2 = prefs[person2][item]
        sum_of_squares = sum_of_squares + (p1-p2)*(p1-p2)
      end
    }
    
    return 1/(1+sum_of_squares)
  end
  
  def users
    return @users
  end
  
  def initialize
    @users = { 
      'Lisa Rose' => {
        'Lady in the Water' => 2.5,
        'Snake on a Plane' => 3.5,
        'Just My Luck' => 3.0,
        'Superman Returns' => 3.5,
        'You, Me and Dupree' => 2.5,
        'The Night Listener'=>3.0
      },
      'Gene Seymour' => { 
        'Lady in the Water' => 3.0,
        'Snake on a Plane' => 3.5,
        'Just My Luck' => 1.5,
        'Superman Returns' => 5.0,
        'The Night Listener' => 3.0,
        'You, Me and Dupree' => 3.5
      },
      'Michael Phillips' => { 
        'Lady in the Water' => 2.5,
        'Snake on a Plane' => 3.0,
        'Superman Returns' => 3.5,
        'The Night Listener' => 4.0
      },
      'Claudia Puig' => { 
        'Snake on a Plane' => 3.5,
        'Just My Luck' => 3.0,
        'The Night Listener' => 4.5,
        'Superman Returns' => 4.0,
        'You, Me and Dupree' => 2.5
      },
      'Mick LaSalle' => { 
        'Lady in the Water' => 3.0,
        'Snake on a Plane' => 4.0,
        'Just My Luck' => 2.0,
        'Superman Returns' => 3.0,
        'The Night Listener' => 3.0,
        'You, Me and Dupree' => 2.0
      },
      'Jack Matthews' => { 
        'Lady in the Water' => 3.0,
        'Snake on a Plane' =>4.0,
        'The Night Listener' => 3.0,
        'Superman Returns' => 5.0,
        'You, Me and Dupree' => 3.5
      },
      'Toby' => { 
        'Snake on a Plane' => 4.5,
        'You, Me and Dupree' => 1.0,
        'Superman Returns' => 4.0
      }
    }
  end
  
end


p.11より、LisaとGeneの相関を計算する
irb -r recommendations.rb

>> c = Critics.new
=> #<Critics:0x69ea9c @users={"Jack Matthews"=>{"The Night Listener"=>3.0, "Superman Returns"=>5.0, "Lady in the Water"=>3.0, "Snake on a Plane"=>4.0, "You, Me and Dupree"=>3.5}, "Gene Seymour"=>{"The Night Listener"=>3.0, "Superman Returns"=>5.0, "Lady in the Water"=>3.0, "Snake on a Plane"=>3.5, "You, Me and Dupree"=>3.5, "Just My Luck"=>1.5}, "Mick LaSalle"=>{"The Night Listener"=>3.0, "Superman Returns"=>3.0, "Lady in the Water"=>3.0, "Snake on a Plane"=>4.0, "You, Me and Dupree"=>2.0, "Just My Luck"=>2.0}, "Toby"=>{"Superman Returns"=>4.0, "Snake on a Plane"=>4.5, "You, Me and Dupree"=>1.0}, "Claudia Puig"=>{"The Night Listener"=>4.5, "Superman Returns"=>4.0, "Snake on a Plane"=>3.5, "You, Me and Dupree"=>2.5, "Just My Luck"=>3.0}, "Lisa Rose"=>{"The Night Listener"=>3.0, "Superman Returns"=>3.5, "Lady in the Water"=>2.5, "Snake on a Plane"=>3.5, "You, Me and Dupree"=>2.5, "Just My Luck"=>3.0}, "Michael Phillips"=>{"The Night Listener"=>4.0, "Superman Returns"=>3.5, "Lady in the Water"=>2.5, "Snake on a Plane"=>3.0}}>
>> c.sim_distance(c.users, 'Lisa Rose', 'Gene Seymour')
=> 0.148148148148148