Skip to content

Instantly share code, notes, and snippets.

@tsunagun
Created November 11, 2013 05:40
Show Gist options
  • Save tsunagun/7408438 to your computer and use it in GitHub Desktop.
Save tsunagun/7408438 to your computer and use it in GitHub Desktop.
rubyから形態素解析ライブラリkuromojiを利用する
README.txt
==========
kuromojiをrubyで利用するサンプル
1. kuromojiのダウンロード
wget https://github.com/downloads/atilika/kuromoji/kuromoji-0.7.7.tar.gz
tar zxf kuromoji-0.7.7.tar.gz
cd kuromoji-0.7.7
2. kuromoji付属のサンプルプログラムをビルド(tokenize_using_rjb.rbを用いる場合は不要)
javac -cp lib/kuromoji-0.7.7.jar \
src/main/java/org/atilika/kuromoji/example/TokenizerExample.java
3. rubyスクリプト実行
スクリプトの詳細は各ファイルの先頭コメントを参照.
tokenize_using_popen.rb
popenを用いて,コマンドライン経由のkuromojiを利用する.
前述のkuromoji付属サンプルプログラムが必要.
実行速度が若干遅いが,ユーザ定義辞書が使える.
tokenize_using_rjb.rb
rjbを用いて,javaで書かれたメソッドを直接利用する.
事前にrjbのインストールが必要.
前述のkuromoji付属サンプルプログラムのビルドが必要ない.
速度が速く,javaで定義されたメソッドをほぼ利用できるが,
ユーザ定義辞書が反映されない.原因不明…
# 入力された自然文を形態素解析するプログラム
# 形態素解析器にはkuromojiを使用
# 辞書はkuromojiがデフォルトで利用するIPA-dic
#
# コマンド書式
# ruby tokenize_using_popen.rb <入力自然文> オプション
#
# 例:
# ruby tokenize_using_popen.rb "朝青龍は相撲取りである." --mode NORMAL --userdic src/main/resource/userdict.txt
#
# オプション
# --mode : kuromojiの解析モード.NORMAL, SEARCH, EXTENDEDから選択.デフォルトはNORMAL
# NORMAL: 通常のコストで形態素解析
# SEARCH: 漢字のみで構成される4文字以上の単語、もしくは7文字以上の単語
# --userdic : ユーザ定義辞書.辞書ファイルのパスを指定する.デフォルトは未使用
require 'timeout'
require 'optparse'
# 本ファイル実行時に与えられたオプションを基に,Kuromojiを起動するためのコマンドを生成する
# 引数
# argv(Array): 本ファイル実行時に与えられたオプション
# 返値
# command(String): Kuromoji起動コマンド
def build_command(argv)
opts = {mode: "normal"}
opt = OptionParser.new
opt.on('--mode VAL') {|v| opts[:mode] = v }
opt.on('--userdic VAL') {|v| opts[:userdic] = v }
opt.parse!(argv)
"java -Dfile.encoding=UTF-8 -cp lib/kuromoji-0.7.7.jar:src/main/java org.atilika.kuromoji.example.TokenizerExample #{opts[:mode]} #{opts[:userdic]}"
end
# Kuromojiを起動する
# Kuromojiの読み込みに1秒以上かかればTimeoutError
# 引数
# command(String): Kuromoji起動コマンド
# wait_limit(Numeric): Kuromoji起動にかける時間の上限(秒).起動にこれ以上かかるとプログラムを終了する
# 返値
# tokenizer(IO): Kuromojiの入力待ちIO
def build_tokenizer(command, wait_limit=2)
tokenizer = IO.popen(command, "r+")
begin
timeout(wait_limit) do
start_line = tokenizer.gets.chomp
raise unless start_line == "Tokenizer ready. Provide input text and press RET."
end
rescue
puts "Kuromoji Load Error"
exit
end
return tokenizer
end
# 形態素解析を行う
# 引数
# tokenizer(IO): Kuromojiの入力待ちIO
# input(String): 形態素解析の対象となる自然文
# wait_time(Numeric): この秒数以上トークンが取得できなければ,すべての解析結果を完了したと判断
# 返値
# token: 形態素解析結果
def tokenize(tokenizer, input, wait_time=0.1)
tokens = Array.new
tokenizer.puts(input)
loop do
begin
timeout(wait_time) do
token = tokenizer.gets.chomp
tokens << token
end
rescue Timeout::Error => e
Process.kill 'KILL', tokenizer.pid
break
end
end
return tokens
end
input = ARGV[0]
command = build_command(ARGV)
tokenizer = build_tokenizer(command)
tokens = tokenize(tokenizer, input)
puts tokens
# 入力された自然文を形態素解析するプログラム
# 形態素解析器にはkuromojiを使用
# 辞書はkuromojiがデフォルトで利用するIPA-dic
# 事前に gem install rjb を実行しておくこと
# 注意:rjbを用いた場合,userDictionary()でユーザ定義辞書を読み込んでも形態素解析に反映されない.原因不明.
#
# コマンド書式
# ruby hoge.rb <入力自然文>
#
# 例:
# ruby hoge.rb "朝青龍は相撲取りである."
require 'rjb'
class Kuromoji
Rjb::load(File.expand_path('../kuromoji-0.7.7.jar', __FILE__))
module JavaIterator
def each
i = self.iterator
while i.has_next
yield i.next
end
end
def map(&proc)
i = self.iterator
ret = []
while i.has_next
ret << proc.call(i.next)
end
ret
end
end
def initialize
tokenizer = Rjb::import('org.atilika.kuromoji.Tokenizer')
@tknizer = tokenizer.builder.build
end
class Token
attr_accessor :surface_form, :features
end
def tokenize(sentence)
tokenized_list = @tknizer.tokenize(sentence)
tokenized_list.extend JavaIterator
list = tokenized_list.map do |x|
token = Kuromoji::Token.new
token.surface_form = x.surface_form
token.features = x.all_features.split(',')
token
end
list
end
end
p Kuromoji.new.tokenize(ARGV[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment