2017年9月10日日曜日

Python3からChaSenを使う@CentOS 7


ChaSenは奈良先端科学技術大学院大学松本研究室で開発された日本語の形態素解析システムです。2000年ころに松本教授自ら書かれた記事が公開されていました。

今回のざっくりとした環境は下記のとおりです。CentOS7は最小インストールした直後の状態を想定しています。
  • ChaSen 2.4.5
  • Python 3.4
  • CentOS 7.3
今回もコンパイルして入れます・・・が、Python 3から呼び出せるバインディングが見つかりませんでしたので、プロセスを呼んで結果を取得します。

準備

nkfとgcc、gcc-c++をインストールします。
yum install nkf gcc gcc-c++

Dartsのインストール

ChaSenを入れる前にDartsというライブラリが必要になりますので、インストールします。
cd ~/download
wget http://chasen.org/~taku/software/darts/src/darts-0.32.tar.gz
cd ~/src
tar xzvf ../download/darts-0.32.tar.gz
cd darts-0.32/
./configure
make
make install

ChaSen本体のインストール

本体をインストールします。
cd ~/download
wget 'https://ja.osdn.net/frs/redir.php?m=jaist&f=%2Fchasen-legacy%2F56305%2Fchasen-2.4.5.tar.gz' -O chasen-2.4.5.tar.gz
cd ~/src
tar xzvf ../download/chasen-2.4.5.tar.gz
cd chasen-2.4.5/
./configure
make
make install

chasen辞書のインストール

辞書は別途用意されているので、ダウンロードしてインストールします。
wget 'https://ja.osdn.net/frs/redir.php?m=ymu&f=%2Fipadic%2F24435%2Fipadic-2.7.0.tar.gz' -O ipadic-2.7.0.tar.gz
cd ~/src/
tar xzvf ../download/ipadic-2.7.0.tar.gz
cd ipadic-2.7.0/
./configure
make
make install
chasen自体はEUCをベースにしていますので、そのままだと文字化けします。
echo "これは、テストです。"|nkf -e|chasen|nkf -w
これ    コレ    これ    名詞-代名詞-一般
は      ハ      は      助詞-係助詞
、      、      、      記号-読点
テスト  テスト  テスト  名詞-サ変接続
です    デス    です    助動詞  特殊・デス      基本形
。      。      。      記号-句点
EOS
仕方ないので、nkfを両端に挟んでみましたが、たぶんコストも大きくなりますし、見た目が悪いw

辞書をutf-8に変更

なんとか、utf-8に変更したいと思って方法を探していたところ、Qiitaにいい記事がありましたので、参考にしつつut-8に変更を行いました。
cd ~/src/ipadic-2.7.0/
make clean
find -name '*.dic' | xargs nkf --overwrite -w
find -name '*.cha' | xargs nkf --overwrite -w
`chasen-config --mkchadic`/makemat -i w
`chasen-config --mkchadic`/makeda -i w chadic *.dic
./configure
make
make install
nkf -w --overwrite /usr/local/etc/chasenrc
この状態でテストを行います。chasenには-iwのオプションを付けて呼び出します。
echo 'これは、テストです。'|chasen -iw
これ    コレ    これ    名詞-代名詞-一般
は      ハ      は      助詞-係助詞
、      、      、      記号-読点
テスト  テスト  テスト  名詞-サ変接続
です    デス    です    助動詞  特殊・デス      基本形
。      。      。      記号-句点
EOS
ちなみに、ChaSenの辞書も古いためそのままでは、新しめの単語には対応できません。
echo 'クラウド'|chasen -iw
クラ    クラ    クラ    名詞-固有名詞-一般
ウド    ウド    ウド    名詞-一般
EOS

Python3から呼び出す

これは、wrapperが見つかりませんでしたので、プロセスを呼び出す要領で標準出力を配列に格納します。 ほかに何か良い方法があれば、だれか教えてください。
ファイル: chasen.py
import subprocess

def strip_cmd_injection(instr):
    inj = [";", "|", "&", "`", "(", ")", "$", "<", ">", "*", "?", "{", "}", "[", "]", "!", "\n"]
    for s in inj:
        instr = instr.replace(s,"")
    return instr

def chasen(arg):
    arg = strip_cmd_injection(arg)
    cmd = "echo {0} | chasen -iw".format(arg)
    proc = subprocess.Popen(
        cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    if stderr != b'':
        raise(Exception(stderr.decode("utf-8")))

    for line in stdout.decode('utf-8').split("\n"):
        if (line == "EOS"):
            break
        yield line.split("\t")

if __name__ == '__main__':
    import sys
    for line in sys.stdin:
        for cha in chasen(line):
            print (cha)
実行すると、下記のような結果が得られます。各要素が配列になっているので、取り出して使うことを想定しています。
echo "これはてすとです。" | python3 sample.py
['これ', 'コレ', 'これ', '名詞-代名詞-一般', '', '']
['はて', 'ハテ', 'はて', '副詞-一般', '', '']
['す', 'ス', 'す', '名詞-一般', '', '']
['と', 'ト', 'と', '助詞-格助詞-一般', '', '']
['で', 'デ', 'で', '助詞-格助詞-一般', '', '']
['す', 'ス', 'する', '動詞-自立', 'サ変・スル', '文語基本形']
['。', '。', '。', '記号-句点', '', '']

0 件のコメント:

コメントを投稿