lucene打分机制

一:相似度算法

lucene采用的是基于VSM(向量空间模型)的相似度算法,

  查询向量(query vector)与搜索出来的文档向量(document vector) 形成N个夹角,计算q 和d  之间的夹角,最小的 就是相

度最高的。



二:lucene的打分公式

看下lucene的打分公式:


评分公式中的因子

评分因子

 

tf(t in d)

项频率因子——文档d)中出现项t)的频率

idf(t)

项在倒排文档中出现的频率:它被用来衡量项的唯一性.出现频率较高的term具有较低的idf,出现较少的term具有较高的idf

boost(t.field in d)

域和文档的加权,在索引期间设置.你可以用该方法 对某个域或文档进行静态单独加权

lengthNorm(t.field in d)

域的归一化Normalization)值,表示域中包含的项数量.该值在索引期间计算,并保存在索引norm.对于该因子,更短的域或更少的语汇单元)能获得更大的加权

coord(q,d)

协调因子(Coordination factor),基于文档中包含查询的项个数.该因子会对包含更多搜索项的文档进行类似AND的加权

queryNorm(q)

每个査询的归一化值指毎个查询项权重的平方和

在Lucene中score简单说是由tf * idf * boost * norm 计算得出的。 


代码实现,必要时可以重写代码。在Lucene的DefaultSimilarity类

1:协调coord(q,d)

<span style="font-size:14px;">  @Override
  public float coord(int overlap, int maxOverlap) {
    return overlap / (float)maxOverlap;
  }</span>

overlap: 文档中命中检索的个数

maxOverlap: 检索条件的个数

比如检索"english book", 现在有一个文档是"this is an chinese book"。

那么,这个搜索对应这个文档的overlap为1(因为匹配了book),而maxOverlap为2(因为检索条件有两个book和english)。

最后得到的这个搜索对应这个文档的coord值为0.5。


2:queryNorm(q)   查询规范 :由idf、权重影响

这个因素对所有文档都是一样的值,所以它不影响排序结果。但是如果每次查询的权重不一样,那么该值就会变动

比如如果我们希望所有文档的评分大一点,那么我们就需要设置这个值。

<span style="font-size:14px;">  /** Implemented as <code>1/sqrt(sumOfSquaredWeights)</code>. */
  @Override
  public float queryNorm(float sumOfSquaredWeights) {
    return (float)(1.0 / Math.sqrt(sumOfSquaredWeights));
  }</span>


3:tf 单个文档词频

函数图:


只在商品名称中出现了1次。。他的tf =1 

Math.sqrt  取平方根   Math.sqrt(9)=3.0
如果搜索“笔记本”  ,在分类和商品名称中都出现了  他的tf 就是1.414 (2次的平方根)
只在商品名称中出现了1次。。他的tf =1 

<span style="font-size:14px;">  @Override
  public float tf(float freq) {
    return (float)Math.sqrt(freq);
  }</span>

4:idf(t) 一个term在多少个文档中出现过


numDocs  总文档数   docFreq 在多少文档中出现过

如果搜索“笔记本”  ,总文档有1000个 ,,出现100次。。那么idf=2

如果出现10次 那么其idf =3

idf 越高、在总文档数中 该词出现的频率越低

<span style="font-size:14px;">public float idf(long docFreq, long numDocs) {
    return (float)(Math.log(numDocs/(double)(docFreq+1)) + 1.0);
}</span>


5:t.getBoost() 权重

6:norm(t,d)  字段标准化


对term和文档的字段长度进行标准化计算 ,如果字段的长度越长,那么该值越低。

<span style="font-size:14px;">  @Override
  public float lengthNorm(FieldInvertState state) {
    final int numTerms;
    if (discountOverlaps)
      numTerms = state.getLength() - state.getNumOverlap();
    else
      numTerms = state.getLength();
    return state.getBoost() * ((float) (1.0 / Math.sqrt(numTerms)));
  }</span>


三:总匹配分值的计算

最终匹配分值score = 查询语句在N个域中的得分之和  * coord的值

每个域中的得分 = queryWeight * fieldWeight 

queryWeight = idf  * queryNorm * boost

fieldWeight=idf * fieldNorm * tf


假设在两个域A,B中查询,那么总结公式 :

score = sum( A(queryWeight=idf*queryNorm*boost + fieldWeight=idf*fieldNorm*tf) *          B(queryWeight=idf*queryNorm*boost +fieldWeight=idf*fieldNorm*tf))*  1/2


电商体验:

在电商搜索中。一般基于VSM算法推导出来的lucene 算法 的tf idf 会被忽视,应为这两个值没有用的。真正用到的是 boost得分和 norm 得分。。

solr的一个bf参数:设置归一函数

elasticsearch 脚本排序:文本相似度得分作为协调因子*(归一函数得分之和)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值