ApacheSolr и словарь для русского стемминга

Главные вкладки

Аватар пользователя gasloff@drupal.org gasloff@drupal.org 5 ноября 2011 в 20:58

Имеем Drupal 7 и Solr 1.4.1. Русский стэмминг реализован стандартным стэммингом от Портера. Он там довольно грубый, думаю все это знают. А вот в случае Sphinx можно для стэмминга подключать пользовательский словарь.

Обновил сегодня Solr до 3.4.0. Обновление прошло без проблем, потребовалось только заменить schema.xml на другой, из папки соответствующего друпаловского модуля.

И вот на 3-м Solr имеется интересная возможность: http://wiki.apache.org/solr/LanguageAnalysis#Customizing_Stemming, а конкретно solr.StemmerOverrideFilterFactory и возможность подключения словаря stemdict.txt.

Сделал его из словаря ispell как описывают в отношении такого же словаря для Sphinx при помощи spelldump. Только заменил символ " > " между терминами и корнями на табуляцию. Подключил.

Просто прописал в schema.xml соответствующие строки:

перед строками в стандартном schema.xml:

Перезапустил Solr. Создал по новой индекс. Все заработало - вижу что стэмминг стал более аккуратным. Появилась возможность подстраивать стемминг под свои нужды, редактируя stemdict.txt.

Странно, что эта возможность не реализована "из коробки" в друпаловском модуле интеграции Solr, хотя бы для варианта с 3-м Solr'ом, отдельный schema.xml все-таки для тройки же есть.

Но возникают два вопроса:

1) Может что-то делаю не так? Что стоит еще поправить?

