2010年5月28日金曜日

GENIA Taggerで英語の形態素解析

大量の英文を形態素解析することになった。日本語ならMeCabを使ったことがあるのだけど、英語の形態素解析器についてはまったく知らないので調べてみた。ちなみに、形態素解析器は英語でPOS(Part of Speech) Taggerというらしい。Part of Speechは品詞のこと。

英語の形態素解析器がたくさんあるのはすぐわかったのだけど、自分が必要としているのは以下の2点。

  1. 各単語の原型(基本形)が取得できるもの
  2. 大量の英文を処理する必要があるため高速なもの。CまたはC++で書かれているものが望ましい。

最初は簡単に見つかると思っていたのだけど、意外にも原型(基本形)を返さないものが多く、さらに速度も考慮に入れると残ったのはGENIA Taggerだけだった。

GENIA Taggerは生物医学の文章に最適化されていて、ProteinやDNA, RNAなどがNamed Entityタグ(NEtag)として認識されるようになっている。自分が形態素解析したいのは一般的な英文で、誤認識することもあるけど、今回の用途ではそれほど問題にならないので気にしないことにする。

いざmakeしてみると、実行ファイルだけが生成されライブラリは提供されていない。さらにその実行ファイルも起動に時間がかかる。ということで、Rubyでサーバーを書くことにした。

require "webrick"

genia = IO.popen("./geniatagger", "r+", :err => "/dev/null")
class << genia
  def readlines_until_empty_line
    result = []
    while line = gets
      break if line == "\n"
      result << line
    end
    result
  end
end

server = WEBrick::GenericServer.new(:Port => 7070)
Signal.trap(:INT) do
  server.shutdown
  genia.close
end
mutex = Mutex.new
server.start do |socket|
  while line = socket.gets
    result = mutex.synchronize do
      genia.print line
      genia.readlines_until_empty_line
    end.join.gsub("\n", " ")
    socket.print result, "\n"
  end
end

WEBrick::GenericServerを利用すると簡単にサーバーを書くことができる。GENIA Taggerは解析結果を複数行で返すのだけど、これをサーバーがそのままクライアントに返すようにすると、TCPでのやりとりの回数が増えて遅くなってしまう。回避策として、改行をスペースに置換して一度に返すようにした(解析結果にスペースが出現することはないのでエスケープも必要ない)。

テスト用のクライアント。

require "socket"

TCPSocket.open("localhost", 7070) do |socket|
  socket.puts ARGV[0]
  puts socket.gets.gsub(" ", "\n").chomp
end

POStagの対応表はPenn Treebank P.O.S. Tagsが見やすい。また、chunktagについてはIOB2フォーマットによるトークンへのタグ付与がわかりやすいと思う。

2010年5月18日火曜日

Ubuntuでゴミ箱を空にできないときは

原因はまったくわからないのだけど、ゴミ箱を空にできなくなることが時々ある。ゴミ箱の中のファイルは~/.local/share/Trash/files/に置かれているので、

% rm -rf ~/.local/share/Trash/files/*
% rm ~/.local/share/Trash/info/*

などとすれば、強制的に空にすることができる。~/.local/share/Trash/info/には、削除前のパスや削除日時などの情報が記録されているので一緒に消してしまえばいい。