私はn-gramの大きなコーパスといくつかの外部n-gramを持っています。このコーパス(カウント)に基づいて、各外部n-gramのPMIスコアを計算したいと思います。
これを行うためのツールはありますか、または誰かがこれを行うことができるPythonのコードを私に提供できますか?
問題は、私のnグラムが2グラム、3グラム、4グラム、および5グラムであるということです。したがって、3グラム以上の確率の計算には本当に時間がかかります。
私があなたの問題を正しく理解しているなら、 log { P("x1 x2 x3 x4 x5") / P("x1") P("x2") ... P("x5") } のようなものを計算したいでしょう。ここで、P は、任意の 5 グラムまたは 1 グラムが特定のものである確率を測定します (基本的には、おそらくラプラス スタイルのオフセットを使用したカウントの比率です)。したがって、コーパスを介して単一のパスを作成し、(1) 各 1 グラム、(2) 各 n グラム (後者には dict を使用) のカウントを格納してから、外部 n グラムごとにいくつかの dict を実行します。ルックアップ、ちょっとした算術、これで終わりです。最初にコーパスを 1 回通過し、次に外部 n-gram ごとに一定量の作業を行います。
(注: 実際には、3 つ以上の確率変数の PMI をどのように定義するのかわかりません。おそらく、log P(a)P(b)P(c)P(abc) / P(ab)P(bc) のようなものです。 P(a_c).しかし、それがこれらの線に沿ったものである場合は、同じ方法で行うことができます: コーパスを繰り返して、多くのものを数えます.必要なすべての確率は、おそらくラプラスを使用して、単純にカウントの比率になります.あらあら訂正。)
コーパスが大きすぎて n-gram dict をメモリに収めることができない場合は、それをメモリサイズのチャンクに分割し、各チャンクの n-gram dict を計算し、それらをディスクに保存できる形式で保存します。任意の n グラムのエントリを合理的に効率的に取得します。次に、extern n-gram ごとに、チャンクを調べてカウントを合計します。
どんな形?君による。1 つの簡単なオプション: n-gram の辞書順 (注: 文字ではなく単語を扱う場合は、単語を数字に変換することから始めることをお勧めします。コーパスを 1 回事前にパスする必要があります。これ); 次に、必要な n-gram を見つけるには、バイナリ検索またはそのようなものを使用します。これは、サイズが 1 GB のチャンクでは、チャンクあたり 15 ~ 20 シーク程度のどこかを意味します。これを減らすために、インデックスを追加することができます。または: Berkeley DB などで、ディスク上のハッシュ テーブルを使用します。その場合、チャンクを省略できます。または、アルファベットが小さい場合 (たとえば、これらは単語の n-gram ではなく文字の n-gram であり、プレーンな英語のテキストを処理している場合)、直接検索を使用して大きな配列に格納するだけですが、その場合は、とにかく、すべてをメモリに収めることができます。