Mecabの導入

自動リンク(AutoLink)や英単語のカタカナ変換、漢字のふりがなをMecabで実現するの続き。
方法論を検討した前回に対し、実際に導入した時のメモです。



1.mecabのインストール

mecabをインストールします。


確認したところ、使っているレンタルサーバには既に入っています。
しかし

# which mecab
/usr/local/bin/mecab

# wget http://www.opendogs.org/pub/php_mecab-0.3.0.tgz
# tar xzvf php_mecab-0.3.0.tgz
# cd php_mecab-0.3.0
# /usr/local/bin/phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519

# ./configure --with-php-config=/usr/local/bin/php-config --with-mecab=/usr/local/bin/mecab-config
checking for MeCab library version... 0.93
configure: error: MeCab version 0.94 or later is required to compile php with MeCab support

0.93(><。。
ということで、php_mecabを使うため、自力インストールする羽目に陥りました。


記事執筆時点の最新版は、2008年02月03日リリースのMeCab 0.97です。

# wget http://downloads.sourceforge.net/project/mecab/mecab/0.97/mecab-0.97.tar.gz?use_mirror=jaist
# tar zxfv mecab-0.97.tar.gz
# cd mecab-0.97
# ./configure --enable-utf8-only --prefix=/home/****/local --exec-prefix=/home/****/local
# make
# make check
# make install

「configure option で --enable-utf8-only を指定すると. MeCab が扱う 文字コードを utf8 に固定」されるそうなので、指定しました。
私の場合、UTF-8以外の文字コードMecabに渡すよりだいぶ前にUTF-8に揃えてしまうので、実行バイナリが小さい方がよかったからです。

makeする時のエラー

makeする時にエラーが何度か出たのですが、killされて失敗したのが原因のようで、何度かmakeしているうちにうまくできました(<いい加減だな、おい)

make[2]: *** [char_property.lo] Error 1
make[2]: Leaving directory `/home/****/mecab-0.97/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/****/mecab-0.97'

make checkの時のエラー

runtests faild in
FAIL: run-cost-train.sh
===================
1 of 3 tests failed
===================
make[2]: *** [check-TESTS] Error 1
make[2]: Leaving directory `/home/****/****/mecab-0.97/tests'
make[1]: *** [check-am] Error 2
make[1]: Leaving directory `/home/****/mecab-0.97/tests'
make: *** [check-recursive] Error 1


バージョンは違いますが、同様のエラーをみつけました
(というかmake checkでぐぐったらトップに表示されました)


▽[mecab-users 240] mecab-0.94でmake checkエラー
 http://sourceforge.jp/projects/mecab/lists/archive/users/2007-March/000239.html


フォローされているコメントによれば、「パラメータ学習をしないのであれば,そんなに深刻に考える必要はありません」とのこと。
そのままmake installしました。


Mecabのダウンロード
 http://mecab.sourceforge.net/#download
※最新版へのリンク等はこちらでご確認ください。


mecabをインストールしてみた(pblo)
 http://playispeace.com/blog/98/mecab_install
※インストールでひっかかったポイントを細かく記録されているので参考になりました。


さくらインターネットで和布蕪(MeCab)をインストールする方法(さぶちゃんねるブログ)
 http://sabuch.sblo.jp/article/792810.html
レンタルサーバMecabをインストールする方法として参考にしました。今はさくらインターネット
Mecabが導入されているので、差し支えなければそちらを使うのがよさそうです。


インストールが無事できているかの確認

# /home/****/local/binmecab
雨が降る
雨が降る 荐?桑筝?・*,*,*,*,*
EOS

ターミナルの文字コードの設定によってはおかしな文字が返ってきますが、無事インストールされていれば、一応動くと思います。



2.php_mecabのインストール(失敗しました)

php_mecabは以下のページから入手します。


php_mecab-0.3.0: 某所より引っ越し(讃容日記)
 http://d.hatena.ne.jp/rsky/20071228/1198841049

$ wget http://www.opendogs.org/pub/php_mecab-0.3.0.tgz
$ tar xzvf php_mecab-0.3.0.tgz
$ cd php_mecab-0.3.0
$ /usr/local/bin/phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
$ ./configure --with-php-config=/usr/local/bin/php-config --with-mecab=/home/****/local/bin/mecab-config --prefix=/home/****/local --exec-prefix=/home/****/local
$ make
$ make install

※後で紹介するウノウラボの記事をもとに、私の環境にあわせて太字部分を書き換えました

make installの際のエラー

Installing shared extensions: /usr/local/lib/php/extensions/no-debug-non-zts-20060613/
cp: cannot create regular file `/usr/local/lib/php/extensions/no-debug-non-zts-20060613/#INST@7870#': Permission denied
make: *** [install-modules] Error 1


パーミッション……
あまりよく考えずに、余所の記事を読みながらそのまま操作していた点に問題があります。


上記makeの段階で、mecab.soというPHP Extensionのファイルとしてコンパイルされています。
つまり、ホームディレクトリの下の、php_mecab-0.3.0/modules/mecab.soをコピーすればmake installしなくても使え……るんですよねぇ?


PHP Extension を作ろう第1回 - まずは Hello WorldDSAS開発者の部屋)
 http://dsas.blog.klab.org/archives/50777398.html


