« 2007年06月 | メイン | 2007年10月 »

2007年07月29日

IMEにおける「文節」とは何ぞや

とあるIME開発者と仮名漢字変換(IME)における「文節」についてディスカッションする 機会がありました。今まであまり真剣に考えたことなかったのですが、 この「IME文節」、いろんな意味で興味深いということを改めて認識しました。

学校文法や自然言語処理におけるいわゆる「文節」とは 統語的な性質からほぼ一意に決定できる単位です。 簡単には 自立語連続+付属語 と言えるでしょう。

たとえば、 「東京特許許可局で工藤は講演をした。」 は

東京特許許可局で|工藤は|講演した。

の3文節になります。小学校のときに「~ね」を挿入できる単位として 習ったかと思います。

しかし、IMEで上記の文を変換してみると。

東京|特許|許可局で|工藤は|講演した|。

と分割されます。(WinXP) あきらかにNLP業界の文節と単位が異なるようです。

このIMEが使っている分割の単位を「IME文節」と呼ぶことにしましょう。

さてここでの問題は、「最適なIME文節の分割単位は何か」ということです。 少なくとも形態素でもなく学校文法での文節でもなさそうです。

IMEの究極の目標はユーザがストレスなく日本語を入力できることにあります。 ストレスを感じさせないような単位が最適IME文節といえますが、これでは あまりにも抽象すぎます。

IME文節の単位が形態素単位ぐらいに短いとどういうことが起きるでしょうか。 付属語(助詞や助動詞)のように変換のあいまい性がほとんどない場合でも、 ユーザに1つづ正解をたずねる必要があります。これはこれでストレスがたまります。

逆に、学校文法の文節ぐらい長くなると、変換がますます困難になり、変換候補の数が 指数的に増えていきます。IMEは数件しか変換候補を出さ(せ)ないため、その中に 適切な候補が入らなくなるかもしれません。これもストレスがたまります。

余談ですが、アドバンスユーザは自然にこのIME文節の単位で入力している気がします。 自ら最適単位で入力しているため、ストレスを最小限に抑えることができます。

工学的には、IMEの変換候補の最大表示数を n とするならば、ある文節の変換候補 の平均分割数(perplexity) が n を超えない程度の長さが最適な文節長といって いいと思います。

さて、ajaximeのように言語モデルベースで動いているIMEの場合、どのように 実装すればいいのでしょうか。あるひらがな文節 w が、複数の 変換候補 y1..yk に変換されるとします。言語モデル的を使った場合、y_1, y_2 .. y_k に変換される確率 p(y_k|input) は BaumWeltch と周辺尤度を使えば簡単に 計算できます。あとは、これの perpleixty、すなわち 2^{ - sum_{k} log(p(y_k|input)) } が平均分割数です。

これがうまくいくかどうかは謎ですが、少なくとも、IMEの文節はユーザのストレス を最小限にするように定義する必要があるようです。いわれてみればすごく当たり前の ことなんですが。

投稿者 taku : 17:23 | トラックバック

2007年07月09日

CRF++ 0.48

CRF++ 0.48を公開しました。L1-norm 正則化を追加しただけです。

http://crfpp.sourceforge.jp/

投稿者 taku : 00:48 | トラックバック

2007年07月08日

AjaxIMEのHTTPサーバは pre-pthread

C++と Pthreads でミニマルなHTTPサーバを書く にて、ネットワークサーバのさまざまな設計・実装方針がまとめられています。

   1. クライアントごとに fork
   2. 事前に fork - 各プロセスで accept
   3. 事前に fork - ファイルロックで accept を保護
   4. 事前に fork - Mutex ロックで accept を保護 (PTHREAD_PROCESS_SHARED)
   5. 事前に fork - ソケットディスクリプタパッシング
   6. クライアントごとにスレッド生成
   7. 事前にスレッド生成 - Mutex ロックで accept を保護
   8. 事前にスレッド生成 - メインスレッドで accept

AjaxIMEの変換エンジンは自作サーバで運用しているのですが、初期の実装は prefork、 すなわち4番の実装でした。

その後、fork の部分を thread に変更した pre-pthread (7番) に変更しました。

最大の理由は、辞書リソースの有効活用です。MeCabは同一プロセス内で同一辞書ファイルを開く場合 に限り、辞書リソースを共有します。数千個インスタンスを作ろうが、mmap される辞書オブジェクトは 1つで済むので、メモリの消費を抑えることができます。

prefork の場合は、同一プロセスではなくなるため、複数のかな漢字変換インスタンスを作るとそれぞれ別の 辞書オブジェクトが生成されてしまいます。AjaxIMEのサーバはメモリを512Mしか積んでいないため 70MB程度の変換用辞書を4つも5つもコピーするわけにはいきません。

投稿者 taku : 00:41 | トラックバック