Lucene 对文档打分的规则整理记录
摘引自:http://www.cnblogs.com/forfuture1978/archive/2010/02/08/1666137.html
Lucene的搜索结果默认按相关度排序,这个相关度排序是基于内部的Score和DocID,Score又基于关键词的内部评分和做索引时的 boost。默认Score高的排前面,如果Score一样,再按索引顺序,先索引的排前面。
Sort groupSort = new Sort(new SortField("排序字段name", SortField.Type.long, true));//true为逆向排序
按字段排序:searcher.search(query, sort)
一:索引阶段设置Document Boost和Field Boost
//Document Boost和Field Boost默认为1。
Document doc = new Document();
Field f = new Field("contents", "hello world", Field.Store.NO, Field.Index.ANALYZED); //Field f = new Field("contents", "hello world", Field.Store.NO, Field.Index.ANALYZED_NO_NORMS);
f.setBoost(100);
doc.add(f);
doc.setBoost(100);
1).Document boost:此值越大,说明此文档越重要。
2).Field boost:此域越大,说明此域越重要。
3).lengthNorm(field) = (1.0 / Math.sqrt(numTerms)):一个域中包含的Term总数越多,也即文档越长,此值越小,文档越短,此值越大。
当设置:Field.Index.ANALYZED_NO_NORMS 第三个因素影响无效
当设置:Field.Index.ANALYZED 第三个因素影响生效
norms(标准化因子)意义:
没有norms意味着索引阶段禁用了文档boost和域的boost及长度标准化。
好处:在于节省内存,不用在搜索阶段为索引中的每篇文档的每个域都占用一 个字节来保存norms信息了。但是对norms信息的禁用是必须全部域都禁用的,一旦有一个域不禁用,则其他禁用的域也会存放默认的norms值。因为为了加快norms的搜索速度,Lucene是根据文档号乘以每篇文档的norms信息所占用的大小来计算偏移量的,中间少一篇文档,偏移量将无法计算,因为大家知道,偏移是相对来说的,一旦它相对的某篇文档缺失了,那么后面的偏移量也就不复存在了 也即norms信息要么都保存,要么都不保存。
二、在搜索语句中,设置Query Boost.
同域:
title:马德华^4 title:刘德华 这样就人为的干预了搜出来的结果,马德华的结果比较靠前 不同域:
title:马德华^100 content:马德华
title中包含马德华的文档比content中包含马德华的文档获得更高的分数
三、继承并实现自己的Similarity
Similariy是计算Lucene打分的最主要的类,实现其中的很多接口可以干预打分的过程
(1) float computeNorm(String field, FieldInvertState state) (2) float lengthNorm(String fieldName, int numTokens) (3) float queryNorm(float sumOfSquaredWeights) (4) float tf(float freq) (5) float idf(int docFreq, int numDocs) (6) float coord(int overlap, int maxOverlap) (7) float scorePayload(int docId, String fieldName, int start, int end, byte [] payload, int offset, int length) 它们分别影响Lucene打分计算的如下部分:
score(q,d) = (6)coord(q,d) · (3)queryNorm(q) · ∑( (4)tf(t in d) · (5)idf(t)2 · t.getBoost() · (1)norm(t,d) )
t in q
norm(t,d) =doc.getBoost()· (2)lengthNorm(field)· ∏f.getBoost() field f in d named as t
(1) float computeNorm(String field, FieldInvertState state)
影响标准化因子的计算,如上述,他主要包含了三部分:文档boost,域boost,以及文档长度归一化。此函数一般按照上面norm(t, d)的公式进行计算。
(2) float lengthNorm(String fieldName, int numTokens)
在一篇1000万个词的鸿篇巨著中,"lucene"这个词出现了11次,而在一篇12个词的短小文档中,"lucene"这个词出现了10次,如果不考虑长度在内,当然鸿篇巨著应该分数更高,然而显然这篇小文档才是真正关注"lucene"的。因而在此处是要除以文档的长度,从而减少因文档长度带来的打分不公。
但是实际情况是需要灵活多变的,所以文档长度也需要自己控制下,比如我想做一个经济学论文的搜索系统,经过一定时间的调研,发现大多数的经济学论文的长度在8000到10000词,因而lengthNorm的公式应该 是一个倒抛物线型的,8000到10000词的论文分数最高,更短或更长的分数都应该偏低,方能够返回给用户最好的数据。
(3) float queryNorm(float sumOfSquaredWeights)
这是按照向量空间模型,对query向量的归一化。此值并不影响排序,而仅仅使得不同的query之间的分数可以比较。
(4) float tf(float freq)
freq是指在一篇文档中包含的某个词的数目。tf是根据此数目给出的分数,默认为Math.sqrt(freq)。也即此项并不是随着包含的数目的增多而线性增加的。
Math.sqrt(freq); freq开平方
(5) float idf(int docFreq, int numDocs)
idf是根据包含某个词的文档数以及总文档数计算出的分数,默认为(Math.log(numDocs/(double)(docFreq+1)) + 1.0)。
由于此项计算涉及到总文档数和包含此词的文档数,因而需要全局的文档数信息,这给跨索引搜索造成麻烦。
从下面的例子我们可以看出,用MultiSearcher来一起搜索两个索引和分别用IndexSearcher来搜索两个索引所得出的分数是有很大差异的。
(6) float coord(int overlap, int maxOverlap)
一次搜索可能包含多个搜索词,而一篇文档中也可能包含多个搜索词,此项表示,当一篇文档中包含的搜索词越多,则此文档则打分越高。
(7) float scorePayload(int docId, String fieldName, int start, int end, byte [] payload, int offset, int length)
由于Lucene引入了payload,因而可以存储一些自己的信息,用户可以根据自己存储的信息,来影响Lucene的打分。
四、继承并实现自己的collector
Lucene 对文档打分的规则整理记录的更多相关文章
- 有关Lucene的问题(4):影响Lucene对文档打分的四种方式
原文出自:http://forfuture1978.iteye.com/blog/591804点击打开链接 在索引阶段设置Document Boost和Field Boost,存储在(.nrm)文件中 ...
- 用Lucene对文档进行索引搜索
问题 现在给出很多份文档,现在对某个搜索词感兴趣,想找到相关的文档. 简单搜索 一种简单粗暴的做法是: 1.读取每个文档:2.找到其中含有搜索词的文档:3.对找到的文档中搜索词出现的次数统计:4.根据 ...
- 2019年最新总结,从程序员到CTO,从专业走向卓越,大牛分享文档pdf与PPT整理
整理大牛分享文档如下,持续更新一线开发架构,技术文档 github链接 网易蜂巢公有容器云架构之路 新浪微博redis优化历程 微博Cache架构设计实践 Go在大数据开发中的经验总结 基于Go构建滴 ...
- 【资源】108个大数据文档PDF开放下载-整理后打包下载
本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html 本博客其他.NET开源项目文章目录:h ...
- LotusScript_文档查询循环方法整理
1. 视图(View)查询 ... Set view = db.GetView("ViewName") Set doc = view.GetFirstDocument While ...
- 转: seajs手册与文档之 -- require规则
require 规则 正确拼写 不要修改 使用直接量 动态依赖的小提示 书写规则 使用 SeaJS 书写模块代码时,需要遵循一些简单规则: 1. 正确拼写 在模块代码中,第一个参数 必须 命名为 re ...
- antd模块组件文档思维导图整理
- 学习Java爬虫文档的学习顺序整理
1.认识正则表达式(Java语言基础) https://www.toutiao.com/i6796233686455943693/ 2.正则表达式学习之简单手机号和邮箱练习 https://www.t ...
- openWRT自学---对官方的开发指导文档的解读和理解 记录3:一些常用方法
1.约定 configuration files follow the convention: <name>.conf init files follow the convention: ...
随机推荐
- Linux下进程的建立
Linux下进程的建立 我们都知道,进程就是正在执行的程序.而在Linux中,可以使用一个进程来创建另外一个进程.这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使 ...
- kali linux karmetasploit配置【续】
Karmetasploit In Action https://www.offensive-security.com/metasploit-unleashed/karmetasploit-action ...
- Titanium vs PhoneGap
http://mobile.51cto.com/Titanium-318049.htm http://www.ibm.com/developerworks/cn/opensource/os-titan ...
- 2016-1-3点菜系统demo的实现,pickerView的学习
// // ViewController.m // pickView // // Created by Mac on 16/1/3. // Copyright © 2016年 Mac. All rig ...
- 技术分享:如何用Solr搭建大数据查询平台
0×00 开头照例扯淡 自从各种脱裤门事件开始层出不穷,在下就学乖了,各个地方的密码全都改成不一样的,重要帐号的密码定期更换,生怕被人社出祖宗十八代的我,甚至开始用起了假名字,我给自己起一新网名”兴才 ...
- Python 安全类目推荐 (持续更新)
推荐学习书目 › Learn Python the Hard Way › Python 学习手册 › Python Cookbook › Python 基础教程 Python Sites › PyPI ...
- 深入分析:Fragment与Activity交互的几种方式(二,使用Bundle)
首先我们需要在Activity中动态添加Fragment时,用Bundle封装我们需要传递的数据. public void button(View view) { ArgFragment arg = ...
- linux常用命令:1文件处理命令
文件处理命令 1.命令格式 命令格式:命令 [-选项] [参数] 例:ls -la /etc 说明:1)个别命令使用不遵循此格式 2)档有多个选项时,可以写在一起 3)简化选项与完整选项 2.目录 ...
- Windows10中无法打开这个应用的解决方案
报错的图:
- ios oc ui 路径和颜色设置--崩溃解决方案
- (id)init{ self = [super init]; if (self) { _lineColor = CGColorCreateCopy([UIColor whiteColor].CGC ...