MeCab Ruby と CaboCha Ruby をインストールしてみた
機械学習も統計もあまり勉強進んでいませんゴメンナサイ。
ちょっとそのきっかけ作り(という名目の個人的な実験)のために、形態素解析とか日本語係り受け解析とかを試してみることにしました。
個人的な理由のために Ruby からの利用を前提として。
MeCab と MeCab Ruby のインストール
最初は「形態素解析」というものに触れてみようということで、 MeCab をインストール。
技術ブログでは「失敗したログも含めて全部記録する」のが定石なんですが、めんどくさいし個人的には成功例と「なぜそれで成功したのか(なぜ失敗を回避できたか)」が分かれば良いと思うのでその方針で書きます。
ちなみに環境は、Mac OSX Lion 10.7.4 です。
インストールしたのは以下の通り:
まずは MeCab 本体。最新のtar ballをDLして以下の要領でインストール。
$ tar xzvf mecab-0.994.tar.gz $ cd mecab-0.994 $ ./configure --enable-utf8-only $ make $ sudo make install
ポイントは以下の通り:
./configure
時に「--enable-utf8-only
」オプションを付加。Ruby 1.9 で UTF-8 での使用しか想定していないので。またこうするとeucやsjisの変換テーブルを埋め込まず実行バイナリを小さく出来ると言うことなので*1。
これはすんなり完了。
続いて辞書のインストール。
$ tar xzvf mecab-ipadic-2.7.0-20070801.tar.gz $ cd mecab-ipadic-2.7.0-20070801 $ ./configure --with-charset=utf8 $ make $ sudo make install
ポイント:
こちらもすんなり。なんだMeCabてばインストール簡単じゃん。
早速実験。sumomo.txt は utf-8 のテキストファイルです。
$ cat sumomo.txt すもももももももものうち $ mecab sumomo.txt すもも 名詞,一般,*,*,*,*,すもも,スモモ,スモモ も 助詞,係助詞,*,*,*,*,も,モ,モ もも 名詞,一般,*,*,*,*,もも,モモ,モモ も 助詞,係助詞,*,*,*,*,も,モ,モ もも 名詞,一般,*,*,*,*,もも,モモ,モモ の 助詞,連体化,*,*,*,*,の,ノ,ノ うち 名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ EOS
OK。
では続いて Ruby で直接いじれるようにするためのモジュールをインストール。Downloads - mecab - Japanese morphological analyzer - Google Project Hostingから最新のモジュールのtar ballをDLして、以下の要領でインストール。
$ tar xzvf mecab-ruby-0.994.tar.gz $ cd mecab-ruby-0.994 $ ruby extconf.rb $ make $ sudo make install $ ruby test.rb 《実行結果省略》
こちらは何も難しいことはないですね。
当然のことながら、今実行している ruby に新しいモジュールとしてインストールされるので、rvmやrbenv等で複数バージョンを管理しているなら、必要なバージョンのRubyごとにインストールしないといけません。rvmなら、専用のgemsetを作ってからインストール、っていう方法も良いかも。私はめんどくさいので素の(普段使用している)Ruby だけにインストールしました。
簡単に実行確認。
[1] 1.9.3-p125(main)> require 'MeCab' => true [2] 1.9.3-p125(main)> sentence = "\u592a\u90ce\u306f\u3053\u306e\u672c\u3092\u4e8c\u90ce\u3092\u898b\u305f\u5973\u6027\u306b\u6e21\u3057\u305f\u3002" => "太郎はこの本を二郎を見た女性に渡した。" [3] 1.9.3-p125(main)> mecab = MeCab::Tagger.new => #<MeCab::Tagger:0x007f885c18ae20 @__swigtype__="_p_MeCab__Tagger"> [4] 1.9.3-p125(main)> puts mecab.parse sentence 太郎 名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー は 助詞,係助詞,*,*,*,*,は,ハ,ワ この 連体詞,*,*,*,*,*,この,コノ,コノ 本 名詞,一般,*,*,*,*,本,ホン,ホン を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 二 名詞,数,*,*,*,*,二,ニ,ニ 郎 名詞,一般,*,*,*,*,郎,ロウ,ロー を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 見 動詞,自立,*,*,一段,連用形,見る,ミ,ミ た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ 女性 名詞,一般,*,*,*,*,女性,ジョセイ,ジョセイ に 助詞,格助詞,一般,*,*,*,に,ニ,ニ 渡し 動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ 。 記号,句点,*,*,*,*,。,。,。 EOS => nil
内容については、ここでは深く突っ込みません。
CaboCha のインストール
つづいて CaboCha 。こちらは「日本語係り受け解析器」。
実は MeCab の存在は以前から知っていて、それでちょっと試したんですが、「結局これ、単語(正確には形態素)の分割は出来るけれど、これだけだと係り受けは分かんないじゃん」てことに気付いて(私がやりたかったことがそっちだったことに気付いて)、後から探して見付けてインストールしたのが CaboCha 、だったりします。
インストールしたのは以下の通り:
なお他に、MeCab がインストールされていることが前提です。
まずは CRF++。
$ tar xzvf CRF++-0.57.tar.gz $ cd CRF++-0.57 $ ./configure $ make $ sudo make install
インストールそのものは問題なし。一応、ポイント:
- CaboCha のインストールをまとめたサイトで、よく「CRF++ を一番最初に(MeCab より前に)インストールする」、と記述があります( 日本語係り受け解析器 CaboCha Ruby 拡張の基本的な使い方とちょっとした応用 - デー等)が、CaboChaの動作に必要なモノなので、今回のように MeCab の後 CaboCha の前でも大丈夫なようです。
続いて CaboCha。MeCab のインストールの時に言及した通り、成功例だけ示します。
$ tar xzvf cabocha-0.64.tar.gz $ cd cabocha-0.64 $ LIBS=-liconv ./configure --with-charset=utf8 $ make $ sudo make install
ポイントは以下の通り:
./configure
時に「--with-charset=utf8
」オプションを付加。Ruby 1.9 で UTF-8 での使用しか想定していないので。- そのまま ./configure すると、iconv 周りで「
ld: symbol(s) not found for architecture x86_64
」というエラーになって落ちてしまいます(実際落ちました)。対処法として調べてみたところ:- 「homebrewでlibiconvをインストール(Mac OS X 10.7 (Lion)へのcabochaのインストール - 犬ぶよツールズ制作記録等)」→homebrew 以外でインストールしているパッケージが色々あったので移行がめんどくさかったので今回は不採用。
- 「LIBS=-liconv(MacOSX10.6 にCaboCha0.60pre4をインストールとPythonバインディング - Do not forget this.)」→つまりliconvを無効に。手っ取り早いのでこちらを採用。今のところ動作に問題なし。
取り敢えず動作確認。
$ cat sumomo.txt すもももももももものうち $ cabocha sumomo.txt すももも-D ももも---D ももの-D うち EOS
…例が悪かったですねw これじゃ何が起きているかよく分からない。別の例。
$ cabocha 私が「あなたは右の道から来ましたか?」と質問したら、あなたは「はい」と答えますか? 私が---------D 「あなたは-----D | 右の-D | | 道から-D | 来ましたか?」と-D 質問したら、-----D あなたは---D 「はい」と-D 答えますか? EOS
複文、係り受け、きちんと解析できてますね。素晴らしい(^-^)
CaboCha Ruby のインストール
続いて CaboCha Ruby。
MeCab には Ruby で直接利用するためのラッパーモジュールが用意されていましたが、CaboCha は自分で用意する必要があります。といってもSWIG (Simplified Wrapper and Interface Generator)というツールを使って簡単にラッパーモジュールを作れるようになっている*2ので、ありがたくそれを利用します。
ということで、さらに以下をインストール:
$ tar xjvf pcre-8.31.tar.bz2 $ cd pcre-8.31 $ ./configure $ make $ sudo make install
$ tar xzvf swig-2.0.7.tar.gz $ cd swig-2.0.7 $ ./configure $ make $ sudo make install
ポイント:
- そのまま SWIG をインストールしようとすると、./configure で pcre がないと怒られたので、PCRE の最新を探してきて先にインストール。予め何かの目的で PCRE を入れてあれば不要かも。
さて、では CaboCha の Ruby 用のモジュールを作ってインストール。
$ cd cabocha-0.64/swig $ make ruby $ cd ../ruby/ $ ruby extconf.rb $ make $ sudo make install
ポイント:
- SWIG が入ってないと、
make ruby
の時点で「swig: No such file or directory」のエラーになります。 ruby extconf.rb
以降は、MaCab Ruby と同じ手順ですね。
さてテストですが、用意されている test.rb が Ruby 1.9 だと 正常に動作しません。文字コード指定のマジックコメントが必要です。
$ vi test.rb #!/usr/bin/ruby # -*- coding: utf-8 -*- # ↑この1行を追記 require 'CaboCha' sentence = "太郎はこの本を二郎を見た女性に渡した。" 《以下略》
で、test.rb 実行。
$ ruby test.rb <PERSON>太郎</PERSON>は-----------D この-D | 本を---D | 二郎を-D | 見た-D | 女性に-D 渡した。 EOS <PERSON>太郎</PERSON>は-----------D この-D | 本を---D | 二郎を-D | 見た-D | 女性に-D 渡した。 EOS * 0 6D 0/1 2.909358 太郎 名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー B-PERSON は 助詞,係助詞,*,*,*,*,は,ハ,ワ O * 1 2D 0/0 1.257926 この 連体詞,*,*,*,*,*,この,コノ,コノ O * 2 4D 0/1 0.638994 本 名詞,一般,*,*,*,*,本,ホン,ホン O を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ O * 3 4D 1/2 1.696047 二 名詞,数,*,*,*,*,二,ニ,ニ O 郎 名詞,一般,*,*,*,*,郎,ロウ,ロー O を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ O * 4 5D 0/1 0.000000 見 動詞,自立,*,*,一段,連用形,見る,ミ,ミ O た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ O * 5 6D 0/1 0.000000 女性 名詞,一般,*,*,*,*,女性,ジョセイ,ジョセイ O に 助詞,格助詞,一般,*,*,*,に,ニ,ニ O * 6 -1D 0/1 0.000000 渡し 動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ O た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ O 。 記号,句点,*,*,*,*,。,。,。 O EOS
Ruby の実行環境上で実験。
[1] 1.9.3-p125(main)> require 'CaboCha' => true [2] 1.9.3-p125(main)> sentence = "\u592a\u90ce\u306f\u3053\u306e\u672c\u3092\u4e8c\u90ce\u3092\u898b\u305f\u5973\u6027\u306b\u6e21\u3057\u305f\u3002" => "太郎はこの本を二郎を見た女性に渡した。" [3] 1.9.3-p125(main)> cabocha = CaboCha::Parser.new => #<CaboCha::Parser:0x007f9b690d1fe0 @__swigtype__="_p_CaboCha__Parser"> => true [4] 1.9.3-p125(main)> tree = cabocha.parse sentence => #<CaboCha::Tree:0x007f9b6990d948 @__swigtype__="_p_CaboCha__Tree"> [5] 1.9.3-p125(main)> puts tree.toString(CaboCha::OUTPUT_RAW_SENTENCE) <PERSON>太郎</PERSON>は-----------D この-D | 本を---D | 二郎を-D | 見た-D | 女性に-D 渡した。 EOS => nil [6] 1.9.3-p125(main)> chunk_to_s = ->(ch){(0...ch.token_size).map{|j|tree.token(ch.token_pos+j).normalized_surface}.join("-")} => #<Proc:0x007f9b699611b0@(pry):38 (lambda)> [7] 1.9.3-p125(main)> chunk_link = ->(ch){if ch.link>=0;ch_from=chunk_to_s[ch];ch_to=chunk_to_s[tree.chunk(ch.link)];"#{ch_from} => #{ch_to}";end;} => #<Proc:0x007f9b6903e0b0@(pry):41 (lambda)> [8] 1.9.3-p125(main)> puts chunk_link[tree.chunk(0)] => 太郎-は => 渡し-た-。 [9] 1.9.3-p125(main)> puts chunk_link[tree.chunk(1)] => この => 本-を
つまり、treeは文の解析ツリー、chunkが文節、tokenが単語(形態素)、ですね。
そしてCaboCha::Chunk#link が係り受けを表している(自分が「係り」、linkで表されるインデックスのChunkが「受け」)、と。
でもこれ、本当に CaboCha を単純にラップしたもので、Ruby 的に使いにくいところとか気になるところがいくつかあるので、余裕があったらより Ruby っぽくなるようにさらにラップしたいところ。
取り敢えず今日はここまで。