首页 > 其他分享 >使用阿里云试用Elasticsearch学习:3.7 处理人类语言——拼写错误

使用阿里云试用Elasticsearch学习:3.7 处理人类语言——拼写错误

时间:2024-04-09 21:58:06浏览次数:19  
标签:匹配 3.7 词项 模糊 查询 拼写错误 Elasticsearch 文档 fuzziness

我们期望在类似时间和价格的结构化数据上执行一个查询来返回精确匹配的文档。 然而,好的全文检索不应该是完全相同的限定逻辑。 相反,我们可以扩大范围以包括 可能 的匹配,而根据相关性得分将更好的匹配推到结果集的顶部。

事实上,只能完全匹配的全文搜索可能会困扰你的用户。 难道不希望在搜索 quick brown fox 时匹配一个包含 fast brown foxes 的文档, 搜索 Johnny Walker 同时匹配 Johnnie Walker ,搜索 Arnold Shcwarzenneger 同时匹配 Arnold Schwarzenegger ?

如果存在完全符合用户查询的文档,他们应该出现在结果集的顶部,而较弱的匹配可以被包含在列表的后面。 如果没有精确匹配的文档,至少我们可以显示有可能匹配用户要求的文档,它们甚至可能是用户最初想要的!

我们已经在 归一化词元 看过自由变音匹配, 将单词还原为词根 中的词干, 同义词 中的同义词, 但所有这些方法假定单词拼写正确,或者每个单词拼写只有唯一的方法。

Fuzzy matching 允许查询时匹配错误拼写的单词,而语音语汇单元过滤器可以在索引时用来进行 近似读音 匹配。

模糊性

模糊匹配 对待 “模糊” 相似的两个词似乎是同一个词。首先,我们需要对我们所说的 模糊性 进行定义。

在1965年,Vladimir Levenshtein 开发出了 Levenshtein distance, 用来度量从一个单词转换到另一个单词需要多少次单字符编辑。他提出了三种类型的单字符编辑:

  • 一个字符 替换 另一个字符: _f_ox → _b_ox
  • 插入 一个新的字符:sic → sic_k_
  • 删除 一个字符:b_l_ack → back

Frederick Damerau 后来在这些操作基础上做了一个扩展:

  • 相邻两个字符的 换位 : _st_ar → _ts_ar

举个例子,将单词 bieber 转换成 beaver 需要下面几个步骤:

  • 把 b 替换成 v :bie_b_er → bie_v_er
  • 把 i 替换成 a :b_i_ever → b_a_ ever
  • 把 e 和 a 进行换位:b_ae_ver → b_ea_ver

这三个步骤表示 Damerau-Levenshtein edit distance 编辑距离为 3 。

显然,从 beaver 转换成 bieber 是一个很长的过程—他们相距甚远而不能视为一个简单的拼写错误。 Damerau 发现 80% 的拼写错误编辑距离为 1 。换句话说, 80% 的拼写错误可以对原始字符串用 单次编辑 进行修正。

Elasticsearch 指定了 fuzziness 参数支持对最大编辑距离的配置,默认为 2 。

当然,单次编辑对字符串的影响取决于字符串的长度。对单词 hat 两次编辑能够产生 mad , 所以对一个只有 3 个字符长度的字符串允许两次编辑显然太多了。 fuzziness 参数可以被设置为 AUTO ,这将导致以下的最大编辑距离:

  • 字符串只有 1 到 2 个字符时是 0
  • 字符串有 3 、 4 或者 5 个字符时是 1
  • 字符串大于 5 个字符时是 2

当然,你可能会发现编辑距离 2 仍然是太多了,返回的结果似乎并不相关。 把最大 fuzziness 设置为 1 ,你可以得到更好的结果和更好的性能。

模糊查询

fuzzy 查询是 term 查询的模糊等价。 也许你很少直接使用它,但是理解它是如何工作的,可以帮助你在更高级别的 match 查询中使用模糊性。

为了解它是如何运作的,我们首先索引一些文档:

