web-dev-qa-db-ja.com

NLTK-バイグラムの頻度を数える

これはPythonおよびNLTK初心者の質問です。

一緒に10回以上発生し、PMIが最も高いバイグラムの頻度を見つけたいと思います。

このために、私はこのコードで作業しています

def get_list_phrases(text):

    Tweet_phrases = []

    for Tweet in text:
        Tweet_words = Tweet.split()
        Tweet_phrases.extend(Tweet_words)


    bigram_measures = nltk.collocations.BigramAssocMeasures()
    Finder = BigramCollocationFinder.from_words(Tweet_phrases,window_size = 13)
    Finder.apply_freq_filter(10)
    Finder.nbest(bigram_measures.pmi,20)  

    for k,v in Finder.ngram_fd.items():
      print(k,v)

ただし、これによって結果が上位20に制限されることはありません。頻度が10未満の結果が表示されます。Pythonの世界は初めてです。

誰かがこれを変更してトップ20だけを取得する方法を指摘できますか?.

ありがとうございました

18
jainp

問題は、apply_freq_filterを使用しようとしている方法にあります。 Wordのコロケーションについて話し合っています。ご存知のように、単語のコロケーションは単語間の依存関係に関するものです。 BigramCollocationFinderクラスはAbstractCollocationFinderという名前のクラスを継承し、関数apply_freq_filterはこのクラスに属します。 apply_freq_filterは、一部のWordコロケーションを完全に削除することは想定されていませんが、他の関数がリストにアクセスしようとした場合に、フィルターされたコロケーションのリストを提供します。

なぜですか?コロケーションのフィルタリングが単にそれらを削除するだけの場合、ランダムな位置から単語を削除した後、適切に機能しない可能性比やPMI自体(コーパス内の他の単語に対する単語の確率を計算する)などの多くの確率測度があったと想像してください。与えられたコーパスで。与えられた単語のリストからいくつかのコロケーションを削除することにより、多くの潜在的な機能と計算が無効になります。また、削除する前にこれらすべての測定値を計算すると、ユーザーが結局必要としない可能性のある大量の計算オーバーヘッドが発生します。

さて、問題はapply_freq_filter functionを正しく使用する方法です。いくつかの方法があります。以下では、問題とその解決策を示します。

サンプルコーパスを定義し、それをあなたが行ったことと同様の単語のリストに分割しましょう。

Tweet_phrases = "I love iphone . I am so in love with iphone . iphone is great . samsung is great . iphone sucks. I really really love iphone cases. samsung can never beat iphone . samsung is better than Apple"
from nltk.collocations import *
import nltk

実験のために、ウィンドウサイズを3に設定しました。

Finder = BigramCollocationFinder.from_words(Tweet_phrases.split(), window_size = 3)
Finder1 = BigramCollocationFinder.from_words(Tweet_phrases.split(), window_size = 3)

比較のために、Finder1でのみフィルターを使用していることに注意してください。

Finder1.apply_freq_filter(2)
bigram_measures = nltk.collocations.BigramAssocMeasures()

今私が書く場合:

for k,v in Finder.ngram_fd.items():
  print(k,v)

出力は次のとおりです。

(('.', 'is'), 3)
(('iphone', '.'), 3)
(('love', 'iphone'), 3)
(('.', 'iphone'), 2)
(('.', 'samsung'), 2)
(('great', '.'), 2)
(('iphone', 'I'), 2)
(('iphone', 'samsung'), 2)
(('is', '.'), 2)
(('is', 'great'), 2)
(('samsung', 'is'), 2)
(('.', 'I'), 1)
(('.', 'am'), 1)
(('.', 'sucks.'), 1)
(('I', 'am'), 1)
(('I', 'iphone'), 1)
(('I', 'love'), 1)
(('I', 'really'), 1)
(('I', 'so'), 1)
(('am', 'in'), 1)
(('am', 'so'), 1)
(('beat', '.'), 1)
(('beat', 'iphone'), 1)
(('better', 'Apple'), 1)
(('better', 'than'), 1)
(('can', 'beat'), 1)
(('can', 'never'), 1)
(('cases.', 'can'), 1)
(('cases.', 'samsung'), 1)
(('great', 'iphone'), 1)
(('great', 'samsung'), 1)
(('in', 'love'), 1)
(('in', 'with'), 1)
(('iphone', 'cases.'), 1)
(('iphone', 'great'), 1)
(('iphone', 'is'), 1)
(('iphone', 'sucks.'), 1)
(('is', 'better'), 1)
(('is', 'than'), 1)
(('love', '.'), 1)
(('love', 'cases.'), 1)
(('love', 'with'), 1)
(('never', 'beat'), 1)
(('never', 'iphone'), 1)
(('really', 'iphone'), 1)
(('really', 'love'), 1)
(('samsung', 'better'), 1)
(('samsung', 'can'), 1)
(('samsung', 'great'), 1)
(('samsung', 'never'), 1)
(('so', 'in'), 1)
(('so', 'love'), 1)
(('sucks.', 'I'), 1)
(('sucks.', 'really'), 1)
(('than', 'Apple'), 1)
(('with', '.'), 1)
(('with', 'iphone'), 1)

