lucene评分-相似度算法的优化

lucene评分里使用的默认相似度算法是BM25,官方文档对BM25的参数(k1,b)调节有专门的介绍。
但是在短文本的场景下,就算是调节k1(一般调到0.3),也不能避免经常出现错误的评分排序。

研读lucene源码,在 BM25Similarity 这个类里,计算tfNorm的时候,公式是 (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)),其中fieldLength这个因子会存储到每个文档中。fieldLength,其意义就是每个文档当前field的分词的数目,其值范围不好预估。在计算过程中,该值本来是float类型。为了节省空间,lucene选择用byte类型来存储这个值,在保存前调用SmallFloat对值进行压缩。压缩就必然带来数值精度的损失。在 ClassicSimilarity 这个类的javadoc里,详细描述了值压缩的动机及后果。

在确定的短文本的场景下,完全可以修改 BM25Similarity 里所做的值压缩策略,以取得更准确的评分排序。压缩是从float转换为byte,默认转换策略是保留原float的高2位尾数和低6位阶码,这个转换结果表达的值范围大,但后续再转换回float精度很差。如果我们明确某个field的分词数量的大概范围,就可以改变压缩转换策略。比如对于短文本field,分词数量小于100,可以更改转换为保留高5位尾数和低3位价码,使精度变好(但值范围变小)。

在极端的场景下,如果明确field不会设置boost值,并且分词数量小于255,完全可以不做转换,直接返回分词数量值。

上述优化,需要自己写1个Similarity。如果是elasticsearch,则需要写plugin,在plugin中加入Similarity。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值