2) В 3-м Solr есть кроме solr.PorterStemFilterFactory еще и solr.RussianLightStemFilterFactory (http://wiki.apache.org/solr/LanguageAnalysis#Russian). Кто-нибудь имел опыт его использования?

P.S. В Solr 3.5 обещают вообще в качестве стеммера возможность выбрать Hunspeel, который используется в OpenOffice. А следовательно, даже словари myspeel не нужно будет конвертировать, что не может не радовать.

P.P.S. Кстати, походу у Solr есть ограничение по максимальному размеру stemdict.txt.

Комментарии

Аватар пользователя gasloff@drupal.org gasloff@drupal.org 6 ноября 2011 в 1:29

Находите в файле schema.xml в двух местах строки:
filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"

меняете их на:
filter class="solr.SnowballPorterFilterFactory" language="Russian" protected="protwords.txt"

Это в случае, если у вас сайт одноязычный и поиск будет только по русскому языку. Если многоязычный - ставьте соответствующий модуль и им генерите файлы для нужных языков. Ну или вручную их делайте.

Если у вас два домена под разные языки, то еще вариант - запускаете ядра Solr по числу доменов и у каждого прописываете свою директорию Solr, куда кладете необходимые файлы.

Но, повторюсь, SnowballPorterFilterFactory по умолчанию не всегда хорошо русские корни выделяет. Почему и заинтересовала возможность прикрутить отдельно русский словарь.

P.S. Это все, естественно, подразумевает установленный и работающий ApacheSolr.

Аватар пользователя gasloff@drupal.org gasloff@drupal.org 6 ноября 2011 в 18:24

Я protwords.txt под себя еще не правил. Stopwords.txt подрихтовал. Сейчас вожусь с stemdict.txt. Затем в планах разобраться с spellings.txt и вообще настройками спеллинга, а также с учетом переносов. А там еще синонимы на очереди. Но у меня довольно специфические потребности сейчас, учитывающие один специфический спортивный жаргон. Потому вряд ли файлы подойдут для паблика.

Аватар пользователя gasloff@drupal.org gasloff@drupal.org 13 ноября 2011 в 10:26

Да, кстати, ради интереса попробовал просто заменить в типовом schema.xml solr.PorterStemFilterFactory на solr.RussianLightStemFilterFactory. Результат не понравился, индексация идет, но в финале друпаловский модуль виснет. Хотя сам Solr вроде с индексацией справляется. Но все равно не айс Smile

Чтобы не было глюка, описанного выше, solr.RussianLightStemFilterFactory подключается без указания ссылки на protwords.txt, т.е. вместо:
filter class="solr.SnowballPorterFilterFactory" language="Russian" protected="protwords.txt"
пишем:
filter class="solr.RussianLightStemFilterFactory"

К сожалению, не смог выяснить глюк ли это модуля под Друпал или у данного стеммера просто нельзя указывать такой параметр в schema.xml.

Еще не очень приятная особенность у нынешнего стеммера в Solr http://lucene.472066.n3.nabble.com/Russian-stemmer-td998603.html - он временами хулиганит со склонениями имен собственных и географических названий. Но это лечится как раз при помощи указания таких имен в словаре stemdict.txt. Причем некоторые он нормально склоняет, а на некоторых спотыкается. Надо смотреть в "полевых условиях", судя по всему. Могут быть как глюки со склонением редких имен, которые он без указания в словаре может просто отказаться склонять. Так и с неправильным выделением корня. Например, в имени "Вася" Solr выделяет корень "вас" и, естественно, выдает не только словоформы от "Вася", но и все упоминания "вас". Лечим внесением правильного корня в stemdict.txt.

Конечно есть надежда, что в 3.5 в Hunspeel это будет учтено. Вобщем продолжаем экспериментировать Smile

Аватар пользователя rfidexpert rfidexpert 10 ноября 2011 в 11:11

А можно немного подробнее?
У меня сайт на двух языках - рус и англ, соответственно поиск нужен и по-русски и по английски. К сожалению, о том, как совместить два языка вместе нет информации.
Буду очень признателен.

Аватар пользователя gasloff@drupal.org gasloff@drupal.org 10 ноября 2011 в 20:28

У меня разные языки разведены на разные сайты, потому проще. Вам, видимо, нужно копать в сторону этого модуля: http://drupal.org/project/apachesolr_multilingual Там создаются отдельные файлы для каждого из необходимых языков, плюс вносятся коррективы в общие файлы, при этом для сайта используется одно ядро, вроде. Но сам не пробовал. Попробуйте, там довольно все просто.

Аватар пользователя duozersk duozersk 8 декабря 2011 в 11:47

Только что попробовал Hunspell - http://wiki.apache.org/solr/LanguageAnalysis#Notes_about_solr.HunspellSt...
Пока что не понял, работает оно или нет (может не надо словари конвертить в UTF8...). Словари для Hunspell брать тут - http://download.services.openoffice.org/files/contrib/dictionaries/ - их надо сконвертить в UTF8 и подложить солру (рядом с schema.xml).

Из всего вышеописанного получается, что можно использовать следующие варианты стемминга для русского языка:

<!-- Overriding using custom stemming dictionary, other stemmers shouldnt change the matches
     see http://wiki.apache.org/solr/LanguageAnalysis#solr.StemmerOverrideFilterFactory -->
<!--        <filter class="solr.StemmerOverrideFilterFactory" dictionary="stemdict.txt" />
-->
<!-- Hunspell -->
<!--        <filter class="solr.HunspellStemFilterFactory" dictionary="ru_RU.dic" affix="ru_RU.aff" ignoreCase="true" />
-->
<!-- Another variant for Russian
     Less agressive: крупный != крупнейший -->
        <filter class="solr.RussianLightStemFilterFactory"/>
<!-- Default
     Very agressive: крупный = крупнейший = крупн -->
<!--        <filter class="solr.SnowballPorterFilterFactory" language="Russian" protected="protwords.txt"/>
-->

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

Аватар пользователя T-34 T-34 13 июня 2013 в 1:37

duozersk, спасибо, очень помогло.
Hunspell показал наилучший результат. SnowballPorter и RussianLightStem, например, не различают слова "отдых" и "отдам", а StemmerOverrideFilterFactory у меня почему-то не заработал (вообще не стартует Солр с этим фильтром, ловится exception).

Аватар пользователя duozersk duozersk 13 июня 2013 в 9:30

Рад, что помог Smile Не могли бы вы тогда тут по свежим следам отписать, как вы заводили Hunspell (нужно ли было конвертировать файлы, как вы это делали, куда и какие файла конвертировали/копировали)? Я сейчас уже давно не на том проекте, где это использовал - но поможет в будущем.
Помню, что по теории Hunspell должен был дать лучший результат, но у меня тогда так и не заработало.

Аватар пользователя yurkinx yurkinx 17 июля 2013 в 1:53

С Hunspell довольно просто. Словари по ссылке обязательно нужно перевести в UTF-8. Только открыть и удостовериться, что файл действительно стал читабельным иначе работать не будет. Положить в папку с конфигом, подключить как вы и написали, и все работает! Только строит индекс очень и очень медленно.

Есть еще один альтернативный стимер, но завести к сожалению не смог.
jmorphy2-solr-stemmer который использует библиотеку rymorphy2
https://github.com/anti-social/jmorphy2-solr-stemmer

Аватар пользователя ilyin.eugene ilyin.eugene 27 июля 2013 в 13:27

«С Hunspell довольно просто. Словари по ссылке обязательно нужно перевести в UTF-8. Только открыть и удостовериться, что файл действительно стал читабельным иначе работать не будет. Положить в папку с конфигом, подключить как вы и написали, и все работает! Только строит индекс очень и очень медленно.»

а через что вы конвертировали? я пробовал через iconv следующим образом:

iconv -f ISO-8859-1 -t UTF8 ru_RU.dic > new_ru_RU.dic

Тоже самое с .aff файлом. В schema.xml добавил строку
<filter class="solr.HunspellStemFilterFactory" dictionary="ru_RU.dic" affix="ru_RU.aff" ignoreCase="true" />

Перезагружал сервер солра, переиндексировал в друпале. В итоге ищет только по полному соответствию Sad

Может надо что то отредактировать еще в конфиге? Или как то по другому надо конвертить?

P.S. Версия солра - 3.6.1

Аватар пользователя yurkinx yurkinx 31 июля 2013 в 1:53

Это наверно проблема кодировки. Я открыл оба файла в эдиторе у себя под windows, увидел абракадабру, изменил кодировку, сохранил, залил на сервер и все встало на свои места. До этого тоже была проблема: Solr так же искал по полному соответствию. iconv не пользовался.

Кстати, в конце концов мы начали пользоваться SnowballPorterFilterFactory, так как индексация в разы быстрее, а ощутимой разницы с Hunspell все таки не увидели.

Аватар пользователя ilyin.eugene ilyin.eugene 31 июля 2013 в 6:48

А как назывался редактор под windows?

>Кстати, в конце концов мы начали пользоваться SnowballPorterFilterFactory, так как индексация в разы быстрее, а ощутимой разницы с Hunspell все таки не увидели.
чтобы он нормально работал, нужен заполненный protwords.txt?

Аватар пользователя multpix multpix 31 июля 2013 в 10:59
<fieldType name="text" class="solr.TextField" indexed="true" stored="true" multiValued="true" positionIncrementGap="100">
      <analyzer type="index">
        <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25" />

не спасает?

Аватар пользователя ilyin.eugene ilyin.eugene 31 июля 2013 в 12:17

multpix wrote:

<fieldType name="text" class="solr.TextField" indexed="true" stored="true" multiValued="true" positionIncrementGap="100">
      <analyzer type="index">
        <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25" />

не спасает?

Спасибо! Это помогло!

Аватар пользователя duozersk duozersk 31 июля 2013 в 11:33

"ilyin.eugene" wrote:
>>Кстати, в конце концов мы начали пользоваться SnowballPorterFilterFactory, так как индексация в разы быстрее, а ощутимой разницы с Hunspell все таки не увидели.
>чтобы он нормально работал, нужен заполненный protwords.txt?

Нет, не обязательно. protwords.txt может быть и абсолютно пустым. И, скорее всего, его даже можно не указывать (но в этом не уверен).

Аватар пользователя ilyin.eugene ilyin.eugene 31 июля 2013 в 11:44

duozersk wrote:
Нет, не обязательно. protwords.txt может быть и абсолютно пустым. И, скорее всего, его даже можно не указывать (но в этом не уверен).

ну с пустым он у меня ищет вообще никчемно.

Для слова радиаторный находит только по радиаторн и радиаторны. Что интересно по точному соответствию не находит!

Аватар пользователя duozersk duozersk 8 августа 2013 в 18:12

Solr ищет по части слова, и успешно.

"multpix" wrote:

<fieldType name="text" class="solr.TextField" indexed="true" stored="true" multiValued="true" positionIncrementGap="100">
      <analyzer type="index">
        <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25" />

не спасает?


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

Изначально же тема была про стемминг, то есть индексацию слов с учетом морфологии языка. Наконец-то снова заработал поиск на computerbild.ru (я уже не занимаюсь этим проектом) - можете посмотреть, например, вот этот запрос - видеокарты - по слову "видеокарты" поиск найдёт статьи (и выделит в сниппете), содержащие различные слово-формы поисковой фразы: "видеокарту", "видеокарта", "видеокарте", "видеокартами" и тд. Но по запросу видеокар поиск уже не выдаст этих результатов (в отличие от способа образования n-грамм).
Настроен он тут так, как я отписывал выше - http://www.drupal.ru/node/71073#comment-417724

Аватар пользователя T-34 T-34 14 августа 2013 в 19:09

"yurkinx" wrote:
Кстати, в конце концов мы начали пользоваться SnowballPorterFilterFactory, так как индексация в разы быстрее, а ощутимой разницы с Hunspell все таки не увидели.

Я не заметил на глаз разницы по скорости индексации (около 200 тыс. нод, индексировал с помощью drush).
Разницу в качестве поиска можно заметить только на отдельных словах, на которых стемминг SnowballPorter срабатывает неправильно (как я уже приводил пример - "отдых" и "отдам", и много других русских слов, у которых корни частично совпадают). Для большинства сайтов, думаю, это не критично, но у меня это имеет значение.

Словари я конвертировал в UTF-8 в текстовом редакторе в Ubuntu/Linux Mint.