Синонимы с использованием Lucene - PullRequest
16 голосов
/ 08 августа 2009

Каков наилучший способ обработки синонимов (фраз) с помощью Lucene? Особенно, когда мне нужно выполнить такие запросы, как: ИЛИ b ИЛИ c НЕ d

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

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

Может ли этот подход хорошо работать для любого типа запроса?

FYI, Синонимы в моем приложении полностью пользовательские, а не из словаря английского языка ... т.е. «Глобальный лидер в области финансов» также может означать «Главный инвестиционный банк» или «Финансовая компания Fortune 500» и т. Д. И т. Д.

Пожалуйста, предложите.

Спасибо.

Ответы [ 3 ]

12 голосов
/ 08 августа 2009

В проект Lucene внесен вклад под названием «wordnet». Согласно его документации :

Этот пакет использует синонимы, определенные WordNet, для создания индекса Lucene, хранящего их, который, в свою очередь, может использоваться для расширения запросов. Обычно вы запускаете Syns2Index один раз для построения индекса / «базы данных» запроса, а затем вызываете SynExpand.expand (...) для расширения запроса.

Это включает пример того, что он делает:

Если вы передадите запрос "большая собака", он напечатает:

Запрос: big adult^0.9 bad^0.9 bighearted^0.9 boastful^0.9 boastfully^0.9 bounteous^0.9 bountiful^0.9 braggy^0.9 crowing^0.9 freehanded^0.9 giving^0.9 grown^0.9 grownup^0.9 handsome^0.9 large^0.9 liberal^0.9 magnanimous^0.9 momentous^0.9 openhanded^0.9 prominent^0.9 swelled^0.9 vainglorious^0.9 vauntingly^0.9 dog andiron^0.9 blackguard^0.9 bounder^0.9 cad^0.9 chase^0.9 click^0.9 detent^0.9 dogtooth^0.9 firedog^0.9 frank^0.9 frankfurter^0.9 frump^0.9 heel^0.9 hotdog^0.9 hound^0.9 pawl^0.9 tag^0.9 tail^0.9 track^0.9 trail^0.9 weenie^0.9 wiener^0.9 wienerwurst^0.9

Вы видите, что к оригинальным словам ("большой" и "собака") не прикреплено никакого веса. Однако синонимы имеют весовой коэффициент (0,9), который вы можете настроить самостоятельно.

Он поставляется в комплекте со стандартным дистрибутивом Lucene в каталоге contrib.

1 голос
/ 11 августа 2009

Вы можете получить объект Query после анализа строки входного запроса с помощью QueryParser.parse ().

В большинстве случаев запрос верхнего уровня является логическим запросом с подзапросами в качестве его дочерних элементов. Вы можете рекурсивно итерировать объект запроса. Когда вы нажимаете на объект TermQuery или PhraseQuery, вы можете получить (под) запрос и заменить этот объект запроса логическим объектом запроса, состоящим из его синонимов, если таковые имеются.

По сути, вы преобразуете свой исходный запрос

a OR b AND c 

до

(a OR synA) OR (b OR synB1 OR synB2) AND c

Работая с объектом запроса, убедитесь, что вы просто заменяете конечные узлы запроса новыми запросами и не возитесь с произвольно сложной иерархией запросов.

0 голосов
/ 08 августа 2009

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

...