Алгоритм с использованием soundex() или метафонов() для создания фраз стиля Mad Gab

Я пытаюсь создать алгоритм, который предложит фразы стиля Mad Gab.

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

  • цикл над фразами (символ по символу)
    • если найдено ключевое слово
      • сохранить ключевое слово и ответвление (рекурсия)
    • число символов приращения

Однако проблемы, с которыми я сталкиваюсь, следующие:

  • Учет для составных ключевых слов, например. "уловы" могут быть "уловы", "кошки" + "сыры".
  • Разрешить литературные термины - "the", "and", "one", "two", "three".
  • Как предложить термины, которые не являются ключевыми словами. то есть вернуться к чему-то вроде системного словаря, когда ключевые слова или литералы не могут быть найдены.
  • Пропустить фразовые сегменты. Сейчас он просто проходит. Но рассмотрим случай, когда фраза начинается с чего-то непревзойденного, но несколько символов позже содержат совпадения.

Я больше всего знаком с PHP и MySQL. Тем не менее, я открыт для другой технологии, если она обеспечивает лучшее решение.

Меня также интересуют любые дополнительные предложения. В частности, способы использования второго параметра metaphone() для более сложных предложений.

Ответы

Ответ 1

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

http://www.ewsdonline.org/education/components/scrapbook/default.php?sectiondetailid=7584

Если вам нужен более технический, совершенно точный способ, то был кандидат наук. диссертация о том, как это сделать:

http://www.tug.org/docs/liang/

Затем превратите каждый слог в фонетическое представление, используя либо что-то, что вы переворачиваете, либо метафоном(). Вы можете использовать аналогичный сайт, который объясняет правила звука гласных. Это будут только обобщения. Вы будете обрабатывать гласные отдельно от согласных, если вы откажетесь от своего. Метафон просто использует согласные, что хорошо, но не так круто, как если бы вы также принимали во внимание гласные.

Гласные: http://www.eslgold.com/pronunciation/english_vowel_sounds.html Согласные: http://usefulenglish.ru/phonetics/english-consonant-sounds

Затем у вас есть словарь английских слов для вашего слова банка. Существует много доступных словарей с открытым исходным кодом, которые можно вставлять в таблицу MySQL.

Начните с первого слога и найдите случайное слово в словаре, которое соответствует тесту soundex. Если вы не можете найти один (это, как правило, только одно слово слога), добавьте дополнительный слог и снова выполните поиск.

Пример:

"Логические последствия"

а. Разделение слога

"lo gi cal con sequence"

В. Применяемые звуковые эффекты

"lah gee cahl con видит айву"

С. Использованы звуки согласных

"lah jee kahl kon see quinse"

Д. Звуковой тест (один слог soundex - слишком легко угадать, но это доказывает концепцию)

"Закон Gee Call Con Sea Quints"

Soundex strcmp возвращает число. Поэтому, если вам нравится, вы можете получить значения soundex всего в своем банке слов заранее. Затем вы можете быстро запустить strcmp.

Пример сравнения Soundex MySQL:

выберите strcmp (soundex ('lah'), soundex ('law'));

Я думаю, что использование soundex для MySQL проще для вас, чем тест soundex для PHP, если вы хотите получить случайный результат из большой базы данных, и вы уже зафиксировали значение soundex в поле в вашей таблице словарей.

Мое предложение может быть неэффективным, но оптимизация - это другой вопрос.

Update:

Я не хотел подразумевать, что мое решение даст только одно слоговое слово. В качестве примера я использовал один слог, но если вы вместе взяли два слога, вы получите многосложные совпадения. Фактически, вы, вероятно, могли бы просто начать с того, что сбивали все слоги вместе и запускали soundex в mysql. Если вы найдете ответ, отлично. Но тогда вы можете откатывать слоги, пока не получите самый длинный матч. Затем вы останетесь с окончанием фразы и можете взять их вместе и выполнить совпадение. Я думаю, что суть решения ниже от другого автора, но я думаю, вам нужно избегать заклинивания всех букв без пробелов. По-английски вы потеряете информацию таким образом. Подумайте о фразе, начинающейся с "th" звука. Если вы смешаете фразу вместе, вы теряете, какой "th" звук необходим. "Термен" (инструмент) имеет другой "th" звук, чем "Там, мужчина".

Ответ 2

Принимая другой подход от решения Джонатана Барлоу, я рекомендую алгоритм O (n 2), который дает вам свойства, которые вы ищете, в случайности, надежности и масштабируемости. Сложность этого алгоритма может быть дополнительно улучшена в постоянное время или с оптимизацией модальности поиска, но поскольку размер ваших входных фраз гарантированно мал, это не так уж важно.

  • Создайте хеш-таблицу все известные слова в Оксфордском словаре английского языка и карту списков слов soundex() стоимость. Это изначально звучит сложно, пока вы не поймете, что на самом деле многие из них не используются в настоящее время. Предполагая достойный алгоритм одностороннего хэширования, это должно занимать несколько мегабайт, вершины.

  • Рассмотрим слова в вашей фразе ввода как одну сжатую строку символов без какой-либо текстовой идентификации, отбрасывая пробелы и все знаки пунктуации. Из этого пройдите пространство для всех длин символов, начиная с длины одного, до полной длины объединенной фразы минус одна. Для каждой строки, созданной этой прогулкой, выполните поиск хэша с OED. Когда встречается слово, которое присутствует в словаре, добавьте его слово и позицию в конец списка в памяти.

    (Этот проход всегда занимает время sum(n), которое по определению 2). Его пространственная сложность является наихудшим случаем O (n 2), но на практике полностью связным множеством термов является крайне маловероятно.)

  • Теперь наступает ваш слайдер сложности. Из подготовленного списка отрубите первый N% найденных терминов, где N - ваш уровень сложности. Принцип здесь заключается в том, что более легкие слова легче лексически обрабатывать, в то время как более длинные слова сложнее прозвучать и различать.

  • Постройте массив, соответствующий исходной длине фразы (без пробелов и знаков препинания) и перетасуйте список найденных слов. Теперь перейдите в перетасованный список. Для каждого элемента проверьте, свободны ли все слоты в массиве для этого слова в исходном положении. Если они есть, сохраните слово и его положение, отметив слоты, используемые в массиве. Если это не так, повторите следующее слово до тех пор, пока список не будет исчерпан. *

  • Из конечного выходного массива создайте разбитый список неиспользуемых символов в пространстве, рассматривая каждый мешок символов как свою собственную фразу. Для этого списка выполните обнаружение слога точно так, как показано здесь, передав результаты metaphone() с процентной вероятностью сближения двух или более слогов вместе. Затем, для сумки выходных словарных слов из 4., выполните soundex(), потянув случайное слово из списка сопоставленных слов сопоставимых значений soundex. Для каждого слова, которое может только soundex() для себя согласно карте поддержки списков, выполните разбиение на разделы и metaphone(). Наконец, сшиваем два списка результатов вместе, сортируя по позиции и печатая результат.

Это случайный алгоритм с тем, что, как я считаю, является всеми желаемыми свойствами, но он все еще груб в моем сознании.


  * Дополнительный кредит: определите допустимые совпадения для вашей системы по характеру или слогу. Это может привести к еще большей гамме принятых выходных фраз и значительно более высокого уровня сложности.