Blog. Just Blog

Генератор текста на основе цепей Маркова

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
В web-строительстве и SEO цепи Маркова используются для генерации псевдоосмысленных текстов на основании исходных текстов. Это используется для штамповки дорвеев с заданными ключевыми словами, для набора контентной текстовой массы и тому подобным "черным" трюкам. К счастью, поисковые системы научились эффективно определять контент, созданный на основе цепей Маркова и отправляет таких умников в бан. Учить вас подобным технологиям я не собираюсь, для этого есть специальные говносайты, меня интересует только программная реализация алгоритма.


Цепью Маркова называется последовательность испытаний, в каждом из которых появляется только одно из k несовместных событий Ai из полной группы. При этом условная вероятность pij(s) того, что в s-ом испытании наступит событие Aj при условии, что в (s - 1) - ом испытании наступило событие Ai, не зависит от результатов предшествующих испытаний.


Желающие повзрывать свой головной мозг могут почитать про математическую модель. На человеческом языке все эти формулы сводятся к следующему. В исходном тексте определяются слова и сохраняется последовательность, какие слова идут за какими. Затем на основании этих данных создается новый текст, в котором сами слова выбраны случайно, но сохранены связи между ними. Для примера возьмем детский стишок:

Из-за леса, из-за гор
едет дедушка Егор:
сам на лошадке,
жена на коровке,
дети на телятках,
внуки на козлятках.

Разберем текст на звенья и связки

из-за [леса, гор]
леса [из-за]
гор [едет]
едет [дедушка]
дедушка [Егор]
Егор [сам]
сам [на]
на [лошадке, коровке, телятках, козлятках]
лошадке [жена]
жена [на]
коровке [дети]
дети [на]
телятках [внуки]
внуки [на]

Звенья в этом списке представляют собой уникальные слова из текста, а в квадратных скобках перечислены связи - список слов, которые могут располагаться после этого слова.

При генерации текста из списка звеньев на первой итерации выбирается случайное звено, определяются его связи, из списка связей выбирается случайная и принимается уже как новое звено. Затем действие повторяется до достижения нужного размера текста. В результате, например, может получиться что-то подобное:

Егор сам на телятках внуки на лошадке жена на коровке дети на коровке
В этом примере полученный текст мало отличается от исходного, так как исходный текст очень короткий. Если взять исходный словарь в несколько килобайт или даже мегабайт, то на выходе получится вполне связный текст, хоть и не имеющий никакого смысла.
  1. // Прочитать исходный текст, на основе которого будет генерироваться новый
  2. $str=file_get_contents('markov.txt');
  3.  
  4. // Установить кодировку системы
  5. setlocale(LC_ALL'ru_RU.CP1251');
  6.  
  7. // Убрать из текста символы кроме цифр, букв и некоторых знаков препинания
  8. $str=eregi_replace('[^-a-zа-я0-9 !\?\.\,]',' ',$str);
  9.  
  10. // Подчистить пробелы перед окончаниями предложений
  11. $str=eregi_replace(' {1,}([!\?\.\,])','\\1',$str);
  12.  
  13. // Поделить текст на слова
  14. $tmp=preg_split('/[[:space:]]+/is',$str);
  15.  
  16. // Массив "звеньев"
  17. $words=Array();
  18.  
  19. // Заполнить звенья
  20. for($i=0$i<count($tmp); $i++) {
  21.     if ($tmp[$i+1]!='') {
  22.         $words[$tmp[$i]][]=$tmp[$i+1];
  23.     }
  24. }
  25. $words=array_map('array_unique',$words);
  26.  
  27. // Массив начальных слов в предложениях
  28. $start=Array();
  29.  
  30. foreach($words as $word=>$links) {
  31.     if (ereg('^[А-Я][а-я]+',$word)) {
  32.         $start[]=$word;
  33.     }
  34. }
  35.  
  36. // Сгененировать 100 предложений на основе исходного текста
  37. for ($i=0$i<100$i++) {
  38.     while (true) {
  39.         $w=$start[rand(0,(count($start)-1))];
  40.         if (ereg('[\.!\?]$',$w)) { continue; }
  41.         $sentence=$w.' ';
  42.         // Количество слов в предложении
  43.         $cnt=1;
  44.         // Сгенерировать предложение
  45.         while(true) {
  46.             $links=$words[$w];
  47.             // Переключить цепочку
  48.             $w=$words[$w][rand(0,(count($words[$w])-1))];
  49.             $sentence.=$w.' ';
  50.             // Если слово находилось в конце предложения
  51.             if (ereg('[\.!\?]$',$w)) { break; }
  52.             $cnt++;
  53.             // Если генератор зациклился, то принудительно выйти 
  54.             if ($cnt>19) { break; }
  55.         }
  56.         // Удачным считать  предложение длиной 5-20 слов
  57.         if ($cnt>&& $cnt<20) { break; }
  58.     }
  59.     // Сгенерированное предложение
  60.     echo $sentence;
  61. }
