7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AtraeAdvent Calendar 2016

Day 4

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

Last updated at Posted at 2016-12-04

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さえアレばお手軽に試せるのでみなさんも是非お試してください!!

7
4
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
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?