词干提取算法
Elasticsearch 中的大部分 stemmers (词干提取器)是基于算法的,它们提供了一系列规则用于将一个词提取为它的词根形式,例如剥离复数词末尾的 s
或 es
。提取单词词干时并不需要知道该词的任何信息。
这些基于算法的 stemmers 优点是:可以作为插件使用,速度快,占用内存少,有规律的单词处理效果好。缺点是:没规律的单词例如 be
、 are
、和 am
,或 mice
和 mouse
效果不好。
最早的一个基于算法的英文词干提取器是 Porter stemmer ,该英文词干提取器现在依然推荐使用。 Martin Porter 后来为了开发词干提取算法创建了Snowball language 网站, 很多 Elasticsearch 中使用的词干提取器就是用 Snowball 语言写的。
[TIP]
{ref}/analysis-kstem-tokenfilter.html[kstem
token filter] 是一款合并了词干提取算法和内置词典的英语分词过滤器。为了避免模糊词不正确提取,这个词典包含一系列根词单词和特例单词。 kstem
分词过滤器相较于 Porter 词干提取器而言不那么激进。
使用基于算法的词干提取器
你可以使用 {ref}/analysis-porterstem-tokenfilter.html[porter_stem
] 词干提取器或直接使用 {ref}/analysis-kstem-tokenfilter.html[kstem
] 分词过滤器,或使用 {ref}/analysis-snowball-tokenfilter.html[snowball
] 分词过滤器创建一个具体语言的 Snowball 词干提取器。所有基于算法的词干提取器都暴露了用来接受 语言
参数的统一接口: {ref}/analysis-stemmer-tokenfilter.html[stemmer
token filter] 。
例如,假设你发现 英语
分析器使用的默认词干提取器太激进并且你想使它不那么激进。首先应在 {ref}/analysis-lang-analyzer.html[language analyzers] 查看 英语
分析器配置文件,配置文件展示如下:
{
"settings": {
"analysis": {
"filter": {
"english_stop": {
"type": "stop",
"stopwords": "_english_"
},
"english_keywords": {
"type": "keyword_marker", (1)
"keywords": []
},
"english_stemmer": {
"type": "stemmer",
"language": "english" <2>
},
"english_possessive_stemmer": {
"type": "stemmer",
"language": "possessive_english" (2)
}
},
"analyzer": {
"english": {
"tokenizer": "standard",
"filter": [
"english_possessive_stemmer",
"lowercase",
"english_stop",
"english_keywords",
"english_stemmer"
]
}
}
}
}
}
<1> keyword_marker
分词过滤器列出那些不用被词干提取的单词。这个过滤器默认情况下是一个空的列表。
<2> english
分析器使用了两个词干提取器: possessive_english
词干提取器和 english
词干提取器。 (((“english stemmer”)))(((“possessive_english stemmer”))) 所有格词干提取器会在任何词传递到 english_stop
、 english_keywords
和 english_stemmer
之前去除 's
。
重新审视下现在的配置,添加上以下修改,我们可以把这份配置当作新分析器的基本配置:
修改
english_stemmer
,将english
({ref}/analysis-porterstem-tokenfilter.html[porter_stem
] 分词过滤器的映射)替换为light_english
(非激进的 {ref}/analysis-kstem-tokenfilter.html[kstem
] 分词过滤器的映射)。添加
asciifolding
分词过滤器用以移除外语的附加符号。移除
keyword_marker
分词过滤器,因为我们不需要它。(我们会在 controlling-stemming 中详细讨论它)
新定义的分析器会像下面这样:
PUT /my_index
{
"settings": {
"analysis": {
"filter": {
"english_stop": {
"type": "stop",
"stopwords": "_english_"
},
"light_english_stemmer": {
"type": "stemmer",
"language": "light_english" (1)
},
"english_possessive_stemmer": {
"type": "stemmer",
"language": "possessive_english"
}
},
"analyzer": {
"english": {
"tokenizer": "standard",
"filter": [
"english_possessive_stemmer",
"lowercase",
"english_stop",
"light_english_stemmer", (1)
"asciifolding" (2)
]
}
}
}
}
}
<1> 将 english
词干提取器替换为非激进的 light_english
词干提取器
<2> 添加 asciifolding
分词过滤器