前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ElasticSearch之TF/IDF

ElasticSearch之TF/IDF

作者头像
丁D
发布2023-10-20 08:28:51
1530
发布2023-10-20 08:28:51
举报
文章被收录于专栏:老铁丁D

摘要本文将了解一下ElasticSearch控制相关度分数的TF/IDF,和向量空间模型

代码语言:javascript
复制
当我们使用es进行全文搜索的时候,es使用TF/IDF算法来计算scroe。
Term Frequency/Inverse Document Frequency简写(TF/IDF):词频/逆向文档频率
TF:词频,词条在当前文档中出现的有多频繁?越频繁的话,那么权重就越高。出现2次的
分数肯定比1次高。
IDF:逆向文档频率,词条在集合所有文档里出现的频率是多少?频次越高,权重 越低。
注意:这里的所有文档是指本地分片
假设我们现在有两个document
doc1:hello, today is very good
doc2:hi world, how are you
我们搜索hello world
TF: term frequency
找到hello在doc1中出现了几次,1次,会根据出现的次数给个分数
一个term在一个doc中,出现的次数越多,那么最后给的相关度评分就会越高
IDF:inversed document frequency
找到hello在所有的doc中出现的次数,1次
一个term在所有的doc中,出现的次数越多,那么最后给的相关度评分就会越低
length norm
hello搜索的那个field的长度,field长度越长,给的相关度评分越低; field长度越短,给的相关度评分越高
最后,会将hello这个term,对doc1的分数,综合TF,IDF,length norm,计算出来一个综合性的分数
hello world --> doc1 --> hello对doc1的分数,world对doc1的分数 --> 但是最后hello world query要对doc1有一个总的分数 --> vector space model

注意:

IDF:词条在集合所有文档里出现的频率是多少,这里的所有文档是指本地分片的所有文档,不是所有分片的所有文档,所以当index有多个share计算出来的记过就会不准确。

方案:

测试环境:可以通过设置只有一个share来处理问题,或者搜索请求中添加?search_type=dfs_query_then_fetch。dfs表示分布频度搜索(Distributed Frequency Search),它会告诉ES首先从每个分片中获取本地IDF,然后计算整个索引上的全局IDF。

生产环境:我们的文档被均匀地分布了,多个个分片上计算得到的IDF应该是相同的。现在想象一下如果含有foo的5份文档被保存在了分片1上,而只有1份含有foo的文档被保存在了分片2上。在这种情况下,词条foo在分片1上就是一个非常常见的词条(重要性很低),但是在分片2上,它是非常少见的词条(重要性很高)。因此,这些IDF的差异就会导致错误的结果。

实际情况下,这并不是一个问题。当你向索引中添加的文档越多,本地IDF和全局IDF之间的差异就会逐渐减小。考虑到真实的世界中的数据量,本地IDF很快就会变的正常。问题不是相关度,而是数据量太小了。

不要在生产环境中使用dfs_query_then_fetch。它真的是不必要的。性能太低。

代码语言:javascript
复制
TF:词频
如果不在意词在某个字段中出现的频次,而只在意是否出现过,则可以在字段映射中禁用词频统计:
PUT /my_index
{
"mappings": {
"doc": {
"properties": {
"text": {
"type": "string",
"index_options": "docs"
}
}
}
}
}
将参数 index_options 设置为 docs 可以禁用词频统计及词频位置,这个映射的字段不会计算词的出现次数,对于短语或近似查询也不可用。要求精确查询的 not_analyzed 字符串字段会默认使用该设置。
代码语言:javascript
复制
length norm:字段长度的归一值
字段长度的归一值对全文搜索非常重要, 许多其他字段不需要有归一值。无论文档是否
包括这个字段,索引中每个文档的每个 string 字段都大约占用 1 个 byte 的空
间。对于 not_analyzed 字符串字段的归一值默认是禁用的,而对于 analyzed 字
段也可以通过修改字段映射禁用归一值:
PUT /my_index
{
"mappings": {
"doc": {
"properties": {
"text": {
"type": "string",
"norms": { "enabled": false }
}
}
}
}
}
这个字段不会将字段长度归一值考虑在内,长字段和短字段会以相同长度计算评分。
对于有些应用场景如日志,归一值不是很有用,要关心的只是字段是否包含特殊的错误码
或者特定的浏览器唯一标识符。字段的长度对结果没有影响,禁用归一值可以节省大量内
存空间。

向量空间模型

代码语言:javascript
复制
向量空间模型提供了一种多词条查询的比较方法。它的输出是一个代表了文档和查询之间匹配程度的分值。为了计算该分值,文档和查询都被表示成向量。
一个向量实际上就是一个包含了数值的一维数组,比如:
[1,2,5,22,3,8]
在向量空间模型中,向量中的每个数值都是由TF/IDF计算得到的一个词条的权重。
假设我们查询了"happy hippopotamus"。一个像happy这样的常见单词的权重是较
低的,然而像hippopotamus这样的罕见单词则拥有较高的权重。假设happy的权重为
2而hippopotamus的权重为5。我们可以使用坐标来表达这个简单的二维向量 - [2, 5]
一条从坐标(0, 0)到坐标(2, 5)的直线,如下所示:
代码语言:javascript
复制
现在,假设我们有三份文档:
I am happy in summer.
After Christmas I’m a hippopotamus.
The happy hippopotamus helped Harry.
我们可以为每份文档创建一个类似的向量,它由每个查询词条的权重组成 - 也就是出现在文档中的词条happy和hippopotamus,然后将它绘制在坐标中,如下图:
文档1:(happy,____________) — [2,0]
文档2:( ___ ,hippopotamus) — [0,5]
文档3:(happy,hippopotamus) — [2,5]
向量的一个很棒的性质是它们能够被比较。通过测量查询向量和文档向量间的角度,我们可以给每份文档计算一个相关度分值。文档1和查询之间的角度较大,因此它的相关度较低。文档2和查询更靠近,所以它的相关度更高,而文档3和查询之间则是一个完美的匹配。

在实际中,只有二维向量(两个词的查询)可以在平面上表示,幸运的是, 线性代数 ——作为数学中处理向量的一个分支——为我们提供了计算两个多维向量间角度工具,这意味着可以使用如上同样的方式来解释多个词的查询。

参考 https://www.elastic.co/guide/cn/elasticsearch/guide/current/scoring-theory.html#tfidf

https://blog.csdn.net/wuzhiwei549/article/details/80407607

https://www.iteye.com/blog/study121007-2294453

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-09-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档