形態素解析エンジンMeCabをFedora17でHaskellから使う際のメモ
Fedora17でのMeCabのインストールとUTF-8用の設定方法、
及びHaskellからMeCabを使う方法を紹介する。
以下のページを参考にさせて頂きました。
http://kane.meta-scheme.jp/article/37183101.html
MeCabのインストールと設定
Fedora17にはmecabパッケージがあるので、
インストールは以下のようにyumからインストールするだけでよい。
yum install *mecab*
上記の方法でインストールしたMeCabは、デフォルトではEUC-JPの辞書ファイルを使うように設定されているため不便である。
MeCabの設定ファイル"/etc/mecabdir"のdicdirで始まる行をコメントアウトして、
以下のようにUTF-8の辞書ファイルを参照するように編集する。
; ; Configuration file of MeCab ; ; $Id: mecabrc.in,v 1.3 2006/05/29 15:36:08 taku-ku Exp $; ; ; dicdir = /usr/lib64/mecab/dic/jumandic-EUCJP dicdir = /usr/lib64/mecab/dic/jumandic ; userdic = /home/foo/bar/user.dic ; output-format-type = wakati ; input-buffer-size = 8192 ; node-format = %m\n ; bos-format = %S\n ; eos-format = EOS\n
UTF-8の辞書ファイルは、上記のyumコマンドを実行した際に/usr/lib64/mecab/dic/jumandicにインストールされたものである。
これで以下のようにmecabが使えるようになった。
$ echo "メカブは美味しくて健康にもいいよ。" | mecab メカブ 名詞,人名,*,*,*,*,* は 助詞,副助詞,*,*,は,は,* 美味しくて 形容詞,*,イ形容詞イ段,タ系連用テ形,美味しい,おいしくて,代表表記:美味しい 健康に 形容詞,*,ナ形容詞,ダ列基本連用形,健康だ,けんこうに,代表表記:健康だ も 助詞,副助詞,*,*,も,も,* いい 形容詞,*,イ形容詞アウオ段,基本形,いい,いい,代表表記:いい よ 助詞,終助詞,*,*,よ,よ,* 。 特殊,句点,*,*,。,。,* EOS
HaskellからMeCabを使う。
使い方の概要は以下の通り。
以下のMeCab C++サンプルとほぼ同じ動作をするHaskellサンプルを示す。
http://mecab.googlecode.com/svn/trunk/mecab/doc/libmecab.html
サンプルで使用した関数の概要は以下の通り。
Taggerインスタンスを作成する関数。
引数には""を指定する。
MeCabの動作を変更するオプションを指定すると思われるが、確認していない。
Taggerインスタンスを第一引数に、解析対象の文字列を第二引数に指定すると、
最も精度がよい解析結果の文字列を取得するIOモナドを作る。
精度のよい解析結果を、上位から第二引数で指定した分だけ返す文字列にして返すIOモナドを作る。
後述するnext関数で、精度のよい解析結果を順番に取得するための初期化を行う。
精度のよい解析結果を一つ取り出す。
最も精度のよい解析結果を、文字列ではなく各ノードのリストとして受け取る。
import Text.MeCab import Control.Monad toString :: Text.MeCab.Node String -> String toString node = foldr (\x acc-> x ++ " " ++ acc) [] attrs where id = (show $ nodeId node) stat = case nodeStat node of BOS -> "BOS" EOS -> "EOS" _ -> (nodeSurface node) ++ " " ++ (show $ nodeRlength node) feature = nodeFeature node rcAttr = show $ nodeRcAttr node lcAttr = show $ nodeLcAttr node posid = show $ nodePosid node ctype = show $ nodeCharType node stat' = show $ nodeStat node isbest = show $ nodeIsBest node alpha = show $ nodeAlpha node beta = show $ nodeBeta node prob = show $ nodeProb node cost = show $ nodeCost node attrs = [id, stat, feature] --attrs = [id, stat, feature, rcAttr, lcAttr, posid, ctype, -- stat', isbest, alpha, beta, prob, cost] test = do let input = "太郎は次郎が持っている本を花子に渡した。" mecab <- new2 "" -- Gets tagged result in string format. result <- parse mecab input putStrLn $ "INPUT : " ++ input putStrLn $ "RESULT: " ++ result -- Gets N best results in string format. nbresult <- parseNBest mecab 3 input putStrLn $ "NBEST: " ++ nbresult -- Gets N best results in sequence. parseNBestInit mecab input forM_ [0..1] $ \n -> do nextResult <- next mecab case nextResult of Just nr -> putStrLn $ (show n) ++ ":" ++ nr _ -> return () -- Gets Node object. nodes <- parseToNode mecab input mapM_ (putStrLn . toString) nodes return () main = test