集合知プログラミング 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