mots quotidiens. | |
Daichi Mochihashi (持橋大地) daichi <at> ism.ac.jp | by hns, version 2.10-pl1. |
|
|||||||||||||||||||||||||||||||||||||||||||||||
さて, 潜在語言語モデルは, NLPの立場からは観測値のnグラムをそのまま使うのでは
なく, 「真のnグラム」を推定して, そこから観測語が生まれたと考えるモデル
ですが, この学習は言うほど簡単ではありません。
各単語について数万次元(=語彙次元)の隠れ変数が存在するため, EMアルゴリズムで
Forward-Backwardを使おうとすると, 数億を超える組み合わせのテーブルを計算する
ことになってしまうため不可能で, Gibbsで局所的に潜在語をサンプリングして学習
していくことになります。
*1
ただしこの時も, ナイーブにはコーパスの各語に対して数万個ある潜在語候補の確率
を求める必要があり, 語彙が多いときわめて遅くなります。
実際, 上のコードで learn.cpp や decode.cpp の中にある slice_gibbs_draw()
を gibbs_draw() に変えると「サンプリングの耐えられない遅さ」
というどこかの小説のタイトルのような感じになりますので,
試してみると面白いかもしれません。
HPYLMの場合, nグラムが内部的には1グラム-2グラム-3グラムと樹構造になっています が, スライスがPY過程の「バックオフ係数」にあたる (θ+d*tu)/(θ+nu)より大きかった場合, 木を上にバックオフしてもスライスより確率の高い候補は 現れないため, 比較的効率的にサンプリングの候補を計算することができます。
..が, 実際やってみると, 特に名詞が来る位置で, 1グラムまでバックオフして
スライスを超える候補を見つける必要があることが多いことがわかりました。
1グラム(木のルート)には全ての単語が存在しているため, スライス s を超える確率
を持った単語を探すためには, ここで数万個の候補をなめる必要が生じてしまいます。
ユニグラムが頻度順に並んでいたりすれば枝刈りは容易ですが, LWLMではnグラム自体
がサンプリングされた潜在語によって動的に書き換わるため, そうした静的な性質は
期待できません。
よく考えると, 完全に単語が頻度順に並んでいる必要はなく, 枝刈りができる程度に
ソートされていればよいので, 少し考えて, 頻度が 2^n 以下になる境界だけを配列で
コンパクトに持つことに。
頻度が1増減する毎に, それが2^nになっているかどうか調べ
(これは二の補数表現を使うと, record.cpp の pow2() というトリッキーなコードで
高速に調べられます),
2^nになった/そこから減った場合は swap を行って境界の値を書き換えます。
さらにメタ関数 foreach を書いて, 2^n境界を使って頻度の高い順からアイテムに
関数ポインタで受け取った関数を実行する Lisp 的な関数を定義しました。
正直これを正しく, かつ美しく実装するのに3日かかりました。。(record.cpp)
効果は劇的で, ここまでやって初めて, 語彙の数にそれほど依存せずに高速な学習
ができるようになりました。長かった。。
最近, Phil Blunsomがslice samplingを使って Synchronous grammar の構文木を
サンプリングするという話を出しているようですが(NAACL 2010), 莫大な候補から
効率的にサンプリングするという意味では, 似たところがあるかもしれません。
タイトル一覧 |