使用 NLTK 构建字符级 Ngram 语言模型

Building a Character-Level Ngram Language Model with NLTK

我正在尝试使用 NLTK 的 KneserNeyInterpolated 函数在 character 级别构建语言模型。我所拥有的是 pandas 数据框中的单词频率列表,唯一的列是它的频率(单词本身就是索引)。根据单词的平均长度,我确定 9 克模型是合适的。

from nltk.lm.models import KneserNeyInterpolated

lm = KneserNeyInterpolated(9)
for i in range(df.shape[0]):
    lm.fit([list(ngrams(df.index[i], n = 9))])

lm.generate(num_words = 9)
# ValueError: Can't choose from empty population

调试尝试:

n = 9 # Order of ngram

train_data, padded_sents = padded_everygram_pipeline(4, 'whatisgoingonhere')
model = KneserNeyInterpolated(n) 
model.fit(train_data, padded_sents)

model.generate(num_words = 10)
# ['r', '</s>', '</s>', '</s>', '</s>', '</s>', '</s>', '</s>', '</s>', '</s>']

这行得通(我猜?),但我似乎无法将功能扩展到连续为语言模型训练新词,而且我仍然无法生成真实的词。我觉得我在这里遗漏了一些关于这个模块应该如何工作的基本知识。使这有点困难的是所有教程似乎都基于单词级 ngram。

您需要标记您的输入,除此之外,您的方法有效。

基本示例:

n = 3
train, vocab = padded_everygram_pipeline(n, 'whatisgoingonhere'.split())
model = KneserNeyInterpolated(n) 
model.fit(train, vocab)
model.generate(num_words = 10, random_seed=5)
# => ['i', 's', 'g', 'o', 'n', 'h', 'e', 'r', 'e', '</s>']

更真实的例子

如何转换输入取决于您使用的原始来源的类型。比方说,对于更现实的情况,您从文本中输入一系列单词:

from nltk.tokenize import word_tokenize

n = 3

# prep inputs
text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
tokenized = word_tokenize(text)
train, vocab = padded_everygram_pipeline(n, tokenized)

# fit model & generate word
model = KneserNeyInterpolated(n) 
model.fit(train, vocab)
model.generate(num_words=5, random_seed=5)
# => ['o', 'r', 'e', 's', 't']