什么是ngram计数以及如何使用nltk实现?

时间:2012-10-10 14:01:09

标签: python nlp nltk

我读过一篇使用ngram计数作为分类器特征的论文,我想知道这究竟意味着什么。

示例文本:“Lorem ipsum dolor sit amet,consetetur sadipscing elitr,sed diam”

我可以在本文中创建unigrams,bigrams,trigrams等,在这里我必须定义创建这些unigrams的“级别”。 “级别”可以是字符,音节,单词......

因此,从上面的句子中创建unigrams只会创建所有单词的列表?

创建双字母组合会导致单词对将相互跟随的单词组合在一起吗?

因此,如果论文谈论ngram计数,它只会在文本中创建unigrams,bigrams,trigrams等,并计算ngram发生的频率?

python的nltk包中是否存在现有方法?或者我是否必须实现自己的版本?

4 个答案:

答案 0 :(得分:18)

我发现了我的旧代码,也许它很有用。

import nltk
from nltk import bigrams
from nltk import trigrams

text="""Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ornare
tempor lacus, quis pellentesque diam tempus vitae. Morbi justo mauris,
congue sit amet imperdiet ipsum dolor sit amet, consectetur adipiscing elit. Nullam ornare
tempor lacus, quis pellentesque diam"""
# split the texts into tokens
tokens = nltk.word_tokenize(text)
tokens = [token.lower() for token in tokens if len(token) > 1] #same as unigrams
bi_tokens = bigrams(tokens)
tri_tokens = trigrams(tokens)

# print trigrams count

print [(item, tri_tokens.count(item)) for item in sorted(set(tri_tokens))]
>>> 
[(('adipiscing', 'elit.', 'nullam'), 2), (('amet', 'consectetur', 'adipiscing'), 2),(('amet', 'imperdiet', 'ipsum'), 1), (('congue', 'sit', 'amet'), 1), (('consectetur', 'adipiscing', 'elit.'), 2), (('diam', 'tempus', 'vitae.'), 1), (('dolor', 'sit', 'amet'), 2), (('elit.', 'nullam', 'ornare'), 2), (('imperdiet', 'ipsum', 'dolor'), 1), (('ipsum', 'dolor', 'sit'), 2), (('justo', 'mauris', 'congue'), 1), (('lacus', 'quis', 'pellentesque'), 2), (('lorem', 'ipsum', 'dolor'), 1), (('mauris', 'congue', 'sit'), 1), (('morbi', 'justo', 'mauris'), 1), (('nullam', 'ornare', 'tempor'), 2), (('ornare', 'tempor', 'lacus'), 2), (('pellentesque', 'diam', 'tempus'), 1), (('quis', 'pellentesque', 'diam'), 2), (('sit', 'amet', 'consectetur'), 2), (('sit', 'amet', 'imperdiet'), 1), (('tempor', 'lacus', 'quis'), 2), (('tempus', 'vitae.', 'morbi'), 1), (('vitae.', 'morbi', 'justo'), 1)]

答案 1 :(得分:3)

当你计算n-gram时,最好使用哈希表(字典)而不是使用计数。对于上面的例子:

unigrams = {}
for token in tokens:
  if token not in unigrams:
    unigrams[token] = 1
  else:
    unigrams[token] += 1

这给你时间复杂度O(n)

答案 2 :(得分:1)

有一个名为Collocations in NLTK的概念。

您可能会发现它很有用。

答案 3 :(得分:-1)

我认为nltk中没有特定的方法来帮助解决这个问题。但这并不难。如果你有一个n个单词的句子(假设你正在使用单词级别),那么获取长度为1-n的所有ngrams,遍历这些ngrams中的每一个并使它们成为关联数组中的键,其值为count。不应超过30行代码,您可以为此构建自己的包,并在需要时导入它。