ようやく協調フィルタリングに再挑戦できる状況に。
Pythonで変換した入力ファイルをHDFSにputして「Item-Based Recommendations」を実行。
$ hadoop fs -put ldgourmet_ratings_for_ibr2.csv ldgourmet $ mahout recommenditembased -s SIMILARITY_LOGLIKELIHOOD -i ldgourmet/ldgourmet_ratings_for_ibr2.csv -o ldgourmet/output --numRecommendations 3 MAHOUT_LOCAL is not set; adding HADOOP_CONF_DIR to classpath. Running on hadoop, using /usr/lib/hadoop/bin/hadoop and HADOOP_CONF_DIR=/etc/hadoop/conf MAHOUT-JOB: /usr/lib/mahout/mahout-examples-0.9-cdh5.3.1-job.jar 15/03/17 23:07:52 INFO common.AbstractJob: Command line arguments: {--booleanData=[false], --endPhase=[2147483647], --input=[ldgourmet/ldgourmet_ratings_for_ibr2.csv], --maxPrefsInItemSimilarity=[500], --maxPrefsPerUser=[10], --maxSimilaritiesPerItem=[100], --minPrefsPerUser=[1], --numRecommendations=[3], --output=[ldgourmet/output], --similarityClassname=[SIMILARITY_LOGLIKELIHOOD], --startPhase=[0], --tempDir=[temp]} 15/03/17 23:07:52 INFO common.AbstractJob: Command line arguments: {--booleanData=[false], --endPhase=[2147483647], --input=[ldgourmet/ldgourmet_ratings_for_ibr2.csv], --minPrefsPerUser=[1], --output=[temp/preparePreferenceMatrix], --ratingShift=[0.0], --startPhase=[0], --tempDir=[temp]} 15/03/17 23:07:53 INFO Configuration.deprecation: mapred.input.dir is deprecated. Instead, use mapreduce.input.fileinputformat.inputdir 15/03/17 23:07:53 INFO Configuration.deprecation: mapred.compress.map.output is deprecated. Instead, use mapreduce.map.output.compress 15/03/17 23:07:53 INFO Configuration.deprecation: mapred.output.dir is deprecated. Instead, use mapreduce.output.fileoutputformat.outputdir 15/03/17 23:07:54 INFO client.RMProxy: Connecting to ResourceManager at /0.0.0.0:8032 15/03/17 23:07:55 WARN security.UserGroupInformation: PriviledgedActionException as:take (auth:SIMPLE) cause:org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory temp/preparePreferenceMatrix/itemIDIndex already exists Exception in thread "main" org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory temp/preparePreferenceMatrix/itemIDIndex already exists at org.apache.hadoop.mapreduce.lib.output.FileOutputFormat.checkOutputSpecs(FileOutputFormat.java:146) at org.apache.hadoop.mapreduce.JobSubmitter.checkSpecs(JobSubmitter.java:554) at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:430) at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1295) at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1292) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:415) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1642) at org.apache.hadoop.mapreduce.Job.submit(Job.java:1292) at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1313) at org.apache.mahout.cf.taste.hadoop.preparation.PreparePreferenceMatrixJob.run(PreparePreferenceMatrixJob.java:77) at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70) at org.apache.mahout.cf.taste.hadoop.item.RecommenderJob.run(RecommenderJob.java:164) at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70) at org.apache.mahout.cf.taste.hadoop.item.RecommenderJob.main(RecommenderJob.java:322) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.hadoop.util.ProgramDriver$ProgramDescription.invoke(ProgramDriver.java:72) at org.apache.hadoop.util.ProgramDriver.run(ProgramDriver.java:145) at org.apache.hadoop.util.ProgramDriver.driver(ProgramDriver.java:153) at org.apache.mahout.driver.MahoutDriver.main(MahoutDriver.java:195) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.hadoop.util.RunJar.main(RunJar.java:212)
あれ、、、またエラーに。
今度は中間データと思われるファイルの出力先が既に存在している、と。
恐らく前回エラーになったときに残ったのだと思われるが、それにしても指定したパス以外に勝手にディレクトリを作っておいて、残したままにしておくとは。もうちょっと後処理ちゃんとせえよ…。
とぼやいていても仕方ないのでディレクトリを消して再度。
$ hadoop fs -rmr temp/preparePreferenceMatrix $ mahout recommenditembased -s SIMILARITY_LOGLIKELIHOOD -i ldgourmet/ldgourmet_ratings_for_ibr2.csv -o ldgourmet/output --numRecommendations 3 (省略) 15/03/17 23:18:37 INFO driver.MahoutDriver: Program took 347306 ms (Minutes: 5.788433333333334)
MapReduceが9回ほど動いて5分ちょいで無事終了。
出力データの中身を見てみる。
$ hadoop fs -ls ldgourmet/output Found 2 items -rw-r--r-- 1 take supergroup 0 2015-03-17 23:18 ldgourmet/output/_SUCCESS -rw-r--r-- 1 take supergroup 245633 2015-03-17 23:18 ldgourmet/output/part-r-00000 $ hadoop fs -tail ldgourmet/output/part-r-00000 9923823] 4278205127 [1050:4.0119233,138:4.007087,586:4.007003] 4278971698 [277:1.0,1637:1.0] 4279952571 [6645:2.50514,581:1.0,4244:1.0] 4281265025 [311518:4.0,370162:4.0,332770:4.0] 4281634113 [300933:4.4904943,335499:4.0,373547:4.0] 4281870486 [11824:4.500969,21348:4.488718,3729:4.487594] 4282442439 [2358:4.0,313:4.0] 4282703212 [384403:4.2505198,334805:4.20008,380188:4.20008] 4283170779 [7910:5.0,8796:5.0] 4283926049 [12555:4.4908667] 4284165778 [8728:5.0,2701:5.0,2302:5.0] 4285085889 [300933:5.0,301515:5.0,323026:4.673149] 4288106213 [406041:4.0870314,396687:4.087023,359265:4.083425] 4288708981 [2945:4.504145,4365:4.502466,8206:4.502196] 4289424931 [2297:5.0,11250:4.5070863,20130:4.498961] 4289532598 [308708:5.0,300489:5.0,308715:5.0] 4291952257 [5343:4.0,5433:4.0,2044:4.0] 4291973773 [2855:5.0,891:5.0,3574:5.0] 4292027381 [352331:4.0,374319:4.0,341967:4.0] 4292733388 [3240:4.514431,10312:4.4899635,20040:4.0136404] 4293060625 [4836:5.0,25064:5.0,3074:5.0] 4294950334 [7207:4.494212,6595:4.493965,12624:4.0]
それっぽく出ている感じ。
データはユーザーIDに対しておすすめレストランのIDと点数のセットが3つ(パラメータで3つレコメンドするようにしたので)出ているよう。元の評価データが5点満点だからか見た感じ5点満点で点数が出ている。
ちょっと気になるのは、3つとも満点で出ているユーザーが結構いること。そんなにお勧めなのか、あるいは自分が評価して満点を付けたレストランが出ているのか。
試しに元データを追ってみる。
$ grep 4293060625 ldgourmet_ratings_for_ibr2.csv 4293060625,433,5 4293060625,6839,5 4293060625,302354,5 $ grep 4291973773 ldgourmet_ratings_for_ibr2.csv 4291973773,4243,4 4291973773,6404,5 4291973773,6925,5 4291973773,11719,4 4291973773,13890,5 4291973773,17502,4 4291973773,19616,3
どうやら、自分が評価したのとは違うレストランがちゃんと選ばれている様子。
ほんとに適切なレコメンドがされているのか気になるが、今日はここまで。
次回、レコメンド結果を定性的に評価してみよ。