Статьи

Индонезийский язык в Lucene, Solr и Elasticsearch

Индонезийский, или индонезийский бахаса, является очень доступным языком для жителей Запада. В нем используются латинские буквы, есть четкая структура, нет времен, нет пола или множественного числа, и он содержит много иностранных слов (как немец, мне особенно нравятся термины, на которые влияют голландцы, такие как knalpot для выхлопной трубы ). Если вы росли за пределами Азии, Индонезия может быть для вас довольно отдаленной страной, о которой вы мало что слышите. Но из-за того, что страна такая большая, на самом деле довольно много людей говорит на этом языке, что делает его вместе со своим родным братом-мелайю одним из самых распространенных языков на земле . И если этого недостаточно, посетив Индонезию, вы увидите, что люди очень позитивно настроены и счастливы. Может быть, еще одна причина, чтобы интересоваться языком.

Поскольку я немного изучал индонезийский язык и провел довольно много времени в Индонезии для работы и отдыха, я подумал, что было бы неплохо заглянуть в индонезийский анализатор Lucene и посмотреть, как он обрабатывает текст. Если вы не знаете, что делает Analyzer, я могу указать вам на один из моих старых постов об абсолютных основах индексации данных .

Индонезийский анализатор в Lucene

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

01
02
03
04
05
06
07
08
09
10
11
12
private List<String> analyze(String text) throws IOException {
    List<String> terms = new ArrayList<>();
 
    try(Analyzer analyzer = new IndonesianAnalyzer();
        TokenStream tokenStream = analyzer.tokenStream(null, text)) {
        tokenStream.reset();
        while (tokenStream.incrementToken()) {
            terms.add(tokenStream.getAttribute(CharTermAttribute.class).toString());
        }
    }
    return terms;
}

Индонезийский анализатор эластичного поиска

Индонезийский анализатор можно использовать и с эластичным поиском. В отображении вы можете обратиться к нему по indonesian имени анализатора.

01
02
03
04
05
06
07
08
09
10
11
{  
  "mappings": {
    "doc": {
      "properties": {
        "content": {
          "type": "text", "analyzer": "indonesian"
        }              
      }
    }
  }
}

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

Индонезийский анализатор в Solr

Большую часть времени вы будете создавать свою собственную цепочку анализаторов в Solr. Это из справочника.

1
2
3
4
5
6
<analyzer>
  <tokenizer class="solr.StandardTokenizerFactory"/>
  <filter class="solr.LowerCaseFilterFactory"/>
  <filter class="solr.IndonesianStemFilterFactory"
    stemDerivational="true" />
</analyzer>

Особенности анализатора

Давайте сначала посмотрим на очень простое примерное предложение.

Сая мау макан ми аям.

Я хочу есть куриную лапшу. Вы не только узнали, что мне нравится индонезийская еда, но вы также можете увидеть, что индонезийский язык использует латинские символы и разделяет слова через пробел. Давайте посмотрим, что Индонезийский анализатор делает с этим текстом.

Если вы посмотрите на условия, приведенные в примере Lucene выше, вы получите следующий список.

1
[makan, mie, ayam]

Так что осталось только три из пяти слов. Сая (я) и Мау (хочу) отброшены. Это вызвано списком стоп-слов по умолчанию, которые считаются несущественными при поиске. Эти слова хранятся в текстовом файле, который поставляется вместе с анализатором . Если вы хотите использовать другой список для вашего контента, вы можете использовать один из конструкторов, который принимает CharArraySet , CharArraySet и Solr вы можете использовать пользовательский StopFilter.

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

Ками, Бангса Индонезия, Денган Ини Менджакан Кемердекаан Индонезия.

Это первое предложение декларации независимости Индонезии, которая была провозглашена в 1945 году. Мы, народ Индонезии, настоящим провозглашаем независимость Индонезии.

Если вы обработаете этот текст с помощью анализатора, вы получите следующий список терминов.

1
[bangsa, indonesia, jata, merdeka, indonesia]

Опять же, такие слова, как kami , dengan , ini , были удалены, поскольку они находятся в списке стоп-слов. Но что-то еще случилось. менджатакан стал джата, а кемердекаан стал мердека . В индонезийском языке нет словосочетания, но есть много префиксов и суффиксов, которые могут изменить значение слов. В этом случае kemerdekaan (независимость) является разновидностью merdeka (независимой). Есть много префиксов и суффиксов. Макан есть , Маканан это еда . Минум это пить , Минуман это напиток . Сама такая же , Берсама вместе . Индонезийский анализатор будет корректно использовать эти примеры (хотя sama и bersama — это ключевые слова).

Реализация

Как и большинство анализаторов, Индонезийский анализатор объединяет всего несколько других компонентов, а именно Tokenizer и несколько TokenFilters.

  • StandardTokenizer
  • StandardFilter
  • LowercaseFilter
  • StopFilter
  • SetKeywordMarkerFilter
  • IndonesianStemFilter

IndonesiaianStemFilter — это интересный компонент, который отвечает за создание базы. В нем используется индонезийский стеммер, основанный на статье «Исследование влияния стемминга на поиск информации в Бахасе, Индонезия» .

Как и в большинстве других основанных на правилах, некоторые слова могут быть написаны неправильно. Пример: menunggu означает ожидание , оно ограничено unggu , но правильной базовой формой будет tunggu . Если вы хотите избавиться от подобных случаев, вы можете добавить слова в stemExclusionSet которые можно передать в анализатор, чтобы защитить их от возникновения. Или вы можете создать свой собственный анализатор, который использует StemmerOverrideFilter — возможно, это материал для другого поста в блоге.

счет

Bahasa Indonesia представляет интересную проблему, когда дело доходит до оценки результатов поиска. Алгоритмы оценки, такие как TF / IDF и BM25, основаны на частоте терминов. Но на индонезийском языке множественное число часто образуется просто повторением слова. Мобил означает автомобильМобил означает автомобиль . Но если текст говорит об одной машине или нескольких машинах, это не должно иметь значения, когда дело доходит до выигрыша. В зависимости от текста, который вы ищете, может быть необходимо игнорировать частоты или написать собственный фильтр, который пропускает слова, которые повторяются немедленно.

Вывод

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

Работа с естественными языками — это то, что мне очень нравится при работе с поисковыми системами. И если, как в этом случае, я изучаю что-то о языке в процессе, что даже лучше.

Смотреть оригинальную статью здесь: индонезийский язык в Lucene, Solr и Elasticsearch

Мнения, высказанные участниками Java Code Geeks, являются их собственными.