POST /my_index/_bulk
{ "index": { "_id": 1 }}
{ "text": "Surprise me!"}
{ "index": { "_id": 2 }}
{ "text": "That was surprising."}
{ "index": { "_id": 3 }}
{ "text": "I wasn't surprised."}

现在我们可以为词 surprize 运行一个 fuzzy 查询:

GET /my_index/_search
{
  "query": {
    "fuzzy": {
      "text": "surprize"
    }
  }
}

fuzzy 查询是一个词项级别的查询,所以它不做任何分析。它通过某个词项以及指定的 fuzziness 查找到词典中所有的词项。 fuzziness 默认设置为 AUTO 。

在我们的例子中, surprise 比较 surprise 和 surprised 都在编辑距离 2 以内, 所以文档 1 和 3 匹配。通过以下查询,我们可以减少匹配度到仅匹配 surprise :

GET /my_index/_search
{
  "query": {
    "fuzzy": {
      "text": {
        "value": "surprize",
        "fuzziness": 1
      }
    }
  }
}

提高性能

fuzzy 查询的工作原理是给定原始词项及构造一个 编辑自动机— 像表示所有原始字符串指定编辑距离的字符串的一个大图表。

然后模糊查询使用这个自动机依次高效遍历词典中的所有词项以确定是否匹配。 一旦收集了词典中存在的所有匹配项,就可以计算匹配文档列表。

当然,根据存储在索引中的数据类型,一个编辑距离 2 的模糊查询能够匹配一个非常大数量的词项同时执行效率会非常糟糕。 下面两个参数可以用来限制对性能的影响:

prefix_length
不能被 “模糊化” 的初始字符数。 大部分的拼写错误发生在词的结尾,而不是词的开始。 例如通过将 prefix_length 设置为 3 ,你可能够显著降低匹配的词项数量。
max_expansions
如果一个模糊查询扩展了三个或四个模糊选项, 这些新的模糊选项也许是有意义的。如 果它产生 1000 个模糊选项,那么就基本没有意义了。 设置 max_expansions 用来限制将产生的模糊选项的总数量。模糊查询将收集匹配词项直到达到 max_expansions 的限制。

模糊匹配查询

match 查询支持开箱即用的模糊匹配:

GET /my_index/_search
{
  "query": {
    "match": {
      "text": {
        "query":     "SURPRIZE ME!",
        "fuzziness": "AUTO",
        "operator":  "and"
      }
    }
  }
}

查询字符串首先进行分析,会产生词项 [surprize, me] ,并且每个词项根据指定的 fuzziness 进行模糊化。
同样, multi_match 查询也支持 fuzziness ,但只有当执行查询时类型是 best_fields 或者 most_fields :

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "fields":  [ "text", "title" ],
      "query":     "SURPRIZE ME!",
      "fuzziness": "AUTO"
    }
  },
  "explain": true
}

match 和 multi_match 查询都支持 prefix_length 和 max_expansions 参数。

模糊性评分

用户喜欢模糊查询。他们认为这种查询会魔法般的找到正确拼写组合。 很遗憾,实际效果平平。

假设我们有1000个文档包含 Schwarzenegger ,只是一个文档的出现拼写错误 Schwarzeneger 。 根据 term frequency/inverse document frequency 理论,这个拼写错误文档比拼写正确的相关度更高,因为错误拼写出现在更少的文档中!

换句话说,如果我们对待模糊匹配类似其他匹配方法,我们将偏爱错误的拼写超过了正确的拼写,这会让用户抓狂。

模糊匹配不应用于参与评分—​只能在有拼写错误时扩大匹配项的范围。

默认情况下, match 查询给定所有的模糊匹配的恒定评分为1。这可以满足在结果列表的末尾添加潜在的匹配记录,并且没有干扰非模糊查询的相关性评分。

在模糊查询最初出现时很少能单独使用。他们更好的作为一个 bigger 场景的部分功能特性,如 search-as-you-type 完成 建议或 did-you-mean 短语 建议。