Finder1に同じものを書くと、同じ結果が得られます。そのため、一見したところ、フィルターは機能しません。ただし、それがどのように機能するかを確認してください。秘訣はscore_ngramsを使用することです。

Finderscore_ngramsを使用すると、次のようになります。

Finder.score_ngrams (bigram_measures.pmi)

出力は次のとおりです。

[(('am', 'in'), 5.285402218862249), (('am', 'so'), 5.285402218862249), (('better', 'Apple'), 5.285402218862249), (('better', 'than'), 5.285402218862249), (('can', 'beat'), 5.285402218862249), (('can', 'never'), 5.285402218862249), (('cases.', 'can'), 5.285402218862249), (('in', 'with'), 5.285402218862249), (('never', 'beat'), 5.285402218862249), (('so', 'in'), 5.285402218862249), (('than', 'Apple'), 5.285402218862249), (('sucks.', 'really'), 4.285402218862249), (('is', 'great'), 3.7004397181410926), (('I', 'am'), 3.7004397181410926), (('I', 'so'), 3.7004397181410926), (('cases.', 'samsung'), 3.7004397181410926), (('in', 'love'), 3.7004397181410926), (('is', 'better'), 3.7004397181410926), (('is', 'than'), 3.7004397181410926), (('love', 'cases.'), 3.7004397181410926), (('love', 'with'), 3.7004397181410926), (('samsung', 'better'), 3.7004397181410926), (('samsung', 'can'), 3.7004397181410926), (('samsung', 'never'), 3.7004397181410926), (('so', 'love'), 3.7004397181410926), (('sucks.', 'I'), 3.7004397181410926), (('samsung', 'is'), 3.115477217419936), (('.', 'am'), 2.9634741239748865), (('.', 'sucks.'), 2.9634741239748865), (('beat', '.'), 2.9634741239748865), (('with', '.'), 2.9634741239748865), (('.', 'is'), 2.963474123974886), (('great', '.'), 2.963474123974886), (('love', 'iphone'), 2.7004397181410926), (('I', 'really'), 2.7004397181410926), (('beat', 'iphone'), 2.7004397181410926), (('great', 'samsung'), 2.7004397181410926), (('iphone', 'cases.'), 2.7004397181410926), (('iphone', 'sucks.'), 2.7004397181410926), (('never', 'iphone'), 2.7004397181410926), (('really', 'love'), 2.7004397181410926), (('samsung', 'great'), 2.7004397181410926), (('with', 'iphone'), 2.7004397181410926), (('.', 'samsung'), 2.37851162325373), (('is', '.'), 2.37851162325373), (('iphone', 'I'), 2.1154772174199366), (('iphone', 'samsung'), 2.1154772174199366), (('I', 'love'), 2.115477217419936), (('iphone', '.'), 1.963474123974886), (('great', 'iphone'), 1.7004397181410922), (('iphone', 'great'), 1.7004397181410922), (('really', 'iphone'), 1.7004397181410922), (('.', 'iphone'), 1.37851162325373), (('.', 'I'), 1.37851162325373), (('love', '.'), 1.37851162325373), (('I', 'iphone'), 1.1154772174199366), (('iphone', 'is'), 1.1154772174199366)]

ここで、2の頻度にフィルタリングされたFinder1に対して同じものを計算するとどうなるかに注目してください。

Finder1.score_ngrams(bigram_measures.pmi)

および出力:

[(('is', 'great'), 3.7004397181410926), (('samsung', 'is'), 3.115477217419936), (('.', 'is'), 2.963474123974886), (('great', '.'), 2.963474123974886), (('love', 'iphone'), 2.7004397181410926), (('.', 'samsung'), 2.37851162325373), (('is', '.'), 2.37851162325373), (('iphone', 'I'), 2.1154772174199366), (('iphone', 'samsung'), 2.1154772174199366), (('iphone', '.'), 1.963474123974886), (('.', 'iphone'), 1.37851162325373)]

頻度が2未満のすべてのコロケーションがこのリストに存在しないことに注意してください。そしてそれはまさにあなたが探していた結果です。したがって、フィルターは機能しました。また、ドキュメントには、この問題に関する最小限のヒントが記載されています。

これがあなたの質問に答えたことを願っています。それ以外の場合は、お知らせください。

免責事項:主にツイートを扱っている場合、ウィンドウサイズ13は大きすぎます。お気づきの方もいらっしゃると思いますが、私のサンプルコーパスでは、サンプルツイートのサイズが小さすぎたため、ウィンドウサイズ13を適用すると、無関係なコロケーションが見つかる可能性があります。

23
user823743