验证相关度排序是否受查询的多个关键字在内容中相邻紧密程度有关

昨天给公司同事们介绍了lucene相关度打分的公式,大家提到了一个问题,总感觉用相关度排序的时候,lucene会把查询关键字相邻紧密的doc排在前面,但是打分公式里面却没提到过这个因素,所以我现在来验证下查询词的紧密程度是否会影响打分。

局部代码

添加doc程序

1 设置lucene保存field的所有信息,包括词位置, payloads等等

FieldType ty = new FieldType();
ty.setIndexed(true);
ty.setStored(true);
ty.setTokenized(true);
ty.setStoreTermVectors(true);
ty.setStoreTermVectorOffsets(true);
ty.setStoreTermVectorPositions(true);
ty.setStoreTermVectorPayloads(true);
IndexOptions value = IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS;
ty.setIndexOptions(value);

2 分词器选择单字分词, 每document只有一个单field

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_48);

Document doc = new Document();
Field f = null;
f = new Field("content", valueString, ty);
doc.add(f);

查询doc程序

查询内容也采用单字分词

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_48);

QueryParser parser = new QueryParser(Version.LUCENE_48, field, analyzer);

查询排序选择sort(),就是相关度排序

TopFieldDocs results = searcher.search(query, 1, new Sort());
ScoreDoc[] hits = results.scoreDocs;

==================================================

我会陆续插入几篇包含“中”“国”这两个字的doc,然后对“中国”进行查询(分词)

1 来验证查询的term在文中的绝对位置是否影响分数

我插入下面三篇内容,这三篇除了“中国”的位置不一样,内容长度,tf,idf还有查询词的相邻程度都是一样的,避免其他因素影响排序

移动网上营业厅中国
移动网上中国营业厅
中国移动网上营业厅

查询的结果如下,三篇的打分一样,按在插入的顺序排列

这说明查询的term在文中的绝对位置不影响分数,分数一样的doc会按在插入顺序排序

doc hit : 3
content: 移动网上营业厅中国 | score : 0.314803
content: 移动网上中国营业厅 | score : 0.314803
content: 中国移动网上营业厅 | score : 0.314803

==================================================

2 来验证查询的term在文中相邻程度是否影响分数

我再插入3篇内容,这三篇内容的查询词相邻程度都不一样

国移动网上营业厅中

国移动网中上营业厅

移动网中上国营业厅

查询的结果如下,新的三篇和旧的三篇打分依旧一样

这说明查询的term在文中相邻程度也不影响分数

doc hit : 6
content: 移动网上营业厅中国 | score : 0.37381613
content: 移动网上中国营业厅 | score : 0.37381613
content: 中国移动网上营业厅 | score : 0.37381613
content: 国移动网上营业厅中 | score : 0.37381613
content: 国移动网中上营业厅 | score : 0.37381613
content: 移动网中上国营业厅 | score : 0.37381613

ps:这次的doc分数虽然都相同,但是却比上一次的要高一点,这是受idf变大的影响,idf的公式如下

idf(t)  =   1 + log (
numDocs
–––––––––  )
docFreq+1

numDocs是文章总个数,docFreq是包含查询term的doc个数,因为测试里面每篇doc都包含term,所以这两个变量是一样的,加入doc越多会导致log里的值变大且无限逼近于1,idf就变大了,分数也就提高了

==================================================

3 来验证查询的term的tf和文章长度是否影响分数

我再插入2篇内容,这一篇内容的查询词tf高,一篇长度短,一篇长度短且tf高,其他还是一样

国移动网中营业厅中

国移动营业厅中

国移动中业厅中

查询结果如下,长度短且tf高的doc分数最高,查询词tf高和内容长度短的两篇排下面,但是分数仅仅略微差别,排最后的是前面插入的6篇

doc hit : 9
content: 国移动中业厅中 | score : 0.5727169
content: 国移动网中营业厅中 | score : 0.47726405
content: 国移动营业厅中 | score : 0.47445422
content: 移动网上营业厅中国 | score : 0.3953785
content: 移动网上中国营业厅 | score : 0.3953785
content: 中国移动网上营业厅 | score : 0.3953785
content: 国移动网上营业厅中 | score : 0.3953785
content: 国移动网中上营业厅 | score : 0.3953785
content: 移动网中上国营业厅 | score : 0.3953785

结论

查询词的位置,紧密程度不影响打分

内容长度和tf值都会对分数有影响,但是这两个因素没绝对的优先级

同查询条件下的对同一篇文章的分数不是一个定值,因为每个词的IDF受全文档数据的影响。

时间: 2024-10-05 19:13:20

验证相关度排序是否受查询的多个关键字在内容中相邻紧密程度有关的相关文章

