Лемматизация запросов Solr/Lucene с контекстом

Я успешно реализовал чешский лемматизатор для Lucene. Я тестирую его с помощью Solr, и он хорошо работает в индексное время. Но это не так хорошо работает при использовании для запросов, потому что анализатор запросов не предоставляет лемматизатору никакого контекста (слова до или после).

Например, фраза pila vodu во время индексации анализируется иначе, чем во время запроса. В нем используется двусмысленное слово pila, которое может означать pila (пила, например, бензопила) или pít (прошедшее время глагола «пить»).

pila vodu ->

  • Время индекса: pít voda
  • Время запроса: pila voda

.. поэтому слово pila не найдено и не выделено во фрагменте документа.

Это поведение задокументировано на solr wiki ( цитируется ниже), и я могу подтвердить это, отладив свой код (в лемматизатор передаются только изолированные строки «пила» и «воду»).

... Lucene QueryParser размечает пустое пространство, прежде чем передать какой-либо текст анализатору, поэтому, если человек ищет слова sea biscit, анализатору будут предоставлены слова "море" и "бисцит" отдельно, ...

Итак, мой вопрос:

Можно ли как-то изменить, настроить или адаптировать парсер запросов, чтобы лемматизатор видел всю строку запроса или хотя бы какой-то контекст отдельных слов? Я хотел бы иметь решение также для различных парсеров запросов solr, таких как dismax или edismax.

Я знаю, что с фразовыми запросами типа "pila vodu" (кавычки) такой проблемы не возникает, но тогда я потеряю документы без точной фразы (например, документы с "pila víno" или даже "pila víno" доброу воду").


Редактировать - пытаюсь объяснить/ответить на следующий вопрос (спасибо, @femtoRgon):

Если эти два термина не являются фразой и, следовательно, не обязательно сочетаются друг с другом, то зачем их анализировать в контексте друг друга?

Конечно, было бы лучше анализировать только термины, сходящиеся вместе. Например, во время индексации лемматизатор обнаруживает предложения во входном тексте и анализирует вместе только слова из одного предложения. Но как добиться подобного во время запроса? Является ли реализация моего собственного анализатора запросов единственным вариантом? Мне очень нравятся опции pf2 и pf3 парсера edismax, должен ли я реализовать их снова в случае моего собственного парсера?

Идея на самом деле немного глубже, потому что лемматизатор делает слово -значение-значение даже для слов, имеющих одинаковую лексическую основу. Например, слово bow имеет примерно 7 различных значений в английском языке (см. википедия).), и лемматизатор различает такие смыслы. Поэтому я хотел бы использовать этот потенциал, чтобы сделать поиск более точным — возвращать только документы, содержащие слово bow в конкретном смысле, требуемом запросом. Таким образом, мой вопрос можно было бы расширить до: как получить правильную пару <lemma;sense> для термина запроса? Лемматизатор очень часто может присвоить правильный смысл, если слово представлено в его общем контексте, но у него нет шансов, когда контекста нет.


person dedek    schedule 04.10.2016    source источник
comment
Если эти два термина не являются фразой и, следовательно, не обязательно сочетаются друг с другом, то зачем их анализировать в контексте друг друга?   -  person femtoRgon    schedule 04.10.2016
comment
@femtoRgon: посмотри мои правки... У тебя есть какие-нибудь предложения для меня? Я был бы очень признателен...   -  person dedek    schedule 05.10.2016
comment
Автоматический фильтр токенов фраз используется Lucidworks для обнаружения и токенизации фраз. Фильтр использует список фраз – извлекается из текстового файла по одной фразе в строке.   -  person Sanjay Dutt    schedule 07.10.2016


Ответы (1)


Наконец, я реализовал свой собственный парсер запросов.

Это было не так сложно благодаря исходникам edismax в качестве руководства и эталонной реализации. Я мог бы легко сравнить результаты моего парсера с результатами edismax...

Решение:

Сначала я анализирую всю строку запроса вместе. Это дает мне список «токенов».

Есть небольшая коллизия со стоп-словами - получить токены для стоп-слов не так просто, так как они пропускаются анализатором, но их можно обнаружить из PositionIncrementAttribute.

Из «токенов» я строю запрос так же, как edismax (например, создавая все фразовые запросы с 2 и/или 3 токенами, объединенные в DisjunctionMaxQuery экземплярах).

person dedek    schedule 04.01.2018