python — Поиск префикса и суффикса ключевого слова с помощью pyparsing
Первая проблема связана с использованием вами оператора ‘&’. При pyparsing ‘&’ производит каждых
выражений, которые похожи на и
, но принимают подвыражения в любом порядке:
Word('a') & Word('b') & Word('c')
соответствует ‘aaa bbb ccc’, а также ‘bbb aaa ccc’, ‘ccc bbb aaa’ и т. д.0004 выражения. и
соответствуют нескольким подвыражениям, но только в заданном порядке.
Во-вторых, одной из причин использования pyparsing является принятие меняющихся пробелов. Пробелы являются проблемой для синтаксических анализаторов, особенно при использовании str.find
или регулярных выражений — в регулярных выражениях это обычно проявляется в виде множества \s+
фрагментов во всех выражениях соответствия. В вашем синтаксическом анализаторе pyparsing, если входная строка содержит «первый элемент»
(два пробела между «первым» и «элементом»), попытка сопоставить литеральную строку «первый элемент» завершится ошибкой.
Keyword
class, и пусть pyparsing пропустит все пробелы между ними. Чтобы упростить это, я написал короткий метод wordphrase
:def wordphrase(s): return And(map(Ключевое слово, s.split())).addParseAction(' '.join) ключевые слова = словосочетание («первый элемент») | wordphrase('второй элемент') печать(ключевые слова)
печатает:
{{"первый" "элемент"} | {"второй" "элемент"}}
указывает, что каждое слово будет проанализировано отдельно, с любым количеством пробелов между словами.
Наконец, вы должны написать парсеры pyparsing, зная, что pyparsing не делает никакого упреждающего просмотра. В вашем синтаксическом анализаторе префиксное выражение ZeroOrMore(Word(alphas))
будет соответствовать всем словам в «aa bb first item ee ff» — тогда не останется ничего, что соответствовало бы выражению ключевых слов, поэтому синтаксический анализатор не работает.
ZeroOrMore
для префиксных слов, которое переводится как «соответствовать каждому слову альфа, но сначала убедитесь, что мы не собираемся анализировать выражение ключевого слова». В pyparsing этот вид негативного просмотра реализуется с помощью NotAny
, который можно создать с помощью унарного оператора ~
. Для удобочитаемости мы будем использовать ключевых слова
выражения сверху:non_keyword = ~keywords + Word(alphas) a = ZeroOrMore(не_ключевое слово)('префикс') + ключевые слова('слово') + ZeroOrMore(Слово(альфа))('суффикс')
Вот полный синтаксический анализатор и результаты с использованием runTests для различных строк образцов:
def wordphrase(s): return And(map(Ключевое слово, s.split())).addParseAction(' '.join) ключевые слова = словосочетание («первый элемент») | wordphrase('второй элемент') non_keyword = ~ ключевые слова + слово (альфа) a = ZeroOrMore(не_ключевое слово)('префикс') + ключевые слова('слово') + ZeroOrMore(Слово(альфа))('суффикс') текст = """ # префикс и суффикс aa bb первый элемент ee ff # только суффикс первый пункт ee ff # только префикс аа бб первый пункт # без префикса или суффикса первый элемент # несколько пробелов в элементе, замененные одиночными пробелами в результате синтаксического анализа первый элемент """ a. runTests(текст)
Дает:
# префикс и суффикс aa bb первый элемент ee ff ['aa', 'bb', 'первый элемент', 'ee', 'ff'] - префикс: ['аа', 'бб'] - суффикс: ['ee', 'ff'] - слово: 'первый элемент' # только суффикс первый пункт ee ff ['первый элемент', 'ее', 'фф'] - суффикс: ['ee', 'ff'] - слово: 'первый элемент' # только префикс аа бб первый пункт ['aa', 'bb', 'первый элемент'] - префикс: ['аа', 'бб'] - слово: 'первый элемент' # без префикса или суффикса первый элемент ['первый элемент'] - слово: 'первый элемент' # несколько пробелов в элементе, замененные одиночными пробелами в результате синтаксического анализа первый элемент ['первый элемент'] - слово: 'первый элемент'
Стемминг | Elasticsearch Guide [8.6]
Stemming — это процесс приведения слова к его корневой форме. Это гарантирует варианты совпадения слова при поиске.
Например, ходить
и ходить
могут быть образованы одним и тем же корнем слова: ходить
. После определения вхождение любого слова будет соответствовать другому в
поиск.
Выделение корня зависит от языка, но часто включает удаление префиксов и суффиксы от слов.
В некоторых случаях корневая форма слова, состоящего из основы, может не быть настоящим словом. Для
Например, jumping
и jumpiness
можно объединить в jumpi
. Пока прыгает
это не настоящее английское слово, для поиска это не имеет значения; если все варианты
слова приведены к одной и той же корневой форме, они будут соответствовать правильно.
Фильтры токенов Stemmeredit
фильтры. Эти фильтры токенов можно разделить на категории в зависимости от происхождения слов:
- Алгоритмические стеммеры, которые формируют слова на основе набора правил
- Словарные стеммеры, которые определяют слова, просматривая их в словаре
Поскольку токены стеммера меняются, мы рекомендуем использовать один и тот же токен стеммера фильтры во время анализа индекса и поиска.
Алгоритмические стеммеры
Алгоритмические стеммеры применяют ряд правил к каждому слову, чтобы свести его к
корневая форма. Например, алгоритмический стеммер для английского языка может удалить -с
и -es
суффиксы от конца слов во множественном числе.
Алгоритмические стеммеры имеют несколько преимуществ:
- Они требуют небольшой настройки и обычно хорошо работают из коробки.
- Они используют мало памяти.
- Как правило, они быстрее, чем стеммеры словаря.
Однако большинство алгоритмических стеммеров изменяют только существующий текст слова. Этот означает, что они могут плохо работать с неправильными словами, которые не содержат своего корня форма, например:
-
будет
,будет
, абудет
. -
мышь
и -
футов
ифутов
Следующие фильтры токенов используют алгоритмический поиск корней:
-
стеммер
, обеспечивающий алгоритмический основа для нескольких языков, некоторые с дополнительными вариантами. -
kstem
, стеммер для английского языка, который сочетает в себе алгоритмический поиск со встроенным словарем. -
porter_stem
, наш рекомендуемый алгоритм стеммер для англ. -
снежок
, который использует Правила стемминга на основе снежного кома для нескольких языки.
Стеммеры словаря
Стеммеры словаря ищут слова в предоставленном словаре, заменяя ненужные варианты слов с производными словами из словаря.
Теоретически стеммеры словаря хорошо подходят для:
На практике алгоритмические стеммеры обычно превосходят стеммеры словаря. Этот потому что стеммеры словаря имеют следующие недостатки:
- Качество словаря
Стеммер словаря настолько хорош, насколько хорош его словарь. Чтобы хорошо работать, эти словари должны включать значительное количество слов, регулярно обновляться, и меняться с языковыми тенденциями. Часто к моменту создания словаря доступен, он неполный, а некоторые его записи уже устарели. - Размер и производительность
Стеммеры словарей должны загружать все слова, префиксы и суффиксы из своего словарь в память. Это может использовать значительный объем оперативной памяти. Некачественный словари также могут быть менее эффективными при удалении префиксов и суффиксов, что может значительно замедлить процесс стемпинга.
Вы можете использовать фильтр токенов
для
выполнить поиск по словарю.
Если доступно, мы рекомендуем попробовать алгоритмический стеммер для вашего языка
перед использованием фильтра токенов hunspell
.
Управление стеммингом
Иногда на основе стемминга могут образовываться слова с общим корнем, которые пишутся одинаково, но
концептуально не связаны. Например, стеммер может уменьшить как неба, так и
, и катание на лыжах
к тому же корневому слову: лыжи
.
Чтобы предотвратить это и лучше контролировать стемпинг, вы можете использовать следующий токен фильтры:
-
stemmer_override
, что позволяет определить правила для получения определенных токенов.