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を触ってみようと思います。

参考