LoginSignup
30
26

More than 5 years have passed since last update.

Juman++をサーバーモードで利用しよう

Posted at

この記事の内容

Juman++とは?

Juman++とは京大・黒橋研究室で開発された形態素解析器です。
「それ、Mecabと何が違うん?」と言う点ですが、Juman++では「RNN(いわゆるディープラーニング系のやつ)言語モデルを利用している」点が異なります。

Qiitaでも紹介記事が徐々に増えつつあり、今後の普及が楽しみです。

Juman++のちょっと気になる点

  1. 依存ライブラリを新しくしないといけない。特にgcc周り
  2. 遅い

依存ライブラリ問題は、gccを更新して、他のコード郡が動かなくなるかもしれない・・・という懸念はあります。
そういう場合はDocker環境を用意するというクールな解決法を使いましょう。

さて、問題は2の速度面です。
こちらの記事では、

Mecabは10秒ほどで終わったのに対し、JUMAN++は 10時間以上 かかってしまい

とのことで、速度面に懸念があるのは確かです。

私の環境でも計測比較をしてみました。

time echo "外国人参政権が認可された。私もあさって日曜最終日。" | mecab

echo   0.00s user 0.00s system 26% cpu 0.005 total
mecab  0.00s user 0.00s system 49% cpu 0.007 total
time echo "外国人参政権が認可された。私もあさって日曜最終日。" | jumanpp

echo   0.00s user 0.00s system 31% cpu 0.004 total
jumanpp  0.14s user 0.35s system 53% cpu 0.931 total

Mecabと比較して3桁も違う数値が出てしまいました。

この要因は設計云々ではなく、モデル読み込みに時間がかかっているため(らしいです。某所よりの話)
つまり、RNN言語モデルを利用する上で、仕方がないことではあります。

では、どうすればいいのでしょうか?

サーバーモードを利用しよう!

解決策は簡単で、「サーバースクリプトを使う」以上!です。

実はこれ、ver.1.0.1 マニュアルにきちんと書いてあります。
5ページを参照してください。

Juman++のtarに同封のRubyスクリプトを利用して、サーバーモードとして起動しっぱなしにしておきます。

マニュアルによると、

$ ruby script/server.rb --cmd "jumanpp -B 5" --host host.name --port 1234

でサーバー起動。クライアントして呼び出すには

echo "ケーキを食べる" | ruby script/client.rb --host host.name --port 1234

です。

では、サーバーモードを利用すると時間はどれくらいの短縮になるのでしょうか?

time echo "外国人参政権が認可された。私もあさって日曜最終日。" | ruby client.rb --host localhost

echo   0.00s user 0.00s system 21% cpu 0.006 total
ruby client.rb --host localhost  0.04s user 0.01s system 47% cpu 0.092 total

約10分の1の時間になりました!スゴイですね!
ちなみに、ネットワーク越しのJuman++だと、どうなるのでしょうか?
ローカルネットワーク内に存在するサーバーマシンにJuman++サーバーを起動し、計測してみました。

time echo "外国人参政権が認可された。私もあさって日曜最終日。" | ruby client.rb --host sever.hogehoge

echo   0.00s user 0.00s system 22% cpu 0.005 total
ruby client.rb --host sever.hogehoge 0.03s user 0.01s system 26% cpu 0.167 total

。。。。まあ、ネットワークレスポンスの考慮すると、こんなものでしょうか。
とにかく、サーバーモードを利用すると、ボトルネックは解決できることがわかったわけです。

みなさん、Juman++はサーバーモードで利用しましょう

PythonからJuman++のサーバーモードを利用する

先のクライアントスクリプトはRubyで記述されています。
なので、Rubyの人はそのまま使えばいいんじゃないっすかねー(鼻くそほじほじ)

ただ、私はPythonを常用する人なので、やっぱりPythonから呼び出ししたいわけです。
client.rbをPythonにして使いたい場合は、下の方にコードをはっつけておくので、そっちを見てください)
公式でpyknpというPythonパッケージが公開されていますが、実はjuman++用にはsubprocess呼び出ししか用意されていません。(pyknp-0.3での話)
これでは、サーバーモードの恩恵を受けることができないわけです。

私はJapaneseTokenizersというPythonパッケージを公開しています。
このPythonパッケージに組み込んじゃいました。

Python2xとPython3xの両方で利用可能です。

できること

  • 1行で形態素分割結果をリスト取得
  • 1行で形態素分割 -> 品詞フィルタリング -> ストップワード除去 -> リスト化
  • Mecab, Juman, Juman++, Kyteaを同じ記法で呼び出し可能

インストール方法

  1. Mecab, Juman, Juman++をインストールする。このREADMEを見てください。
  2. Juman++をサーバーモードで起動する。Juman++同封のserver.rbを使ってください。
  3. pip install JapaneseTokenizer

でおしまいです。

使い方

Juman++をサーバーモードで呼び出すには1行で済みます。

>>> from JapaneseTokenizer import JumanppWrapper
>>> sentence = 'テヘラン(ペルシア語: تهران  ; Tehrān Tehran.ogg 発音[ヘルプ/ファイル]/teɦˈrɔːn/、英語:Tehran)は、西アジア、イランの首都でありかつテヘラン州の州都。人口12,223,598人。都市圏人口は13,413,348人に達する。'
>>> list_result = JumanppWrapper(server='localhost', port=12000).tokenize(sentence, return_list=True)
>>> print(list_result)
['テヘラン', 'ペルシア', '語', '発音', 'ヘルプ', 'ファイル', '英語', 'Tehran', '西', 'アジア', 'イラン', '首都', 'テヘラン', '州都', '人口', '12,223,598', '都市', '圏', '人口', '13,413,348']

品詞で形態素選択をするには、選択したい品詞を List[Tuple[str]] で渡してやります。
Juman++の品詞体系はこのページを見てください。

>>> from JapaneseTokenizer import JumanppWrapper
>>> sentence = 'テヘラン(ペルシア語: تهران  ; Tehrān Tehran.ogg 発音[ヘルプ/ファイル]/teɦˈrɔːn/、英語:Tehran)は、西アジア、イランの首都でありかつテヘラン 州の州都。人口12,223,598人。都市圏人口は13,413,348人に達する。'
>>> pos_condition = [('名詞', '地名')]
>>> JumanppWrapper(server='localhost', port=12000).tokenize(sentence, return_list=False).filter(pos_condition=pos_condition).convert_list_object()
['テヘラン', 'アジア', 'イラン', 'テヘラン']

他にも品詞情報、表層系、その他、Juman++が出力する情報をまとめて獲得もできます。

詳しくはexamples.pyを参照ください。

前回の記事からの改良点

  • Juman++を利用できるようにした
  • Juman serverモードで発生するバグを解消
  • 1行で品詞フィルタリングまでを完結させるシンタックスシュガーの導入
30
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
26