对于西方人来说,印尼语(或印尼语)是一种非常平易近人的语言。 它使用拉丁字符,结构清晰,没有时态,没有性别或复数形式,并且包含许多外来词(作为德国人,我特别喜欢荷兰语的影响词,例如排气管 knalpot )。 如果您在亚洲以外的地方长大,对于您来说印尼可能是一个遥远的国家,您可能不会听说很多。 但是由于这个国家很大,实际上有很多人在讲这种语言,并与它的兄弟姐妹Bahasa Melayu一起使用, 这是地球上最常见的语言之一 。 如果这还不够的话,那么一旦您访问印度尼西亚,您就会发现他们的人民非常积极和快乐。 可能是对该语言感兴趣的另一个原因。
由于我已经学习了一些印尼语,并且不得不花很多时间在印尼工作和休闲,所以我认为研究一下Lucene印尼分析器并查看其如何处理文本可能是个好主意。 如果您不知道分析器是什么,我可以指出您关于索引数据绝对基础的一篇较早的文章。
Lucene的印度尼西亚分析器
如果您想使用IndonesianAnalyzer,它可以与lucene-analyzers-common一起使用,您很可能已经将其包括在内。 您可以只创建一个实例并以自己喜欢的任何方式使用它。 此代码片段将显示字符串中文本的术语。
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;
}
弹性搜索中的印尼分析器
IndonesianAnalyzer也可以与elasticsearch一起使用。 在映射中,您可以通过分析器名称indonesian
来引用它。
{
"mappings": {
"doc": {
"properties": {
"content": {
"type": "text", "analyzer": "indonesian"
}
}
}
}
}
elasticsearch文档在分析器上也有一节,说明如何使用不同的过滤器重建它。
Solr中的印度尼西亚分析器
大多数时候,您将在Solr中创建自己的分析器链。 这来自参考指南。
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.IndonesianStemFilterFactory"
stemDerivational="true" />
</analyzer>
分析仪的功能
首先让我们看一个非常简单的例句。
Saya mau makan mie ayam。
我想吃鸡肉面条。 您不仅了解了我喜欢印尼美食,而且还看到印尼语使用拉丁字符并用空格分隔单词。 让我们看看IndonesianAnalyzer对这段文本的处理方式。
如果您查看上面的Lucene示例产生的术语,您将获得以下列表。
[makan, mie, ayam]
因此,仅剩五个词中的三个。 Saya (I)和mau (想要)被删除。 这是由默认的停用词列表引起的,停用词在搜索时被认为并不重要。 这些单词将保留在分析仪随附的文本文件中。 如果你想为你的内容使用不同的列表,你可以使用一个接受一个构造函数CharArraySet
,为elasticsearch和Solr你可以使用自定义的StopFilter。
现在,其余单词保持不变,没有词干涉及,这是通过将术语简化为基本形式来处理自然语言的一种常用方法。 让我们看另一个例子。
卡米(Kami),邦萨(Bangsa)印尼,印尼(Dengan ini menjatakan kemerdekaan Indonesia)。
这是1945年宣布的印度尼西亚独立宣言的第一句话。我们印度尼西亚人民在这里宣布印度尼西亚独立。
如果使用分析器处理此文本,则将获得以下术语列表。
[bangsa, indonesia, jata, merdeka, indonesia]
再次,像kami , dengan , ini这样的词已被删除,就像停用词列表中的一样。 但是其他事情发生了。 Menjatakan变成了jata , kemerdekaan变成了merdeka 。 印尼语没有动词词尾变化,但是有许多前缀和后缀可以改变单词的含义。 在这种情况下kemerdekaan(独立)是默迪卡 (独立)的变化。 有很多前缀和后缀。 makan是吃 , makanan是食物 。 minum是喝 , minuman是喝 。 SAMA是一样的 ,是bersama 一起 。 IndonesianAnalyzer将正确地阻止这些示例(即使sama和bersama是停用词)。
实作
像大多数分析器一样,IndonesianAnalyzer仅合并了一些其他组件,即令牌生成器和服务器令牌过滤器。
- StandardTokenizer
- 标准过滤器
- 小写过滤器
- 停止过滤器
- SetKeywordMarkerFilter
- 印尼语干式过滤器
IndonesianStemFilter是引起词干的有趣组件。 它使用了基于本文的IndonesianStemmer,该论文基于印度尼西亚语的词干对信息检索的影响研究 。
与大多数其他基于规则的词干一样,某些单词可能无法正确词干。 例如: menunggu表示等待 ,它源于unggu ,但是正确的基本形式是tunggu 。 如果要消除此类情况,可以将单词添加到stemExclusionSet
,然后可以将其传递到分析器中以防止它们被阻止。 或者,您可以构建自己的使用StemmerOverrideFilter的分析器-也许这是另一篇博客文章的材料。
计分
评分搜索结果时,印度尼西亚语(Bahasa Indonesia)提出了一个有趣的挑战。 诸如TF / IDF和BM25之类的评分算法依赖于词频。 但是在印尼语中,通常只需重复一个单词就可以形成复数形式。 美孚意思是汽车 - 美孚意思是汽车 。 但是,如果一篇文字谈到一辆或多辆汽车,在计分方面没有什么不同。 根据要搜索的文本,可能有必要忽略频率–或编写自定义过滤器来跳过立即重复的单词。
结论
词根并不是在每个搜索应用程序中都占有一席之地。 但这是可以帮助使自然语言更易于访问而又不太复杂的技术之一。 它可以使您的搜索看起来像魔术。
当使用搜索引擎时,使用自然语言是我非常喜欢的一件事。 而且,如果像在这种情况下那样,我正在学习一些更好的语言知识。
翻译自: https://www.javacodegeeks.com/2018/03/indonesian-language-in-lucene-solr-and-elasticsearch.html