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

2024-04-28 11:35:52 发布

您现在位置:Python中文网/ 问答频道 /正文

this documentation中,有使用nltk.collocations.BigramAssocMeasures()BigramCollocationFindernltk.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)

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

如何使用AbstractCollocationFinder中的方法(例如nbest())和NgramAssocMeasures中的方法来处理4-gram、5-gram、6-gram、…、n-gram(比如容易使用bigram和trigram)?

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

谢谢。


Tags: 方法示例findertrigramgrampminltkbigram
2条回答

如果您想找到超过2或3克的克,可以使用scikit package和Freqdist函数来获取这些克的计数。我试着用nltk.collaborations做这个,但是我认为我们不能找到超过3克的分数。所以我决定用克数。我希望这能帮你一点忙。谢谢

这是密码

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

这将输出为

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, ...>

编辑

当前的NLTK有一个最多可用于^{}的硬编码函数,但是为什么不能简单地创建NgramCollocationFinder的原因仍然存在,您必须从根本上更改from_words()函数中用于不同顺序ngram的公式。


简而言之,不,如果您想找到超过2和3克的搭配,就不能简单地创建一个AbstractCollocationFinder(ACF)来调用nbest()函数。

这是因为不同ngram的from_words()不同。您可以看到,只有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'

因此,在TrigramCF中给定这个from_words()

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)

你可以通过某种方式破解它,并尝试对4克关联查找器进行硬编码,如下所示:

@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)

然后还必须更改代码中分别使用from_words返回的cls的任何部分。

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

  • 如果你想在更大的单词搭配中检索单词 超过2或3克的视窗,那么你会得到很多 在你的单词检索中有噪音。

  • 如果你打算用2建立一个基于搭配模式的模型 或者3grams窗口,那么你也将面临稀疏性问题。

相关问题 更多 >