Небольшие пояснения, как это все работает. Сперва загружается файл "markov.txt", он должен быть в кодировке win-1251. Затем из него удаляются все символы, кроме букв и некоторых знаков препинания, потом вырезаются излишние пробелы. Получается чистый текст, который затем разделяется на отдельные слова. Все, у нас есть отдельные звенья цепи. Теперь надо определить связи слов, то есть какие слова и за какими могут располагаться. Это самый ресурсоемкий процесс, так что на больших файлах придется запастись терпением. Если генерация требуется часто, то, наверное, имеет смысл сохранять массив звеньев и связок в какой-нибудь базе, чтобы иметь к нему быстрый доступ. Следующий шаг - определение слов, с которых начинаются предложения. Я принял условие, что у таких слов первая буква должна быть заглавной, вы можете сделать более точное определение. Генерация текста выполняется по описанному выше алгоритму, я только добавил к нему несколько проверок от зацикливания.

Рабочий пример генератора текстов на основе цепей Маркова и приведенного выше скрипта, можете посмотреть на сайте. Для генерации нового текста просто обновите страничку.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 21672 | Комментариев: 17

Метки: PHP, SEO
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Цитатахочу уехать отдыхать
Алла (26.11.2015 в 00:43):
А мне вот этот генератор текста нравиться [del]
Maks (06.12.2014 в 21:13):
но указание свыше...следить за порядком и спокойствием на форуме...и слишком буйных приструнять...
ManHunter (27.07.2011 в 20:35):
Вряд ли это мой труд. 6 кило в архиве такой скрипт занимать не может, да и размещен он на том сайте два года назад.
Locki (27.07.2011 в 10:10):
ManHunter вот как твоим умом пользуются некоторые недалекие, но охочие до наживы люди - [del] и хоть бы спасибо сказали...
timsky (12.03.2011 в 17:09):
Огромное спасибо за разжеваный на пальцах алгоритм и скрипт!
Давно интересовал этот алгоритм :)

А что если его модифицировать... интересно, каким макаром ПС вычисляют генереный текст?
jnpe (11.01.2011 в 07:37):
Прекрасно ))) забрал в коллекцию
ManHunter (20.12.2010 в 20:33):
Isaev, абсолютно ничего. Взят первый попавшийся текст с lib.ru и перелопачен по указанному алгоритму.
Isaev (20.12.2010 в 19:10):
//в него добавляются ключевые слова, типа названия компании
А что именно внедрено в "Рабочий пример"?
64-ядерный процессор (19.12.2010 в 21:29):
ManHunter, примерно понятно...
ManHunter (19.12.2010 в 14:26):
Не совсем так. Словосочетания не всевозможные, а только с учетом первоначальных связей. То есть в этом примере не может получиться "внуки из-за леса на лошадке", так как связи будут нарушены.
64-ядерный процессор (19.12.2010 в 14:10):
ManHunter, всё, я тебя понял короче. Ты хочешь сказать, что просто генерится из набора слов всевозможные сочетания?
ManHunter (19.12.2010 в 03:27):
Туда ей и дорога :)
ipSlicer (19.12.2010 в 03:13):
ManHunter, уже года 3 как эта SEO-технология почила в бозе (это я для тех, кто захочет ее на практике применить).
ManHunter (18.12.2010 в 13:07):
64-ядерный процессор, берется какой-нибудь исходный текст, лучше тематический, в него добавляются ключевые слова, типа названия компании, "купить холодильник", "лучший сервис" и т.п. Потом генерится 100500 страниц псевдотематического "уникального контента" и делается пачка дорвеев со ссылками на раскручиваемый сайт. Никогда разве в гуглояндексах не натыкался на такие "сайты"?
64-ядерный процессор (18.12.2010 в 10:09):
ManHunter, можешь привести примеры использования этого скрипта?
kruvas (18.12.2010 в 07:41):
похоже с помощью такого генератора сейчас печатают макулатуру для чтения в поездах - всякие детективы и прочую ерунду...

для интереса надо текстовую версию войны и мира прогнать.. а еще лучше мертвые души и выпустить второй том :)

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2016
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.0033 сек.) / Память: 4.25 Mb
Наверх