2.4 アイテムを推薦する
今回は、ユーザ間の類似性スコアとアイテム(作品)の評価点を用いて作品をランキング化して提示するサンプルを実装しました。getRecommendationsサブルーチンを追加しました。これまでとほとんど同じで、新たに使ったのはexists関数くらいか。。。データセットを外部から読み込むようにしたりとか新しいことをした方がいいような気がしてきました。
出来たもの
# personへ推薦するアイテムを返す sub getRecommendations { my ($prefs, $person, $similarity) = @_; # ユーザ間の類似性スコアとアイテムの評価点から、対象ユーザが評価していないアイテムの評価値を計算 # 評価値を全ユーザの類似性スコアを合計した値で割った重み付き平均を計算し、値の高い順にソートしてランキングを作成 my %totals = (); my %simSums = (); foreach my $user (keys %$prefs) { next if ($user eq $person); # ユーザ間の類似性スコア算出 my $score; $score = &$similarity($prefs, $person, $user); # 0以下のスコアは無視する next if ($score <= 0); # 対象ユーザが評価していないアイテムについて評価値を計算 foreach my $item (keys %{ $prefs->{$user} }) { if ((not exists $prefs->{$person}->{$item}) || ($prefs->{$person}->{$item} == 0)) { # 評価値 $totals{$item} += $prefs->{$user}->{$item} * $score; # 類似性スコアの合計値 $simSums{$item} += $score; } } } # 重み付き平均の算出 my %li = (); foreach my $item (keys %totals) { $li{$item} = $totals{$item} / $simSums{$item}; } # 値の高い順にソートする my @rankings = (); foreach my $item (sort {$li{$b} <=> $li{$a}} keys %li) { my $h = { $item => $li{$item} }; push(@rankings, $h); } return @rankings; }
ユーザ名を指定すると、推薦するアイテムと指定したユーザのスコアの予想値が表示されます。
Enter person1 ==> Toby Recommendations: The Night Listener : 3.3477895267131 Lady in the Water : 2.83254991826416 Just My Luck : 2.53098070376556
コード置き場
コードはgistにも置いてあります。
gist: 489178 - GitHub