В этой статье мы обсудим генерацию псевдо-случайного «осмысленного» текста на основе исходного текстового образца. Генерация текста по образцу подразумевает наличие осмысленного текстового источника (книги, статьи и т.д.), анализ которого позволит синтезировать текст с аналогичными стилем и лексикой. Слово «осмысленный» взято в кавычки, поскольку такая характеристика является условной и не подразумевает (в данной задаче) построения логически связанных цепочек словосочетаний и предложений, подчиняющихся определенной тематике. В нашем случае под «осмысленностью» будем понимать генерацию реально существующих слов, ненулевое количество грамматически согласованных словосочетаний и случаев корректной пунктуации.
В
основе приведенного ниже алгоритма лежит принцип понимания текста как
совокупности символьных k-грамм. Символьная
k-грамма – это последовательность из k идущих
подряд символов (букв, знаков препинания, пробельных символов и т.д.) Например,
предложение «Превед, медвед.» можно разбить на 5-граммы следующим образом: «Преве»,
«ревед», «евед », «вед, », «ед, м», «д,
ме», «, мед», « медв», «медве», «едвед», «двед.». Естественным образом вводится
понятие частоты k-граммы, то есть отношение количества
вхождений данной k-граммы в исходный текст к общему
количеству k-грамм данного текста.
Генерируемый
текст выше назван псевдо-случайным, поскольку генерация текста заключается в
последовательном выборе подходящей k-граммы из
списка, извлеченного из исходного текста, и добавлении ее в конец нового текста.
Таким образом, новых k-грамм в
полученном тексте появиться не может.
Алгоритм генерации нового текста состоит из следующих шагов:
1. Составить словарь всех k-грамм исходного текста с подсчетом количества вхождений.
2. Случайным образом выбрать из списка одну k-грамму. Это будет начало нового текста. (Далее будем добавлять по одному символу к генерируемому тексту.)
3. Выделить из предыдущей k-граммы (k-1)-грамму, отбросив первый символ. В исходном списке всех k-грамм найти такие, которые начинаются на данную (k-1)-грамму.
4. Для каждой найденной на предыдущем шаге k-граммы посчитаем частоту среди всех найденных на предыдущем
шаге k-грамм.
(Например, на шаге 3 были получены следующие
3-граммы с указанием количества вхождений в исходный текст:
–
«пар»: 4
–
«пас»: 10
–
«пал»: 5
–
«пан»: 3.
Количество всех триграмм, начинающихся с «па», равно 22. Посчитаем их частоты:
6. Из списка найденных (в данном случае четырех) k-грамм выбираем k-грамму, соответствующую номеру диапазона. (Если случайное число попало в первый диапазон, то берем k-грамму «пар», если во второй – «пас» и т.д.). Последний символ выбранной k-граммы – это новый символ генерируемого текста.
7. Переходим к шагу 3 и повторяем шаги 3-6, пока не получим текст желаемого объема.
Таким
образом, мы посимвольно генерируем новый текст. Описанный подход позволяет
случайно выбирать следующий символ с учетом частотности появления символьных сочетаний
в осмысленном источнике.
Ниже приведем пример генерации текста на основе романа Германа Гессе «Игра в бисер» для k (количества символов в k-граммах) равного 3, 5 и 10.
k = 3 |
k = 5 |
k = 10 |
Видно,
что чем больше число k, тем
осмысленнее выглядит текст, однако новых слов и словосочетаний (которые отсутствуют
в исходном тексте) становится все меньше. Если для вашей задачи не принципиально
появление новых слов, полностью аналогичный алгоритм вы можете использовать для
словесных k-грамм, то есть для
последовательностей подряд идущих k
слов. Тогда на каждом шаге алгоритм будет
выдавать новое слово, и любые k подряд идущих слов будут грамматически согласованы.