如何在python nltk中获得n-gram搭配和关联?

Fah*_*zal 6 python nlp nltk n-gram collocation

这个文件中,使用的例子nltk.collocations.BigramAssocMeasures(),BigramCollocationFinder,nltk.collocations.TrigramAssocMeasures(),和TrigramCollocationFinder.

对于bigram和trigram,有基于pmi的示例方法find nbest.例:

finder = BigramCollocationFinder.from_words(
...     nltk.corpus.genesis.words('english-web.txt'))
>>> finder.nbest(bigram_measures.pmi, 10)
Run Code Online (Sandbox Code Playgroud)

我知道BigramCollocationFinderTrigramCollocationFinder继承自AbstractCollocationFinder.While BigramAssocMeasures()TrigramAssocMeasures()继承自NgramAssocMeasures.

如何使用该方法(例如nbest())在AbstractCollocationFinderNgramAssocMeasures4克,5克,6克,...,的n-gram(例如使用二元和三元语法容易)?

我应该创建继承的类AbstractCollocationFinder吗?

谢谢.

Gun*_*jan 9

如果你想找到超过2或3克的克,你可以使用scikit包和Freqdist函数来计算这些克数.我尝试用nltk.collocations做这个,但我不认为我们可以找到超过3克的分数.所以我宁愿决定克数.我希望这可以帮到你一点点.Thankz

这是代码

from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizer
from nltk.collocations import *
from nltk.probability import FreqDist
import nltk

query = "This document gives a very short introduction to machine learning problems"
vect = CountVectorizer(ngram_range=(1,4))
analyzer = vect.build_analyzer()
listNgramQuery = analyzer(query)
listNgramQuery.reverse()
print "listNgramQuery=", listNgramQuery
NgramQueryWeights = nltk.FreqDist(listNgramQuery)
print "\nNgramQueryWeights=", NgramQueryWeights
Run Code Online (Sandbox Code Playgroud)

这将输出为

listNgramQuery= [u'to machine learning problems', u'introduction to machine learning', u'short introduction to machine', u'very short introduction to', u'gives very short introduction', u'document gives very short', u'this document gives very', u'machine learning problems', u'to machine learning', u'introduction to machine', u'short introduction to', u'very short introduction', u'gives very short', u'document gives very', u'this document gives', u'learning problems', u'machine learning', u'to machine', u'introduction to', u'short introduction', u'very short', u'gives very', u'document gives', u'this document', u'problems', u'learning', u'machine', u'to', u'introduction', u'short', u'very', u'gives', u'document', u'this']

NgramQueryWeights= <FreqDist: u'document': 1, u'document gives': 1, u'document gives very': 1, u'document gives very short': 1, u'gives': 1, u'gives very': 1, u'gives very short': 1, u'gives very short introduction': 1, u'introduction': 1, u'introduction to': 1, ...>
Run Code Online (Sandbox Code Playgroud)


alv*_*vas 6

已编辑

当前的 NLTK 有一个硬编码器函数,QuadCollocationFinder但对于为什么不能简单地创建NgramCollocationFinder静止支架的原因,您必须从根本上更改from_words()函数中不同顺序的 ngram 的公式。


简短的回答,不,如果您想找到超过 2-gram 和 3-gram 的搭配,您不能简单地创建一个AbstractCollocationFinder(ACF) 来调用该nbest()函数。

这是因为from_words()不同的 ngrams 的差异。你看到只有ACF的子类(即BigramCF和TrigramCF)才有这个from_words()功能。

>>> finder = BigramCollocationFinder.from_words(nltk.corpus.genesis.words('english-web.txt'))
>>> finder = AbstractCollocationFinder.from_words(nltk.corpus.genesis.words('english-web.txt',5))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'AbstractCollocationFinder' has no attribute 'from_words'
Run Code Online (Sandbox Code Playgroud)

所以from_words()在 TrigramCF 中给出了这个:

from nltk.probability import FreqDist
@classmethod
def from_words(cls, words):
    wfd, wildfd, bfd, tfd = (FreqDist(),)*4

    for w1,w2,w3 in ingrams(words,3,pad_right=True):
      wfd.inc(w1)

      if w2 is None:
        continue
      bfd.inc((w1,w2))

      if w3 is None:
        continue
      wildfd.inc((w1,w3))
      tfd.inc((w1,w2,w3))

    return cls(wfd, bfd, wildfd, tfd)
Run Code Online (Sandbox Code Playgroud)

您可以以某种方式破解它并尝试为 4-gram 关联查找器进行硬编码:

@classmethod
def from_words(cls, words):
    wfd, wildfd = (FreqDist(),)*2
    bfd, tfd ,fofd = (FreqDist(),)*3

    for w1,w2,w3,w4,w5 in ingrams(words,5,pad_right=True):
      wfd.inc(w1)

      if w2 is None:
        continue
      bfd.inc((w1,w2))

      if w3 is None:
        continue
      wildfd.inc((w1,w3))
      tfd.inc((w1,w2,w3))

      if w4 is None:
        continue
      wildfd.inc((w1,w4))
      wildfd.inc((w2,w4))
      wildfd.inc((w3,w4))
      wildfd.inc((w1,w3))
      wildfd.inc((w2,w3))
      wildfd.inc((w1,w2))
      ffd.inc((w1,w2,w3,w4))

    return cls(wfd, bfd, wildfd, tfd, ffd)
Run Code Online (Sandbox Code Playgroud)

然后,您还必须更改使用clsfrom_words分别返回的代码的任何部分。

所以你要问,找到搭配的最终目的是什么?

  • 如果您正在寻找在大于 2 或 3 克窗口的搭配中检索单词,那么您最终会在单词检索中遇到很多噪音。

  • 如果您要使用 2 或 3 克窗口基于搭配模式构建模型,那么您还将面临稀疏问题。