さくらインターネットPECLをインストール(dozo dokuwiki.php
 http://dozo.matrix.jp/pecl/%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90

断念した理由

使えることを前提に、各所のサンプルファイルをもとに、phpを書いてみましたが、以下のようなエラー。

Warning: dl() [function.dl]: Unable to load dynamic library '/home/****/****/public_html/mecab.so' - /lib/tls/libc.so.6: version `GLIBC_2.0' not found (required by /home/****/****/public_html/mecab.so) in /home/****/****/public_html/test.php on line 11

Fatal error: Class 'MeCab' not found in /home/****/game5.jp/public_html/test.php on line 16

dl()はセーフモードに対応していないので、このファイルだけcgiモードにしてセーフモードを回避しました。
そうすると、上記のエラーがでます。

#/lib/tls> ls -l
total 1733

  • rwxr-xr-x 1 root root 1417095 2005-09-10 02:36 libc-2.3.5.so

lrwxrwxrwx 1 root root 13 2006-07-24 11:37 libc.so.6 -> libc-2.3.5.so

  • rwxr-xr-x 1 root root 191109 2005-09-10 02:36 libm-2.3.5.so

lrwxrwxrwx 1 root root 13 2006-07-24 11:37 libm.so.6 -> libm-2.3.5.so

  • rwxr-xr-x 1 root root 93266 2005-09-10 02:36 libpthread-2.3.5.so

lrwxrwxrwx 1 root root 19 2006-07-24 11:37 libpthread.so.0 -> libpthread-2.3.5.so

  • rwxr-xr-x 1 root root 40833 2005-09-10 02:36 librt-2.3.5.so

lrwxrwxrwx 1 root root 14 2006-07-24 11:37 librt.so.1 -> librt-2.3.5.so

  • rwxr-xr-x 1 root root 28210 2005-09-10 02:36 libthread_db-1.0.so

lrwxrwxrwx 1 root root 19 2006-07-24 11:37 libthread_db.so.1 -> libthread_db-1.0.so

#/lib/tls> rpm -qi glibc
Name : glibc Relocations: (not relocatable)
Version : 2.3.5 Vendor: SUSE LINUX Products GmbH, Nuernberg, Germany
Release : 40 Build Date: Sat 10 Sep 2005 02:37:21 AM JST
〜中略〜

#ldd -v mecab.so
./mecab.so: /lib/tls/libc.so.6: version `GLIBC_2.0' not found (required by ./mecab.so)
linux-gate.so.1 => (0xffffe000)
libmecab.so.1 => /home/****/local/lib/libmecab.so.1 (0x40012000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x400a9000)
libc.so.6 => /lib/tls/libc.so.6 (0x40189000)
libiconv.so.2 => /usr/local/lib/libiconv.so.2 (0x402a8000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x40382000)
libm.so.6 => /lib/tls/libm.so.6 (0x40394000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x403bb000)
/lib/ld-linux.so.2 (0x80000000)

Version information:
./mecab.so:
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
/home/****/local/lib/libmecab.so.1:
libgcc_s.so.1 (GCC_3.0) => /usr/lib/libgcc_s.so.1
libm.so.6 (GLIBC_2.0) => /lib/tls/libm.so.6
libpthread.so.0 (GLIBC_2.1) => /lib/tls/libpthread.so.0
libpthread.so.0 (GLIBC_2.0) => /lib/tls/libpthread.so.0
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
libstdc++.so.6 (GLIBCXX_3.4) => /usr/lib/libstdc++.so.6
libstdc++.so.6 (CXXABI_1.3) => /usr/lib/libstdc++.so.6
/usr/lib/libstdc++.so.6:
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/tls/libc.so.6
libgcc_s.so.1 (GCC_3.3) => /usr/lib/libgcc_s.so.1
libgcc_s.so.1 (GCC_3.0) => /usr/lib/libgcc_s.so.1
libgcc_s.so.1 (GLIBC_2.0) => /usr/lib/libgcc_s.so.1
/lib/tls/libc.so.6:
ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_2.0) => /lib/ld-linux.so.2
/usr/local/lib/libiconv.so.2:
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
/lib/tls/libpthread.so.0:
ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.3.2) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.2) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.1) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib/tls/libc.so.6
/lib/tls/libm.so.6:
ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6
/usr/lib/libgcc_s.so.1:
libc.so.6 (GLIBC_2.2.4) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.1.3) => /lib/tls/libc.so.6
libc.so.6 (GLIBC_2.0) => /lib/tls/libc.so.6


