ES如何提高召回率之【词干提取】

想要提高召回率就需要尽可能匹配相关的文档,其中一个办法就是在索引阶段对词语分析(分词器)的时候提取词干,搜索的时候也取词干。

不取词干

es默认使用的是标准的分词器,是不会取词干的。
但是标准分词器是包含小写转换分词过滤器的,也是可以提高召回率的。

{
    "analyzer": "standard",
    "text": "I liked apple"
}
{
    "tokens": [
        {
            "token": "i",
            "start_offset": 0,
            "end_offset": 1,
            "type": "",
            "position": 0
        },
        {
            "token": "liked",
            "start_offset": 2,
            "end_offset": 7,
            "type": "",
            "position": 1
        },
        {
            "token": "apple",
            "start_offset": 8,
            "end_offset": 13,
            "type": "",
            "position": 2
        }
    ]
}
  • 【liked】被分词器切割出来了

那我们使用【liked】进行搜索是能搜索出来的,但是如果我们使用【like】是无法搜索出来的。

那为了提高召回率,我们需要对【liked】二次提取,提取出词干【like】,那么搜索的时候,无论是使用like、liked、liking都能搜索出来了

取词干

使用能取词干的分词器,比如english

{
    "analyzer": "english",
    "text": "I liked apple"
}
{
    "tokens": [
        {
            "token": "i",
            "start_offset": 0,
            "end_offset": 1,
            "type": "",
            "position": 0
        },
        {
            "token": "like",
            "start_offset": 2,
            "end_offset": 7,
            "type": "",
            "position": 1
        },
        {
            "token": "appl",
            "start_offset": 8,
            "end_offset": 13,
            "type": "",
            "position": 2
        }
    ]
}
  • 【liked】提取出来的词干是【like】

取词干带来的准确率问题

问题描述

如果用户就是想根据时态(过去式、过去分词)搜索,返回的数据会和用户预料的一样么?
比如:现在有两条数据

{"id":1,"content":"I like apple"}
{"id":2,"content":"I liked apple"}

现在搜索词是【liked】,那么两条数据都会被搜出来,并且评分一样,如下:

{
    "query":{
        "match":{
            "content":"i liked it"
        }
    }
}
{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 0.18232156,
        "hits": [
            {
                "_index": "dong_analyzer_test",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.18232156,
                "_source": {
                    "id": 1,
                    "content": "I like apple"
                }
            },
            {
                "_index": "dong_analyzer_test",
                "_type": "_doc",
                "_id": "2",
                "_score": 0.18232156,
                "_source": {
                    "id": 2,
                    "content": "I liked apple"
                }
            }
        ]
    }
}
  • 可以发现文档2排在了第二位,如果数量多一点,可能页面第一页都看不到他,但实际上他应该排在第一位

解决办法

再加一个字段

{
  "properties": {
      "content": {
        "type": "text",
        "analyzer": "english",
        "fields": {
          "std": {
            "type": "text",
            "analyzer": "standard"
          }
        }
      }
    }
}
  • content:使用了提取词干的分词器
  • content.std:不使用标准分词器

注意:如果是新增字段,需要重新导入一遍数据。

搜索的时候进行多字段搜索

{
   "query": {
        "multi_match": {
            "query":  "I liked it",
            "type":   "most_fields", 
            "fields": [ "content", "content.std" ]
        }
    }
}
  • most_fields:是将两个字段查询的评分加起来
{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.2401118,
        "hits": [
            {
                "_index": "dong_analyzer_test",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.2401118,
                "_source": {
                    "id": 2,
                    "content": "I liked apple"
                }
            },
            {
                "_index": "dong_analyzer_test",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.5469647,
                "_source": {
                    "id": 1,
                    "content": "I like apple"
                }
            }
        ]
    }
}

你可能感兴趣的:(ElasticSearch,elasticsearch,数据库)