Генерация текстов на основе частотного анализа символьных k-грамм


 

         В этой статье мы обсудим генерацию псевдо-случайного «осмысленного» текста на основе исходного текстового образца. Генерация текста по образцу подразумевает наличие осмысленного текстового источника (книги, статьи и т.д.), анализ которого позволит синтезировать текст с аналогичными стилем и лексикой. Слово «осмысленный» взято в кавычки, поскольку такая характеристика является условной и не подразумевает (в данной задаче) построения логически связанных цепочек словосочетаний и предложений, подчиняющихся определенной тематике. В нашем случае под «осмысленностью»  будем понимать генерацию реально существующих слов, ненулевое количество грамматически согласованных словосочетаний и  случаев корректной пунктуации.

В основе приведенного ниже алгоритма лежит принцип понимания текста как совокупности символьных 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 подряд идущих слов будут грамматически согласованы.