libc.so.6は、libc-2.3.5.soへのシンボリックリンクになっているので、GLIBCは、2.3.5が使われるはず。
にもかかわらずこの状況ということは、GLIBC自体が設定の問題で利用できない(みつからない?)状態、ということなのでしょうか。
けどエラーエッセージ的にはディレクトリはあっているので、かっちり2.0じゃないと駄目とか(まさかねぇ……だとしたら現行の環境の多くでは動かないでしょうに)


以下のページを参考にlddもしてみました。「共有ライブラリへの依存関係を表示する」らしいですが……正直どうなってるんだか、さっぱりわかりません(><。。


▽[ja-dev] glibc-2.2.x 問題
 http://search.luky.org/oo/ja-dev.2003/msg00182.html

お手上げです。
解決しても、dl()自体が「 PHP 5.3.0 で 非推奨となり、PHP 6.0.0 で削除」されるので、どうせこのあたりのコードを一生懸命書いてもさほど時間かからずにいじらないといけなくなりそうです。
だったらこれ以上解決できるかわからない問題にとりくみつづけるのもなぁ


よって今回は断念しました。他の方法を考えます。


3.php_mecabを使わずに、phpからmecabを使う

php_mecabは、PHP extensionですから、動的に拡張できるのはもちろん、高速に動作するという利点があります。


PHP Extension を作ろう第1回 - まずは Hello WorldDSAS開発者の部屋)
 http://dsas.blog.klab.org/archives/50777398.html


したがって大変魅力的なのですが、使えない環境で使いたいといってもはじまらない。
当然ですが、php_mecabを使わずに、phpからmecabを使う方法もあります。


PHPMeCabを使って形態素解析をするときのメモ(クデラボ)
 http://kudelab.com/archives/15


PHPMeCabでオートリンクの実装をする2(KAKKU TIPS(終了しました))
 http://kakku.blogspot.com/2008/01/phpmecab2.html


