Python3対応のMeCab(using subprocess)
Python3対応のMeCab
言語処理をされているかたならば,ご存知のMeCabですが
公式で配布されているパッケージがPython3に対応していなくて困ったことになります.
以下の記事では, python2のパッケージをpython3用に書きなおして pipで配布されているようです.
インストールは非常に簡単で以下のいちコマンドで
pip install mecab-python3
これで今までのMeCabがPython3でも使えるようになりました.素敵!!
......
で終わるとなんだかつまんないですよね.
いつも思うことなのですが,
こういうパーサー系のライブラリを使おうとすると,
その仕様を理解するのが色々面倒です.
出力を自分で直接パースしてしまうのが早かったりします.
またMeCabに限らず他のパーサをPythonで利用する時には結局自分でラッパーを書くしか無いので
パーサー系をラップするPythonを書くのは一度書いておくと何かと楽です.
Pythonでパーサーをラップする
ということでsubprocessを利用して, パーサをラップしたコードを書いてみました.
以下は分かち書き用のMeCab parserを抜き出したものです.
コード全体はこちらです.
python3でも使えるように書かれています.
python2でsubprocessを利用するときの注意として,
Popen.communicate(input=None)には注意です.
バッファサイズが小さいと入力によっては例外が投げられます.
python2でもtimeoutが設定できればよいのですが, (python3では設定できます)
無いので実装する際には, デットロックがかからないよう注意してください.
※例えば, 何もwriteしてない状態で, read()等を呼び出すとデットロックになります.
#Mecab implements for Python using subprocess class MeCab(): def __init__(self, opts=['-Owakati']): self.opts = opts self._process = subprocess.Popen( list(itt.chain(['mecab'], opts)), stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines =True, ) def parse(self, iterable): for line in iterable: self._process.stdin.write(line+'\n') output = self._process.stdout.readline() yield output.strip().split() parser = MeCab() print next(parser.parse(['すもももももももものうち'])) # >>> ['すもも', 'も', 'もも', 'も', 'もも', 'の', 'うち']
こういうのひとつ書いておくと, あとで他のパーサでも書きやすいので何かと楽です.