stMind

You'll never blog alone

perl de 集合知プログラミング(6.5)

2.7 アイテムベースのフィルタリング

ここではアイテムベースのフィルタリングを実装してみます。アイテムベースの協調フィルタリングでは、あるユーザへ推薦を行う際に、アイテム間の類似度を基に、そのユーザが高く評価しているアイテムと似たアイテムを提示することを行ないます。今回はその準備ということで、アイテム間の類似度のデータセットを作成しました。

アイテム間の類似度のデータセット作成

テスト用のデータセットは、ユーザとユーザが評価している映画とその評価値を含んだものを使います。このデータセットを、アイテム中心な形に変換してアイテム間の類似度を求めます。変換と類似度を算出する部分は、transformPrefsとtopMatchesをそのまま使います。

# 各アイテムに似ているアイテムのリストを作成する
sub calculateSimilarItems {
    my ($prefs, $n, $similarity) = @_;

    # ユーザベースのデータをアイテムベースに入れ替える
    my %itemPrefs = transformPrefs($prefs);

    # リスト作成
    my %result = ();
    my $c = 0;
    foreach my $item (keys %itemPrefs) {
        # 巨大なデータセットのときはステータス表示
        $c += 1;
        if( ($c % 100) == 0 ) {
            printf("%d / %d\n", $c, scalar(keys %itemPrefs));
        }
        # アイテムに似ているアイテムを探す
        my @scores = topMatches(\%itemPrefs, $item, $n, $similarity);
        $result{$item} = \@scores;
    }

    return \%result;
}

これを呼び出して結果を表示する部分。

my $json_file = $ARGV[0] || 'critics.json';
my $critics = conv_json2perl($json_file);

print "Enter num of match items ==> ";
my $n = <STDIN>;
chomp($n);

my $itemSim = calculateSimilarItems($critics, $n, \&sim_distance);

print "Similar items:\n";
foreach my $item (keys %{ $itemSim }) {
    print $item . ":\n";
    for(my $i=0; $i<$n; $i++) {
        foreach my $similar (keys %{ $itemSim->{$item}->[$i] }) {
            print "\t" . $similar . " " . $itemSim->{$item}->[$i]{$similar} . "\n";
        }
    }
}

ハッシュの中にハッシュの配列があってすごくややこしいことになってしまいましたが、これを実行すると以下のようなアイテム間の類似度のデータセットを得ることが出来ます。

Enter num of match items ==> 5
Similar items:
Just My Luck:
	Lady in the Water 0.222222222222222
	You, Me and Dupree 0.181818181818182
	The Night Listener 0.153846153846154
	Snakes on a Plane 0.105263157894737
	Superman Returns 0.0645161290322581
Snakes on a Plane:
	Lady in the Water 0.222222222222222
	The Night Listener 0.181818181818182
	Superman Returns 0.166666666666667
	Just My Luck 0.105263157894737
	You, Me and Dupree 0.0512820512820513
Lady in the Water:
	You, Me and Dupree 0.4
	The Night Listener 0.285714285714286
	Just My Luck 0.222222222222222
	Snakes on a Plane 0.222222222222222
	Superman Returns 0.0909090909090909
Superman Returns:
	Snakes on a Plane 0.166666666666667
	The Night Listener 0.102564102564103
	Lady in the Water 0.0909090909090909
	Just My Luck 0.0645161290322581
	You, Me and Dupree 0.0533333333333333
The Night Listener:
	Lady in the Water 0.285714285714286
	Snakes on a Plane 0.181818181818182
	Just My Luck 0.153846153846154
	You, Me and Dupree 0.148148148148148
	Superman Returns 0.102564102564103
You, Me and Dupree:
	Lady in the Water 0.4
	Just My Luck 0.181818181818182
	The Night Listener 0.148148148148148
	Superman Returns 0.0533333333333333
	Snakes on a Plane 0.0512820512820513

次回は、「2.7.2の推薦を行う」をやってみたいと思います。