集合知プログラミング 2.3.3 マンハッタン距離

集合知プログラミング

集合知プログラミング

この本では類似性尺度の求め方に、ユーグリッド距離とピアソン相関以外にマンハッタン距離が紹介されていました。
今回はRubyで挑戦してみました。

集合知プログラミング 2章 その3 マンハッタン距離
http://d.hatena.ne.jp/ksmemo/20080802/p1

集合知プログラミング』を Ruby
http://d.hatena.ne.jp/mrkn/20080722

今回はこちらの2つを参考にしました。


ファイル名は"recommendations.rb"としました。
こちらは2.2のデータセットです。

# 映画の評者といくつかの映画に対する彼らの評点のディクショナリ
$critics = {
  'Lisa Rose' => {
    'Lady in the Water' => 2.5,
    'Snakes 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,
    'Snakes 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,
    'Snakes on a Plane' => 3.0,
    'Superman Returns' => 3.5,
    'The Night Listener' => 4.0,
  },
  'Claudia Puig' => {
    'Snakes 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 LaSsumse' => {
    'Lady in the Water' => 3.0,
    'Snakes 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,
    'Snakes on a Plane' => 4.0,
    'The Night Listener' => 3.0,
    'Superman Returns' => 5.0,
    'You, Me and Dupree' => 3.5,
  },
  'Toby' => {
    'Snakes on a Plane' => 4.5,
    'You, Me and Dupree' => 1.0,
    'Superman Returns' => 4.0,
  },
}

続いて、マンハッタン距離を求めるプログラムです。

#マンハッタン距離
module Recommendations
  def self.sim_manhattan(prefs, p1, p2)
    # 両者が互いに評価しているアイテムのリストを得る
    si = prefs[p1].keys & prefs[p2].keys
    
    # 共に評価しているアイテムがなければ0を返す
    if si.empty?
      return 0.0 
    end
    
    #各座標の差(の絶対値)の総和をだす
    sum_of_abs = si.inject(0.0) {|sums, it| sums += (prefs[p1][it] - prefs[p2][it]).abs}
    
    manh = 1 / (1 + sum_of_abs)
    
    return manh 
  end
end


実行はirbを使います。

$ irb
irb(main):001:0> load 'recommendations.rb'
=> true
irb(main):002:0> Recommendations.sim_manhattan($critics, 'Lisa Rose', 'Gene Seymour')
=> 0.181818181818182

とりあえず数値はあっているようなのでよかったです。