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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了验证相关度排序是否受查询的多个关键字在内容中相邻紧密程度有关相关的知识,希望对你有一定的参考价值。

昨天给公司同事们介绍了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受全文档数据的影响。


以上是关于验证相关度排序是否受查询的多个关键字在内容中相邻紧密程度有关的主要内容,如果未能解决你的问题,请参考以下文章

如何简化在字符串中搜索关键字并按相关性排序的 LINQ 查询?

solr 查询的相关配置

快速排序

从封装变化的角度看设计模式——对象创建

从封装变化的角度看设计模式——对象创建

排序算法之一冒泡排序