shell_execproc_openか、ですね。

shell_execは、セーフモードでは無効になるので、セーフモードで使えるproc_openを検討することにしました。


クデラボさんの記事にあるソースの頭に

$text = '人権相互の矛盾衝突を調整する実質的公平の原理';

と、お尻に

echo $result;

をつければOK。あっさり動きました。

人権 名詞,一般,*,*,*,*,人権,ジンケン,ジンケン 相互 名詞,一般,*,*,*,*,相互,ソウゴ,ソーゴ の 助詞,連体化,*,*,*,*,の,ノ,ノ 矛盾 名詞,サ変接続,*,*,*,*,矛盾,ムジュン,ムジュン 衝突 名詞,サ変接続,*,*,*,*,衝突,ショウトツ,ショートツ を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 調整 名詞,サ変接続,*,*,*,*,調整,チョウセイ,チョーセイ する 動詞,自立,*,*,サ変・スル,基本形,する,スル,スル 実質 名詞,一般,*,*,*,*,実質,ジッシツ,ジッシツ 的 名詞,接尾,形容動詞語幹,*,*,*,的,テキ,テキ 公平 名詞,形容動詞語幹,*,*,*,*,公平,コウヘイ,コーヘイ の 助詞,連体化,*,*,*,*,の,ノ,ノ 原理 名詞,一般,*,*,*,*,原理,ゲンリ,ゲンリ EOS

ただ結局、セーフモードでは(少なくともうちの環境では)動かないですね。
システム関数ってことで、まるっと動かないようにしてあるのかな。



なお、せっかく最新のMecab0.9.7を導入しましたが、管理の都合を考えて、サーバにインストールされているMecab 0.9.3をそのまま使うことにしました(なんだったんだ、これまでの苦労は)。


改訂履歴を見る限り、さほど問題がない気がする(そうか?)

2008-02-03 MeCab 0.97
マルチスレッド環境で辞書を開くときの排他制御がうまくいっていなかったバグの修正
Windows版でインストール時に辞書の文字コードを指定できるようになった
一部のコンパイラで正しくコンパイルできなかった問題の修正
部分解析モードを変更するAPI の追加 (Tagger::set_partial())
ラティスの生成レベルを変更するAPI の追加 (Tagger::set_lattice_level())
温度パラメータを変更するAPIの追加 (Tagger::set_theta())
全候補出力モードを変更するAPIの追加 (Tagger::set_all_morphs())

2007-06-10 MeCab 0.96
バッファオーバフローのバグを修正
常にPOS-IDを作成するようにした (-p オプションの廃止)
ユーザ辞書のデリミタを : から , (CSV) に変更 (Windows対策)
charsetの判定にバグがあり, ある条件でユーザ辞書とシステム辞書が非互換になるバグを修正
ユーザ辞書ファイルの文字コードとシステム辞書ファイルの文字コー ドが異なる場合, 辞書の構築がうまくいかなかった問題の修正
コマンドラインオプションをダンプする --dump-config オプションの追加
EMベースのHMM学習をサポートできるような学習ルーチンの追加 (experimental)

2007-03-11 MeCab 0.95
古いコンパイラコンパイルできない問題を修正
csvエスケープの不具合で ","を含む単語が追加できなかった問題を修正
UTF8辞書が一部正常に作成できなかったバグの修正
recall/precisionの表示が反対になっていたバグの修正
コマンドライン解析の不具合の修正
その他細かなバグの修正

2007-02-24MeCab 0.94
多くのバグフィックス
HMMによる学習をサポート (実験的)
解析結果の全情報を取得できるAPIを追加 (begin_node_list, end_node_list)
char.def, unk.def, matrix.def が未定義の場合でも辞書が作成できるよう変更
Windows版の iconv.dllへの依存を廃止
コードのクリーンアップ


とりあえずこれで一区切りですね。あとはこれをどう使うか、です。