标签:匹配,3.7,词项,模糊,查询,拼写错误,Elasticsearch,文档,fuzziness
From: https://blog.csdn.net/weixin_49131823/article/details/137528165

相关文章

  • ES(ElasticSearch)基础查询语法
    在ES中使用正确有意义的查询语句是很重要的,可以方便、快速的从大量数据中找到想要的数据。所以写好一个查询语句是必不可少的。ES分词器分词器是ES搜索引擎的核心特点,合理了解并使用可以发挥ES最大的效率。后面很多查询也有关,所以应该重点了解分词器。对于存入(Index)中的各个......
  • Elasticsearch之倒排索引、索引操作
    目录一、Elasticsearch之倒排索引1.倒排索引是什么2.举例3.倒排索引待解决的问题二、Elasticsearch之索引操作2.1创建索引2.2查询索引配置2.3更新索引2.4删除索引一、Elasticsearch之倒排索引1.倒排索引是什么倒排索引源于实际应用中需要根据属性的值来查找记录,这种索......
  • Elasticsearch之-mapping 映射管理
    目录Elasticsearch之-mapping映射管理一、映射介绍1.1字段数据类型1.2映射参数二、创建索引时指定映射2.16.x的版本写法2.27.x版本以后2.3插入数据测试三、查看索引Elasticsearch之-mapping映射管理在Elasticsearch6.0.0或更高版本中创建的索引只包含一个mappingtype......
  • Elasticsearch之数据的增删查改(CURD)
    目录Elasticsearch之数据的增删查改(CURD)一、CURD之Create(增)二、CURD之Update(改)三、CURD之Delete(删)四、CURD之Retrieve(查)Elasticsearch之数据的增删查改(CURD)一、CURD之Create(增)注意:当执行PUT命令时,如果数据不存在,则新增该条数据,如果数据存在则修改该条数据(这种修改相当于删......
  • Elasticsearch 配置内置分析器(3)
    一.内置分析器(analyzer)内置分析器无需任何配置即可直接使用,也支持配置选项来更改其行为。下面示例,分别使用了自定义分析器与内置分析器PUTmy-index-000001{"settings":{"analysis":{"analyzer":{"std_english":{#自定义分析......
  • Elasticsearch 悬挂索引分析和自己的一点见解
    在Elasticsearch的实战中,悬挂索引是一个既常见又容易引起困扰的概念。今天,我将分享一次处理集群状态为RED,原因为DANGLING_INDEX_IMPORTED 的实战经验,深入探讨悬挂索引的定义、产生原因、管理方法,以及如何有效处理它们,确保读者能够明白并解决自己面临的问题。值得一提的是,......
  • linux 环境下 elasticsearch 及 python 相关库的使用
    -elasticsearch是什么?elasticsearch简称es,是一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能。-安装1、下载官网下载地址2、解压tarzxvfelasticsearch-8.13.0-linux-x86_64.tar.gz-C/usr/local/3、解决JDK依赖问题新版本的es压缩......
  • elasticsearch-head的安装和使用
    一、elasticsearch-head插件介绍elasticsearch-head是elasticsearch的一款可视化工具,依赖于node.js,所以需要先安装node.js二、安装Node.js详情见文章nodejs安装和使用三、安装Grunt这一步可不做#Grunt是基于Node.js的项目构建工具。grunt作为一个前端构建工具,有资源......
  • Elasticsearch 配置与测试分析器 (2)
    一.配置文本分析器(Configuretextanalysis) 默认情况下,Elasticsearch使用standard分析器来进行文本分析,如果使用该分析器,则不用额外的配置。如果不满足,可以使用其它内置分析器,也可以创建自定义的分析器更好的控制,通常在生产实战中都是自定义分析器,方便更好扩展。 ......
  • Elasticsearch,使用scroll实现遍历(分页)查询
    为什么要使用scroll查询在使用es中,当某个index存贮的数据超过10000时,只能查询到10000的数据。因为index.max_result_window默认值是10000。并且使用游标查询可以在一次查询中获取大量文档,并且保持查询快照状态,允许用户多次检索数据而不影响其他并发请求。scroll查......