Lucene08-Lucene的相关度排序

目录 1 什么是相关度 2 相关度评分 3 相关度设置 3.1 需求 3.2 广告设置中...... 1 什么是相关度 概念: 相关度指两个事物之间的关联关系(相关性). Lucene中指的是搜索关键词(Term)与搜索结果之间的相关性. 如: 搜索bookname域中包含java的图书, 则根据java在bookname中出现的次数和位置来判断结果的相关性. 2 相关度评分 Lucene对查询关键字和索引文档的相关度进行打分, 得分越高排序越靠前. Lucene的打分方法: Lucene在用户

Lucene底层储存结构、优化和相关度排序

lucene详细存储结构: 索引 (Index) : 一个目录一个索引,在 Lucene 中一个索引是放在一个文件夹中的. 段(Segment) : 一个索引 (逻辑索引)由多个段组成, 多个段可以合并, 以减少读取内容时候的磁盘IO. Lucene 中的数据写入会先写在内存的一个Buffer,当Buffer内数据到一定量后会被flush成一个Segment,每个Segment有自己独立的索引,可独立被查询,但数据永远不能被更改.这种模式避免了随机写,数据写入都是批量追加,能达到很高的吞吐量.S

MySQL进阶5--分组排序和分组查询 group by(having) /order by

MySQL进阶--分组排序和分组查询 group by(having) /order by /* 介绍分组函数 功能:用做统计使用,又称为聚合函数或组函数 1.分类: sum, avg 求和 /平均数, 只处理数值型,都绝对忽略NULL值(avg处理时统计的个数没有null项) max ,min ,可以求字符串最大最小 ,可以匹配日期,都绝对忽略NULL值 count ,不计算NULL ,不把null算进数里 #2. 参数支持类型 SELECT MIN(last_name) ,MAX(last_

oracle篇 之 排序、限制查询行

第二章:排序.限制查询行 一.order by子句 1.order by排序规则 (1)asc,升序排列,默认取值 (2)desc,降序排列 (3)order by是select命令的最后一个子句 select last_name,salary,dept_id from s_emp order by salary; select last_name,salary,dept_id from s_emp order by salary asc; select last_name,salary,dep

Oracle层次查询和分析函数在号段选取中的应用

转自:http://www.itpub.net/thread-719692-1-1.html 摘要一组连续的数,去掉中间一些数,如何求出剩下的数的区间(即号段)?知道号段的起止,如何求出该号段内所有的数?知道一个大的号段范围和已经取过的号段,如何求出可用的号段?利用Oracle提供的强大的查询功能以及分析函数,我们可以很轻松的解决上述问题. 关键词:号段选取.连续数.断点.层次查询.分析函数.connect by.rownum.level.lead.lag 1.        问题的提出在实际工

mysql 可以根据查询结果插入到指定的表中

MySQL可以根据查询到的记录集插入到指定的表中其例子为: 首先阐述三张表的结构: s(sno,sname.sex,age,dept)   //学生信息表 c(cno,cname,tname)      //课程信息表 sc(sno,cno,grade)              //课程选修信息表 那么现在就是问题是: 将一门课的成绩大于等于80分学生的学号.姓名和系名插入到一个已存在(要建立)基本表stu(sno,sname,dept)中 stu表已存在   数据库Schema为: <spa

【c语言】输入一个递增排序的数组的一个旋转,输出旋转数组中的最小元素

//旋转数组的最小数字 //题目:把一个数组最開始的若干个元素搬到数组的末尾.我们称之为数组的旋转. //输入一个递增排序的数组的一个旋转.输出旋转数组中的最小元素. //比如:数组{3.4,5,1,2}为{1,2.3.4.5}的一个旋转,最小元素是1. #include <stdio.h> #include <assert.h> int min_equ(int *src, int left, int right) { int i = 0; int ret = src[left];

14.输入一个已经按升序排序过的数组和一个数字, 在数组中查找两个数,使得它们的和正好是输入的那个数字。 要求时间复杂度是O(n)

待完善! 转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4259199.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目: 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.要求时间复杂度是O(n).如果有多对数字的和等于输

oc将字符串中单词按照出现次数(次数都不一样)降序排序,排序之后单词只出现一次,源字符串中单词用下划线连接,生成字符串也用下滑线连接

/* 将字符串中单词按照出现次数(次数都不一样)降序排序,排序之后单词只出现一次,源字符串中单词用下划线连接,生成字符串也用下滑线连接(10分) 如传入:@"good_good_study_good_study" 返回:@"good_study" 如传入:@"I_love_I_hate_love_love" 返回:@"love_I_hate" */ 方法1:选择排序 -(NSString *)sortStringByNumbe