Ngram言語モデルメモ

はじめに

現在よく使われていると思われる確率的言語モデルについて簡単に調べてみたのでメモ。

Ngram言語モデルとは

  • 例えば、「お酒が飲みたい」と「バリウムが飲みたい」という文章があった時に、前者の方がよく聞く文章で、後者はほとんど聞かない文章
  • 上記のような「文章の出やすさ」を数学的モデルで表現したい
  • 単語列w^n=w_1 w_2 ... w_nが与えられたとき、その単語列の生起確率P(w^n)
  • P(w^n)=P(w_1) P(w_2|w_1) P(w_3|w_1 w_2) \cdots P(w_n|w_1 w_2 ... w_{n-1})
    • 例えば「お酒/が/飲みたい」は、P(お酒が飲みたい)=P(お酒)*P(が|お酒)*P(飲みたい|お酒が)
  • しかし、P(単語|ながーい文章)を求めるのは実際には難しい
    • 単語の種類がmで単語列の長さがnならば、m^n通りをすべて計算して値を推定しなければならない→無理
  • Ngram言語モデルは、「各単語の生起確率は、直前の(N-1)単語までのみに依存する」モデル(Markovモデル)
    • 2gram3gramモデルなら、「今日/の/お昼/は/パスタ/です」はP(今日のお昼はパスタです)=P(今日)*P(の|今日)*P(お昼|今日の)*P(は|のお昼)*P(パスタ|お昼は)*P(です|はパスタ)
  • 0gramモデルは、直前の単語に依存しない&全ての単語が等確率で生起するモデル
  • 1gramモデルは、その単語が現れる確率のみを考慮するモデル(順番は考えない)
  • 文頭文字$を考えて、P(今日|$$)*P(の|$今日)*P(お昼|今日の)*...とすれば統一的に扱える

Ngram確率の推定

  • 学習データとしていくつかの文章が与えられたとして、P(w_i|w_{i-k}...w_{i-1})を推定したい
最尤推定
  • 単語列w^nが学習データに現れる回数をC(w^n)とする
  • P_{ML}(w_n|w^{n-1}_{n-N+1})=\frac{C(w^n_{n-N+1})}{C(w^{n-1}_{n-N+1})}
    • P(単語|直前の単語列)=(「直前の単語列+単語」の出現回数)/(「直前の単語列」の出現回数)
    • 単語のN個組と(N-1)個組の相対頻度
  • 学習データ中に単語列が出てこなければ確率が0になってしまう
    • たまたま学習データにでてこなかっただけかもしれない、、、(実際は0ではない)
    • 学習データに出てこない単語列に対しても適切な推定値を与えたい(スムージング、平滑化)
加算スムージング
  • 出現回数に一定の値を加えたものを使う
  • P(w_n|w^{n-1}_{n-N+1})=\frac{C(w^n_{n-N+1})+\delta}{C(w^{n-1}_{n-N+1})+\delta V}
    • \delta : 定数(0<δ<=1)、δ=1のときラプラス法と呼ばれるみたい
    • V : 単語列の異なり総数(Ngramのuniqな総数?)
  • 簡単だけど、他の手法に比べて精度が悪い
    • 全部同じオフセットじゃいろいろおかしい
線形補間法(Interpolation)
  • Ngramの確率値をMgram(N>M)で線形補間する
    • Interpolationでは、低次のngramは常に考慮される
  • P(w_n|w^{n-1}_{n-N+1})=\lambda P_{ML}(w_n|w^{n-1}_{n-N+1}) + (1-\lambda)P(w_n|w^{n-1}_{n-N+2})
  • 補間係数λの推定の手順
    • "学習データ"と、学習データとは異なる"評価データ"を用意する
    • 学習データからNグラム確率を求める
    • 評価データでの生成確率が最大になるようにEMアルゴリズムで各補間係数λiを最適化する
  • 補間係数の推定手法
    • ヘルドアウト補間法
      • 学習データを2つに分けて、片方をNグラム推定用、もう片方を補間係数推定用に使う
    • 削除補間法
      • 学習データをm個にわけて、j個目以外でNグラム推定して、j個目で補間係数を推定する(1個だけ取り出す方法はleaving-one-out法)
      • 各jについて求めた補間係数の平均値が収束するまで推定を繰り返す
バックオフ・スムージング(Back-off)
  • 学習データで出現するときはグッドチューリングの推定値を使って、出現しないときは(1-全ての出現する場合の推定値の和)を出現しない単語に均等に確率を分配する
    • Back-offでは必要に応じて低次のngramを使用する
  • C(w^n_{n-N+1})>0のとき、P(w^n_{n-N+1})=d_{C(w^n_{n-N+1})}P_{ML}(w_n|w^{n-1}_{n-N+1})
    • d_{C(w^n_{n-N+1})}は、ディスカウント係数
  • C(w^n_{n-N+1})=0のとき、P(w^n_{n-N+1})=\alpha(C(w^n_{n-N+1}) P(w_n|w^{n-1}_{n-N+2})
    • αは、ディスカウント係数を掛けた確率の和は1にならないので、その差分をC=0の単語列の生成確率に分配する関数
  • カッツ・スムージング
  • チャーチ・ゲイル・スムージング
ウィトン・ベル・スムージング
  • C(w^n_{n-N+1})>0のとき、P(w^n_{n-N+1})=\frac{C(w^n_{n-N+1})}{C(w^{n-1}_{n-N+1})+r(w^{n-1}_{n-N+1})}
  • C(w^n_{n-N+1})=0のとき、P(w^n_{n-N+1})=\frac{r(w^{n-1}_{n-N+1})}{C(w^{n-1}_{n-N+1})+r(w^{n-1}_{n-N+1})}
    • r(w^{n-1}_{n-N+1})は、単語列w^{n-1}_{n-N+1}の後に出現した異なり単語数
      • 「"I like pen"、"I like apple"、"I like pen"」が出現したならr(I like)=2
ワン・カウント法
  • 単語の生起にディレクレ分布を仮定
  • 性能がよいらしい(特にtrigram)
  • P(w^n_{n-N+1})=\frac{C(w^n_{n-N+1})+\alpha P(w_n|w^{n-1}_{n-N+2})}{C(w^{n-1}_{n-N+1})+\alpha}
    • \alpha=\gamma ( N_1(w^{n-1}_{n-N+1})+\beta )
      • \gamma,\betaは、定数
      • N_1(w^{n-1}_{n-N+1})は、C(w^n_{n-N+1})=1であるような単語列の数
Kneser-Neyスムージング
  • かなり高い性能を持つスムージング手法
    • 性能的に一番は「改良Kneser-Neyスムージング」らしい

その他のNグラムモデルの改良版など

  • Nクラスモデル
    • 単語をクラス(カテゴリやクラスタ)にわけて、クラスの生起確率とクラスからの文字の生起確率を考える
  • キャッシュモデル
    • 直前に使われた単語は再び使われやすいという性質を取り入れたモデル
  • トリガーモデル
    • 距離のはなれた単語間の共起関係を取り入れたモデル
  • 可変長Ngramモデル
    • Nを可変にすること(単語に応じて直前の何単語を見るかを変えること)で、モデルの信頼性を失わず、精度を向上させることができるモデル
  • 階層的ベイズ言語モデル(ベイズ階層言語モデル)
  • 階層的ディレクレ言語モデル
    • ディレクレ分布を仮定した階層的ベイズ言語モデル
    • 単語のpower-lowな性質を考慮できてない
  • 階層的Pitman-Yor言語モデル(Kneser-Neyスムージングの近似)
  • Nested Pitman-Yor言語モデル