pyknp(JUMANN++)で形態素解析してみた

どうも、大阪DI部の大澤です。

今回は形態素解析システムであるJUMAN++をPythonで使えるpyknpを試してみました。

JUMAN++

公式ページでは次のように紹介されています。

JUMAN++は言語モデルを利用した高性能な形態素解析システムです.言語モデルとして Recurrent Neural Network Language Model(RNNLM) を用いることにより,単語の並びの意味的な自然さを考慮した解析を行います.それにより JUMAN,MeCab に比べ大きく性能が向上しています.文法・辞書・出力フォーマット等は JUMAN から引き継いだものを利用しています.本システムは CREST「知識に基づく構造的言語処理の確立と知識インフラの構築」の支援により開発されました.

どういった解析が行われるかは以下のデモサイトで確認できます。試しに触ってみることでどういったものなのかと言う理解が進むかと思います。

やってみる

環境

  • macOS Mojave
  • Python 3.7.2

JUMAN++のインストール

pyknpにJUMAN++が内包されている訳ではなく、バインドしているだけなので、JUMAN++のインストールが必要です。 jumanpp-1.02に含まれるREADME_ja.mdに従って、インストールを進めます。

wget http://lotus.kuee.kyoto-u.ac.jp/nl-resource/jumanpp/jumanpp-1.02.tar.xz
tar xJvf jumanpp-1.02.tar.xz
cd jumanpp-1.02
./configure
make
sudo make install

正しくインストールされていれば、以下のコマンドでバージョンが表示されます。

jumanpp -v
JUMAN++ 1.02

試しに定番の文章で構文解析してみます。

echo "すもももももももものうち" | jumanpp
すもも すもも すもも 名詞 6 普通名詞 1 * 0 * 0 "代表表記:酸桃/すもも 自動獲得:EN_Wiktionary"
@ すもも すもも すもも 名詞 6 普通名詞 1 * 0 * 0 "自動獲得:テキスト"
も も も 助詞 9 副助詞 2 * 0 * 0 NIL
もも もも もも 名詞 6 普通名詞 1 * 0 * 0 "代表表記:股/もも カテゴリ:動物-部位"
@ もも もも もも 名詞 6 普通名詞 1 * 0 * 0 "代表表記:桃/もも 漢字読み:訓 カテゴリ:植物;人工物-食べ物 ドメイン:料理・食事"
も も も 助詞 9 副助詞 2 * 0 * 0 NIL
もも もも もも 名詞 6 普通名詞 1 * 0 * 0 "代表表記:股/もも カテゴリ:動物-部位"
@ もも もも もも 名詞 6 普通名詞 1 * 0 * 0 "代表表記:桃/もも 漢字読み:訓 カテゴリ:植物;人工物-食べ物 ドメイン:料理・食事"
の の の 助詞 9 接続助詞 3 * 0 * 0 NIL
うち うち うち 名詞 6 副詞的名詞 9 * 0 * 0 "代表表記:うち/うち"
EOS

※ 今回はpyknpでJuman++しか使わないのでKNPはインストールしませんが、必要であれば以下のページを参考にインストールしてください。

pyknpのインストール

pyknpのインストールはpipで簡単にできます。

pip install pyknp

構文解析

先ほどと同様に構文解析してみます。

from pyknp import Juman
jumanpp = Juman()
result = jumanpp.analysis("すもももももももものうち")
for mrph in result.mrph_list(): # 各形態素にアクセス
    print("見出し:%s, 読み:%s, 原形:%s, 品詞:%s, 品詞細分類:%s, 活用型:%s, 活用形:%s, 意味情報:%s, 代表表記:%s" \
            % (mrph.midasi, mrph.yomi, mrph.genkei, mrph.hinsi, mrph.bunrui, mrph.katuyou1, mrph.katuyou2, mrph.imis, mrph.repname))
見出し:すもも, 読み:すもも, 原形:すもも, 品詞:名詞, 品詞細分類:普通名詞, 活用型:*, 活用形:*, 意味情報:代表表記:酸桃/すもも 自動獲得:EN_Wiktionary, 代表表記:酸桃/すもも
見出し:も, 読み:も, 原形:も, 品詞:助詞, 品詞細分類:副助詞, 活用型:*, 活用形:*, 意味情報:NIL, 代表表記:
見出し:もも, 読み:もも, 原形:もも, 品詞:名詞, 品詞細分類:普通名詞, 活用型:*, 活用形:*, 意味情報:代表表記:股/もも カテゴリ:動物-部位, 代表表記:股/もも
見出し:も, 読み:も, 原形:も, 品詞:助詞, 品詞細分類:副助詞, 活用型:*, 活用形:*, 意味情報:NIL, 代表表記:
見出し:もも, 読み:もも, 原形:もも, 品詞:名詞, 品詞細分類:普通名詞, 活用型:*, 活用形:*, 意味情報:代表表記:股/もも カテゴリ:動物-部位, 代表表記:股/もも
見出し:の, 読み:の, 原形:の, 品詞:助詞, 品詞細分類:接続助詞, 活用型:*, 活用形:*, 意味情報:NIL, 代表表記:
見出し:うち, 読み:うち, 原形:うち, 品詞:名詞, 品詞細分類:副詞的名詞, 活用型:*, 活用形:*, 意味情報:代表表記:うち/うち, 代表表記:うち/うち

CLIで実行した時と同じような結果が出ました。

分かち書きが必要な場合は次のようにすると良さそうです。(もっと良い方法があれば教えてください...。)

[mrph.midasi for mrph in result.mrph_list()]
['すもも', 'も', 'もも', 'も', 'もも', 'の', 'うち']

※ Python2系で実行する場合には次の二行を冒頭で実行する必要があるようです。

# coding: utf-8
from __future__ import unicode_literals

さいごに

今回はpyknpを使って、JUMANN++の構文解析を試してみました。Pythonで使える構文解析システムは他にもMeCabやJanomeなどがあります。JUMANN++は速度はそこまで早くないようですが、精度が高いようです。必要な用途に応じて使い分けると良さそうです。