Hadoopでレコメンドシステムを作ろう

第5回 レコメンドシステム-協調フィルタリングのHadoopへの実装[後編]

この記事を読むのに必要な時間:およそ 4 分

Hadoop Streamingを使って計算する

コサイン関数の計算に必要なMapperおよびReducerは全て揃いました。各段階でのMapper,Reducerおよび各段階の処理結果を保存するディレクトリを表1のとおりにすると,リスト3のようにHadoop Streamingの実行スクリプトを記述できます。

表1 各段階の処理結果保存ディレクトリ

処理の段階Mapper/ Reducer処理結果を出力
するディレクトリ
第一段Mapper:mapper_for_gihyo_1.plgihyo
Reducer:reducer_for_gihyo_1.pl
第二段Mapper:mapper_for_gihyo_2.plgihyo2
Reducer:reducer_for_gihyo_2.pl
第三段Mapper:mapper_for_gihyo_3.plgihyo3
Reducer:reducer_for_gihyo_3.pl

第一段階の入力データ,Amazonのレビューデータは,この例ではディレクトリamazonにあります。

リスト3 Hadoop Streamingによる計算スクリプト

hadoop dfs -rmr gihyo/;
hadoop jar /opt/hadoop/contrib/streaming/hadoop-*-streaming.jar - D mapred.task.timeo
ut=300000 -input amazon -output gihyo/ -mapper './mapper_for_gihyo_1.pl' -reducer
 './reducer_for_gihyo_1.pl'  -file './mapper_for_gihyo_1.pl' -file './reducer_for_gihy
o_1.pl' -jobconf mapred.reduce.tasks=12;
hadoop dfs -rmr gihyo2/;
hadoop jar /opt/hadoop/contrib/streaming/hadoop-*-streaming.jar - D mapred.task.timeo
ut=300000 -input gihyo/ -output gihyo2/ -mapper './mapper_for_gihyo_2.pl'
 -reducer './reducer_for_gihyo_2.pl' -file './mapper_for_gihyo_2.pl' -file './reducer_for_gihyo_2.pl' ?
jobconf mapred.reduce.tasks=12;
hadoop dfs -rmr gihyo3/;
hadoop jar /opt/hadoop/contrib/streaming/hadoop-*-streaming.jar - D mapred.task.timeo
ut=300000 -input gihyo2/ -output gihyo3/ -mapper './mapper_for_gihyo_3.pl'
 -reducer './reducer_for_gihyo_3.pl' -file './mapper_for_gihyo_3.pl' -file './reducer_for_gihyo_3.pl' ?
jobconf mapred.reduce.tasks=12;

間単にスクリプトの内容を説明します。

  • hadoop jar /opt/hadoop/contrib/streaming/hadoop-*-streaming.jar は,利用しているHadoopのバージョンに合わせて変えてください。
  • -inputでMapperが読み込むデータのあるHDFSのディレクトリを指定します。
  • -outputでReducerがデータを出力するHDFSのディレクトリを指定します。
  • -mapperでMapperとなるスクリプトを指定します。
  • -reducerでReducerとなるスクリプトを指定します。
  • -fileでMapperおよびReducerとなるスクリプトファイルを指定します。
  • -jobconf mapred.reduce.tasks=12でReducerの数を指定します。この例では12としています。

この計算結果をMySQLなどのデータベース,あるいはHBaseに保存することで,レコメンドシステムを実現できます。

処理を短くできないか?

今回の目的は,アイテム相関に基づくレコメンドを実施することでした。このレコメンドでは,基準となるアイテムごとに,他アイテムをアイテム相関の値で高い順にユーザに表示します。今回はそのアイテム相関をコサイン関数を用いて計算していますので,コサイン関数の値が高い順位にアイテムを表示することになります。

ここで,基準となるアイテム(ザスーラ)に対する他のアイテム(ジュマンジ,バトルランナー,はやぶさ)を表示する場合,ザスーラに対する他の映画のコサイン関数による値は図3の通りです。

表2 ⁠ザスーラ」を基準とした各アイテムとアクセスユーザ数

アイテムおよびアイテムペアアクセスユーザ数
ザスーラ3
ジュマンジ2
バトルランナー100
はやぶさ1000
ザスーラ:ジュマンジ2
ザスーラ:バトルランナー2
ザスーラ:はやぶさ2

図3 ⁠ザスーラ」に対するアイテム相関をコサイン関数で表すと

図3 「ザスーラ」に対するアイテム相関をコサイン関数で表すと

これらの値に,基準となるアイテム(ザスーラ)の出現頻度3が共通して含まれていることがわかるでしょうか? これらの値をアクセスユーザ数3の平方根で割る場合,値は変わりますが,値の大小関係は変わりません。したがって,ザスーラと相関の強いアイテムとして,ジュマンジ,バトルランナー,はやぶさの順にユーザに対し推薦することになります。

このため,単にアイテムごとに他のアイテムのランキングを表示するのであれば,コサイン係数でなくこの値を計算するだけなので,二段目のReducerの出力結果だけで十分です。

コサイン関数以外は計算できるか?

もちろん,コサイン関数以外にも他の関数や指標を使って相関および類似度を計算できます。相関や類似度を求めるのに使われる関数や指標には次のようなものがあります。

表3 相関を使う場合に使用される指標の一覧

名称定義
Jaccard係数画像
Dice係数画像
Simpson係数画像
Mutual Information
(相互情報量)
画像

アイテムa, bのアイテムシーケンスをベクトルna,nbと表すと,表3の記号の意味はそれぞれ次の通り。ここではユーザのアイテムアクセスログを想定した表現にとなっています。

  • na*nb
     na,nbの内積。アイテムa, bを両方アクセスしたユーザの数。
  • |na|,|nb|
     na,nbの大きさ。それぞれアイテムa, bをアクセスしたユーザの数の平方根。
  • |na ∩ nb|
     アイテムa, bを両方アクセスしたユーザの数。
  • |na ∪ nb|
     アイテムa, bのどちらかをアクセスしたユーザの数。
  • min(|na|, |nb|)
     na,nbの比較。アイテムa, bをアクセスしたユーザの数のうち小さい方の数を返す。
  • p(na ∩ nb), p(na), p(nb)
     na ∩ nb, na, nbそれぞれの出現確率。

見ておわかりのとおり,これらの関数および指標は共通してnanbのみで構成されています。したがって,コサイン関数を求めるのに使った関数,第三段目のReducerを変更するだけで,これらの関数や指標を計算できます。またReducerの中で同時に複数の関数および指標を計算することもできます。

次回はアイテムベースのレコメンドをコンテンツベースでの実装方法を紹介します。

著者プロフィール

川前徳章(かわまえのりあき)

工学博士,NTTコムウェア 研究開発部 勤務。専門は情報検索,統計的機械学習,マーケティングサイエンス。現在はレコメンドシステムと感性検索の研究と開発に従事。

東京電機大学安田研究室 研究員