如果您查看用于拟合语言模型的代码,您会发现其核心fit()
是根据以下文档更新计数train_data
:
self.counts.update(self.vocab.lookup(sent) for sent in text)
但是,请注意,它一次更新一个句子的计数。每个句子都是完全独立的。该模型不知道该句子之前的内容或之后的内容。另外,请记住,您正在训练三元组模型,因此每个句子中的最后两个单词是('</s>', '</s>')
. 因此,模型以非常高的概率学习到 ,但它从不学习有时可以跟随'</s>'
的。'</s>'
'</s>'
'<s>'
所以解决你的问题最简单的方法就是generate()
每次看到时手动开始一个新句子(即再次调用)'</s>'
。但是,假设您不想这样做,并希望模型一次生成多个句子。
从文档字符串中padded_everygram_pipeline
:
Creates two iterators:
- sentences padded and turned into sequences of `nltk.util.everygrams`
- sentences padded as above and chained together for a flat stream of words
所以不像train_data
,padded_sents
包含你所有的句子作为一个条目:
>>> tokenized_text= [['this', 'is', 'sentence', 'one'],
['this', 'is', 'sentence', 'two']
]
>>> train_data, padded_sents = padded_everygram_pipeline(n, tokenized_text)
>>> padded_sents = list(padded_sents) #we need to do this because padded_sents is a generator and can only be gone through once
>>> print(padded_sents)
['<s>', '<s>', 'this', 'is', 'sentence', 'one', '</s>', '</s>', '<s>', '<s>', 'this', 'is', 'sentence', 'two', '</s>', '</s>']
>>> model = MLE(n)
>>> model.fit(padded_sents, padded_sents) #notice that I'm not using train_data
好消息:我们现在有一个'<s>'
以下示例'</s>'
。坏消息:包含两个不同句子的 ngram 的唯一可能三元组是('</s>', '</s>', '<s>')
和('</s>', '<s>', '<s>')
。所以 generate 现在应该生成多个句子,但是这些句子的内容仍然是完全独立的。
如果你想让上一句的内容影响下一句的内容,那就是事情开始变得复杂的地方。与其将语料库作为一系列句子传递给模型,不如将其作为一系列段落传递,每个段落包含多个句子:
tokenized_text = [['this', 'is', 'sentence', 'one', '.', 'this', 'is', 'sentence', 'two', '.'],
['this', 'is', 'a', 'second', 'paragraph', '.']
]
那会起作用,但是现在并不意味着句子的开头和结尾,它们意味着段落的开头和结尾'<s>'
。'</s>'
并且生成的段落仍然是相互独立的。您还可以将其扩展为生成一系列段落或整本书,而不是段落。这取决于什么最适合您的任务。