集合知プログラミング 2.3.1をperl化してみた(ユークリッド距離)

ユークリッド距離でAさんとBさんがどれくらい近いか計算するやつ。
pythonでかかれてたのでperl化してみた。

#!/usr/bin/perl -w

use warnings;
use strict;
use Dumpvalue;

my %prefs = (
  '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 Listner'  => 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,
    'You, Me and Dupree' => 3.5,
    'The Night Listner'  => 3.0,
  },
  'Michael Pillips' => {
    'Lady in the Water'  => 2.5,
    'Snakes on a Plane'  => 3.0,
    'Superman Returns'   => 3.5,
    'The Night Listner'  => 4.0,
  },
  'Claudia Puig' => {
    'Snakes on a Plane'  => 3.5,
    'Just My Luck'       => 3.0,
    'The Night Listner'  => 4.5,
    'Superman Returns'   => 4.0,
    'You, Me and Dupree' => 2.5,
  },
  'Mick LaSalle' => {
    'Lady in the Water'  => 3.0,
    'Snakes on a Plane'  => 4.0,
    'Just My Luck'       => 2.0,
    'Superman Returns'   => 3.0,
    'The Night Listner'  => 3.0,
    'You, Me and Dupree' => 2.0,
  },
  'Jack Matthew' => {
    'Lady in the Water'  => 3.0,
    'Snakes on a Plane'  => 4.0,
    'The Night Listner'  => 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,
  },
);

# euclid distance
sub sim_distance {
  my($user1, $user2) = @_;
  my %si = ();
  
  # 両者が互いに評価しているアイテムのリストを取得
  foreach my $key(keys(%{$prefs{$user1}})) {
    if ($prefs{$user2}{$key}) {
      $si{$key} = 1;
    }
  }
  # 要素の数
  my $n = keys %si;
  if ($n == 0) {
    die('not mutched.');
  }
  
  # 全ての差の平方を加算
  my $sum_of_squares = 0;
  while (my($key,$val) = each(%{$prefs{$user1}})) {
    if ($prefs{$user2}{$key}) {
      $sum_of_squares += ($val - $prefs{$user2}{$key}) * ($val - $prefs{$user2}{$key});
    }
  }
  
  return(1/(1+$sum_of_squares));
}

print sim_distance('Lisa Rose', 'Gene Seymour');

1;

こんな感じ。
というかコピペと殆どかわらんw


・出力結果

0.148148148148148