Edited at
AtraeDay 4

イケてる形態素解析エンジン「juman++」をrubyから実行できるようにする!

More than 1 year has passed since last update.

Atraeアドベントカレンダーの四日目です。


はじめに

形態素解析エンジンにjuman++というのがあります

結構いい感じに使えそうなので、これをrubyから触れるようになることが今回の目的です。

そこでググル先生にお尋ねしたところ、コマンドラインを触るためのライブラリとして、

「open3」というのがあることがわかったので今回はそれを使って見ようと思います。


環境


  • Mac OSX ver. 10.11.6


やること


  • juman++をインストールする

  • open3の使い方を理解する

  • open3からjuman++をたたくためのラッパーを作成する


1. juman++のインストール

brew install jumanpp


1-2. juman++の使い方

$ jumanpp ハロー、ワールド

=> ハロー はろー ハロー 感動詞 12 * 0 * 0 * 0 "代表表記:ハロー/はろー" 、 、 、 特殊 1 読点 2 * 0 * 0 NIL
ワールド わーるど ワールド 名詞 6 普通名詞 1 * 0 * 0 "代表表記:ワールド/わーるど カテゴリ:場所-その他"
EOS


open3の使い方を理解する

open3とは


プログラムを実行し、そのプロセスの標準入力、標準出力、標準エラー出力にパイプを繋ぎます


らしいです。

とりあえず叩いてみましょう。

pry(main)> require 'open3'

pry(main)> Open3.popen3('jumanpp')
=> [#<IO:fd 13>, #<IO:fd 14>, #<IO:fd 16>, #<Thread:0x007fa025099ee0 sleep>]

のように配列が返ってきます。

順にstdin, stdout, stderr, wait_thrのようです。

juman++を使う場合、stdinにテキストを渡して、stdoutから解析結果を取得できればよさそうですね。



  • stdin引数を渡すためには、puts


  • stdoutから結果を取得するには、read

をそれぞれ使えば、望む結果が得られそうです。

早速試してみましょう。

pry(main)> stdin, stdout, stderr, wait_the = Open3.popen3('jumanpp')

=> [#<IO:fd 13>, #<IO:fd 15>, #<IO:fd 18>, #<Thread:0x007fb50f671af8 sleep>]

pry(main)>stdin.puts 'ハロー、ワールド'
=> nil

[23] pry(main)> stdout.read
=> "ハロー はろー ハロー 感動詞 12 * 0 * 0 * 0 \"代表表記:ハロー/はろー\"\n、 、 、 特殊 1 読点 2 * 0 * 0 NIL\nワールド わーるど ワールド 名詞 6 普通名詞 1 * 0 * 0 \"代表表記:ワールド/わーるど カテゴリ:場所-その他\"\nEOS\n"

結構簡単に求める結果を得ることができました(∩´∀`)∩ワーイ


ラッパーを作ろう

これを簡単に使えるように、module化しておきましょう。

ソースコードは以下のとおりです。

require 'open3'

module Jumanpp
class Parser
def initialize
@stdin, @stdout, @stderr, @thread = Open3.popen3('jumanpp')
end

def parse(text)
print(text)
@stdin.close # stdinを閉じる
stdout_to_array
end

def print(text)
@stdin.puts text
end

def stdout_to_array
# EOSやNILなどを削除したり
@stdout.read.gsub(/\nEOS\n/, '').split(/NIL/)
end

# threadをkillするために一応つけとく
def kill
@stdin.close unless @stdin.closed?
@thread.kill
end
end
end

使い方はこんな感じ

pry(main)> jumanpp=Jumanpp::Parser.new

pry(main)> jumanpp.parse 'ハロー、ワールド'
=> ["ハロー はろー ハロー 感動詞 12 * 0 * 0 * 0 \"代表表記:ハロー/はろー\"\n、 、 、 特殊 1 読点 2 * 0 * 0 ",
"\nワールド わーるど ワールド 名詞 6 普通名詞 1 * 0 * 0 \"代表表記:ワールド/わーるど カテゴリ:場所-その他\""]


おわり

というわけでjuman++をrubyから使うことができるようになりました。

ほとんどopen3の話でしたがw

juman++は口語に強い形態素解析エンジン(という認識)なのでSNSの投稿やチャットなどを解析させると色々捗るかもしれません!!

macさえアレばお手軽に試せるのでみなさんも是非お試してください!!