14

我读过一篇使用 ngram 计数作为分类器特征的论文,我想知道这到底是什么意思。

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

我可以从本文中创建一元、二元、三元等,我必须在其中定义创建这些一元的“级别”。“级别”可以是字符、音节、单词、...

那么从上面的句子中创建一元组只会创建一个所有单词的列表?

创建二元组会导致单词对将彼此跟随的单词组合在一起?

因此,如果论文谈到 ngram 计数,它只是从文本中创建 unigrams、bigrams、trigrams 等,并计算哪个 ngram 出现的频率?

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

4

4 回答 4

17

我找到了我的旧代码,也许它很有用。

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)]
于 2012-10-10T14:07:49.553 回答
3

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

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

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

于 2016-09-30T00:44:41.250 回答
1

NLTK 中有一个叫做搭配的概念。

您可能会发现它很有用。

于 2013-09-06T06:34:28.493 回答
-1

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

于 2012-10-10T14:06:59.093 回答