Mahoutセットアップ
前記事に引き続き、本日連続更新であります!
さて、Mahoutをインストールしましょう。 MahoutはHadoop上で動作する機械学習フレームワークです(たぶん)。 数年前に見つけて以来ずっと興味があったのですがそもそもHadoopがよくわからないレベルだったので ずっと触れずにいました。
という訳で初挑戦です!Let's Try!
Mahoutのダウンロードと展開
本記事執筆時点でのMahoutの最新バージョンは、0.7です。 公式サイトより、 mahout-distribution-0.7.tar.gzをダウンロードしてきました。
Hadoopと違ってこちらはrpmは用意されていないようです。
# pwd /mahout # ls mahout-distribution-0.7.tar.gz # tar zxf mahout-distribution-0.7.tar.gz # ls mahout-distribution-0.7 mahout-distribution-0.7.tar.gz # cd mahout-distribution-0.7 # ls -F LICENSE.txt distribution/ mahout-examples-0.7-job.jar NOTICE.txt docs/ mahout-examples-0.7.jar README.txt examples/ mahout-integration-0.7.jar bin/ integration/ mahout-math-0.7.jar buildtools/ lib/ math/ conf/ mahout-core-0.7-job.jar core/ mahout-core-0.7.jar #
第一印象としてはHadoopとディレクトリ構成似てるな〜というところ。 (本ブログではrpm版を使っていますが、tarball版も使ったことがあるので)
Hadoopの起動
MahoutはHadoop上で動作するということでHadoopを起動しなければ話になりません。
という訳で起動…
# su - hadoop $ /usr/sbin/start-all.sh starting namenode, logging to /var/log/hadoop/hadoop/hadoop-hadoop-namenode-ノード名.out localhost: starting datanode, logging to /var/log/hadoop/hadoop/hadoop-hadoop-datanode-ノード名.out localhost: starting secondarynamenode, logging to /var/log/hadoop/hadoop/hadoop-hadoop-secondarynamenode-ノード名.out starting jobtracker, logging to /var/log/hadoop/hadoop/hadoop-hadoop-jobtracker-ノード名.out localhost: starting tasktracker, logging to /var/log/hadoop/hadoop/hadoop-hadoop-tasktracker-ノード名.out $
とりあえず動かす
本家サイトに掲載されている、Twenty Newsgroupsという例をやってみます。
とりあえずサイトの説明を読むと、Mavenでビルド…とか書いてありますが、今回はビルド済みバイナリをダウンロードしてあるはずなので不要…なはず…
$ cd /mahout/mahout-distribution-0.7 $ ./examples/bin/classify-20newsgroups.sh Please select a number to choose the corresponding task to run 1. cnaivebayes 2. naivebayes 3. sgd 4. clean -- cleans up the work area in /tmp/mahout-work-hadoop Enter your choice :
お、オプション選択を求められました。今回は1を実行してみます。 データのダウンロードが始まり、おもむろにHadoopが動き始めました。 (長いので画面出力は省略)
と、
12/11/21 17:58:53 INFO mapred.JobClient: Task Id : attempt_201211211723_0009_m_000000_0, Status : FAILED java.lang.IllegalArgumentException at com.google.common.base.Preconditions.checkArgument(Preconditions.java:72) at org.apache.mahout.classifier.naivebayes.training.WeightsMapper.setup(WeightsMapper.java:42) at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:142) at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370) at org.apache.hadoop.mapred.Child$4.run(Child.java:255) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Unknown Source) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121) at org.apache.hadoop.mapred.Child.main(Child.java:249) …
がーーーーーーーーーーーん…(←古い)
検索した結果、シングルノード環境では、MAHOUT_LOCAL=TRUEをセットして実行しないといけないらしい。
↓以下のサイトの下から3つ目のコメントに書いてありました… [#MAHOUT-1034] ERROR in Navie Bayes Training(update: seqdirectory does not give output)
ってよく見たらこんな警告も表示されていました。
MAHOUT_LOCAL is not set; adding HADOOP_CONF_DIR to classpath.
よし今度こそ。
$ MAHOUT_LOCAL=TRUE ./examples/bin/classify-20newsgroups.sh Please select a number to choose the corresponding task to run 1. cnaivebayes 2. naivebayes 3. sgd 4. clean -- cleans up the work area in /tmp/mahout-work-hadoop Enter your choice : 1 … SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/util/ProgramDriver at org.apache.mahout.driver.MahoutDriver.main(MahoutDriver.java:96) Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.util.ProgramDriver at java.net.URLClassLoader$1.run(Unknown Source) …
orz
しかしこちらは調べてみるとバグのよう。という訳で、bin/mahoutをバックアップした上で修正してみます。 参考:[#MAHOUT-1044] bin/mahout throws NoClassDefFoundError: org/apache/hadoop/util/ProgramDriver
上記サイトによるとこんな感じです↓
# diff mahout mahout.bk 224c224 < CLASSPATH="${CLASSPATH}:${MAHOUT_HOME}/lib/hadoop/*" --- > CLASSPATH="${CLASSPATH}:${MAHOUT_HOME/lib/hadoop/*}"
さて実行。どきどき。
$ MAHOUT_LOCAL=TRUE ./examples/bin/classify-20newsgroups.sh … 12/11/21 22:34:31 WARN mapred.LocalJobRunner: job_local_0001 java.io.IOException: Mkdirs failed to create file:/mahout/mahout-distribution-0.7/temp/summedObservations/_temporary/_attempt_local_0001_r_000000_0 at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:366) at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:528) at org.apache.hadoop.io.SequenceFile$Writer.(SequenceFile.java:843) at org.apache.hadoop.io.SequenceFile.createWriter(SequenceFile.java:393) at org.apache.hadoop.io.SequenceFile.createWriter(SequenceFile.java:354) at org.apache.hadoop.io.SequenceFile.createWriter(SequenceFile.java:427) at org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat.getRecordWriter(SequenceFileOutputFormat.java:61) at org.apache.hadoop.mapred.ReduceTask$NewTrackingRecordWriter. (ReduceTask.java:569) at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:638) at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:417) at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:260) …
そういえばmahoutのインストールディレクトリをrootで展開したままでした。orz
hadoopという名前のユーザーで実行するようにしているので、 mahoutの一時データを書き出すためのテンポラリーディレクトリを作成できていないようでした。
という訳で、改めてrootにsuしてchownしましょう。
# cd /mahout # ls -lh 合計 70M drwxr-xr-x. 12 root root 4.0K 11月 21 16:05 2012 mahout-distribution-0.7 -rw-r--r--. 1 root root 70M 6月 12 17:52 2012 mahout-distribution-0.7.tar.gz # chown -R hadoop:hadoop mahout-distribution-0.7
何度目かの正直!
$ MAHOUT_LOCAL=TRUE ./examples/bin/classify-20newsgroups.sh … ------------------------------------------------------- Correctly Classified Instances : 6885 90.2359% Incorrectly Classified Instances : 745 9.7641% Total Classified Instances : 7630 ======================================================= Confusion Matrix ------------------------------------------------------- (略) 12/11/21 22:41:54 INFO driver.MahoutDriver: Program took 11052 ms (Minutes: 0.1842)$
Confusion Matrixを見ると感動しますね!!!(←だったら略すな)
動くことは確認できたので今回はここまでにしましょう。 次回はどうしましょうかね。 現在考え中ですが、特に思いつかなければLDAを触ってみようと思います。