原形词干提取

为了完整地完成本章的内容,我们将讲解如何将已提取词干的词和原词索引到同一个字段中。举个例子,分析句子 The quick foxes jumped 将会得到以下词项:

  1. Pos 1: (the)
  2. Pos 2: (quick)
  3. Pos 3: (foxes,fox) (1)
  4. Pos 4: (jumped,jump) (1)

<1> 已提取词干的形式和未提取词干的形式位于相同的位置。

Warning:使用此方法前请先阅读 stemming-in-situ-good-idea

为了归档词干提取出的 原形 ,我们将使用 keyword_repeat 过滤器,跟 keyword_marker 过滤器 ( see preventing-stemming ) 一样,它把每一个词项都标记为关键词,以防止后续词干提取器对其修改。但是,它依然会在相同位置上重复词项,并且这个重复的词项 提取的词干。

单独使用 keyword_repeat token 过滤器将得到以下结果:

  1. Pos 1: (the,the) (1)
  2. Pos 2: (quick,quick) (1)
  3. Pos 3: (foxes,fox)
  4. Pos 4: (jumped,jump)

<1> 提取词干前后的形式一样,所以只是不必要的重复。

为了防止提取和未提取词干形式相同的词项中的无意义重复,我们增加了组合的 {ref}/analysis-unique-tokenfilter.html[unique] 语汇单元过滤器 :

  1. PUT /my_index
  2. {
  3. "settings": {
  4. "analysis": {
  5. "filter": {
  6. "unique_stem": {
  7. "type": "unique",
  8. "only_on_same_position": true (1)
  9. }
  10. },
  11. "analyzer": {
  12. "in_situ": {
  13. "tokenizer": "standard",
  14. "filter": [
  15. "lowercase",
  16. "keyword_repeat", (2)
  17. "porter_stem",
  18. "unique_stem" (3)
  19. ]
  20. }
  21. }
  22. }
  23. }
  24. }

<1> 设置 unique 类型语汇单元过滤器,是为了只有当重复语汇单元出现在相同位置时,移除它们。

<2> 语汇单元过滤器必须出现在词干提取器之前。

<3> unique_stem 过滤器是在词干提取器完成之后移除重复词项。

原形词干提取是个好主意吗

用户喜欢 原形 词干提取这个主意:``如果我可以只用一个组合字段,为什么还要分别存一个未提取词干和已提取词干的字段呢?’’ 但这是一个好主意吗?答案一直都是否定的。因为有两个问题:

第一个问题是无法区分精准匹配和非精准匹配。本章中,我们看到了多义词经常会被展开成相同的词干词:organsorganization 都会被提取为 organ

using-language-analyzers 我们展示了如何整合一个已提取词干属性的查询(为了增加召回率)和一个未提取词干属性的查询(为了提升相关度)。当提取和未提取词干的属性相互独立时,单个属性的贡献可以通过给其中一个属性增加boost值来优化(参见 prioritising-clauses )。相反地,如果已提取和未提取词干的形式置于同一个属性,就没有办法来优化搜索结果了。

第二个问题是,必须搞清楚 相关度分值是否如何计算的。在 relevance-intro 我们解释了部分计算依赖于逆文档频率(IDF)—— 即一个词在索引库的所有文档中出现的频繁程度。在一个包含文本 jump jumped jumps 的文档上使用原形词干提取,将得到下列词项:

  1. Pos 1: (jump)
  2. Pos 2: (jumped,jump)
  3. Pos 3: (jumps,jump)

jumpedjumps 各出现一次,所以有正确的IDF值;jump 出现了3次,作为一个搜索词项,与其他未提取词干的形式相比,这明显降低了它的IDF值。

基于这些原因,我们不推荐使用原形词干提取。