Если вы посмотрите на код для подгонки языковой модели , вы увидите, что по своей сути fit()
делает обновление счетчиков на основе документов в train_data
:
self.counts.update(self.vocab.lookup(sent) for sent in text)
Однако обратите внимание, что он обновляет эти числа по одному предложению за раз. Каждое предложение полностью не зависит друг от друга. Модель не знает, что было до того предложения, а что после. Также помните, что вы тренируете модель триграммы, поэтому последние два слова в каждом предложении - ('</s>', '</s>')
. Следовательно, модель узнает, что за '</s>'
следует '</s>'
с очень высокой вероятностью, но никогда не узнает, что за '</s>'
иногда может следовать '<s>'
.
Так что самое простое решение вашей проблемы просто вручную начинать новое предложение (т.е. снова вызывать generate()
) каждый раз, когда вы видите '</s>'
. Но допустим, вы не хотите этого делать и хотите, чтобы модель генерировала несколько предложений в одном go.
Из строки документов для 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>'
. Плохая новость: единственными возможными триграммами, которые содержат нграммы для двух разных предложений, являются ('</s>', '</s>', '<s>')
и ('</s>', '<s>', '<s>')
. Таким образом, генерирование должно теперь генерировать несколько предложений, но содержание этих предложений будет по-прежнему полностью независимым.
Если вы хотите, чтобы содержание предыдущего предложения влияло на содержание следующего, то здесь все и начинается. сложно. Вместо того, чтобы передавать ваш корпус модели в виде серии предложений, вы можете передать ее в виде серии абзацев с несколькими предложениями в каждом:
tokenized_text = [['this', 'is', 'sentence', 'one', '.', 'this', 'is', 'sentence', 'two', '.'],
['this', 'is', 'a', 'second', 'paragraph', '.']
]
Это будет работать, но теперь '<s>'
и '</s>'
не означают начало и конец предложения, они означают начало и конец абзаца. И сгенерированные абзацы все равно будут независимы друг от друга. Вы также можете расширить это, чтобы вместо абзацев создавать серии абзацев или целые книги. Это зависит от того, что лучше всего подходит для вашей задачи.