沙师弟,师父的充电器掉了

ES匹配度的打分问题

Elasticsearch | 作者 sishuidliunian | 发布于2019年01月02日 | 阅读数:20190

使用ES默认的打分规则(TF-IDF),搜索“葡萄糖”时,搜索结果中“纯净葡萄糖(食用葡萄糖)”比全匹配的“葡萄糖”的得分还要高。因为在前者中“葡萄糖”出现过两次。
但是我更想要全匹配的或匹配度更高的,而不关心出现的次数。对我来说,相比“纯净葡萄糖(食用葡萄糖)”,我希望“葡萄糖液”得分更好。因为“葡萄糖液”中关键字占了3/4,即使前者出现两次“葡萄糖”。
我该怎么修改?是修改TF-IDF配置,或者修改打分算法,还是自定义打分规则?
已邀请:

rochy - rochy_he

赞同来自: sishuidliunian

ES 支持关闭词频统计,设置 mapping 即可
PUT /my_index
{
"mappings": {
"doc": {
"properties": {
"text": {
"type": "string",
"index_options": "docs"
}
}
}
}
}

将参数 index_options 设置为 docs 可以禁用词频统计及词频位置,这个映射的字段不会计算词的出现次数,对于短语或近似查询也不可用。要求精确查询的 not_analyzed 字符串字段会默认使用该设置。
 
具体可参考:https://blog.csdn.net/paditang ... 98830

core_wzw - 某AILab搜索技术负责人

赞同来自: U5years

请用对的方式解决问题,另一个答案里提到的“关词频”肯定是不行的,人家还要打分排序,关词频只剩召回,明显不是楼主要的结果。
 
纠正下楼主一个错误,现在ES默认公式是BM25,并非早期版本默认的TFIDF变种。
 
BM25相对TFIDF优势就是来解决楼主提到的问题,正确的解决方式是修改k1和b值:
 
1. b用来控制字段长度fieldLength对score的惩罚程度。b=0,则fieldLength对score无影响,b=1,则fieldLength对score达到完全的惩罚作用。ES 中默认 b=0.75,你的场景可调整为b=0.1。顺便建议你查询分词用smart模式,索引分词用max模式。
 
2. 而k1用来控制公式对词项频率 tf 的敏感程度,k1越小,匹配到token的数目越多分数变化也不会那么大,ES中默认 k1=1.2,根据你的需求可调整为0.3。

sishuidliunian - 怎么能说是菜鸟呢,明明是弱鸡

赞同来自:

在加上index-options后
 
山鸡饮料.jpg


食用葡萄糖.jpg

 
如上面两个图所示,这两个图片都是在同一次查询中的结果,并且都是在同一个字段,为什么他们计算出的doc不一样?
图1中,doc=10515、docFreq=165、docCount=29862; 图2中,doc=15542、docFreq=176、docCount=29972。他们各自的含义是什么,统计的基础是什么?
 
另外关于字段长度计算的,在图1中,该文档的字段值为“葡萄糖山药鸡内金固体饮料”,但是fieldLength=7;图2中该文档的字段值为“纯净葡萄糖(食用葡萄糖)”,但filedLength=8; 并且avgFieldLength也不相等。fieldLength不是值得字段值的长度吗?
 
感谢

Merrizee

赞同来自:

打分是建索引,分词的时候就打好的?

U5years

赞同来自:

ES 5.0以后的版本,默认的相似度算分算法变成了BM25算法。赞同楼上 core_wzw的说法,但是需要补充的是:
 
k1和b值都有自己的取值范围和最佳的范围(官方文档):
 
b应该在[0,1]之间,理想的范围应该是[0.3, 0.9]; 
k1应该在[0,3]之间,当然可以更高,理想的范围应该是[0.5,2.0]
 
如果长文档的话,b值设置的低一些,主题比较分散的文档,k1设置得高一些。
 
另外,调整k1和b并不是见效最快的方式,用其他的方式,换个分词器,phrase matches等方式的效果会更好。

kamzhuyuqing

赞同来自:

这个问题最后的解决方案是关闭了词频的影响吗

要回复问题请先登录注册