Lucene的排序算法
来源:互联网 发布:剑侠情缘网络版叁mac 编辑:程序博客网 时间:2024/06/05 13:11
公式:
1 tf(t in d) term frequency与term的出现次数(frequency)有关系(correlate to),定义为(defined as)term t在当前算分(currently scored)的文档d中出现(appear in)的次数(number of times)。对一个给定(gived)的term,那些出现此term的次数越多(more occurences)的文档将获得越高的分数(higher score)。缺省的tf(t in d)算法实现在DefaultSimilarity类中,公式如下
2 idf(t) Inverse Document Frequency 代表(stand for)反转文档频率(Inverse Document Frequency)。这个分数与反转(inverse of)的docFreq(出现过term t的文档数目)有关系。这个分数的意义是越不常出现(rarer)的term将为最后的总分贡献(contribution)更多的分数。缺省idff(t in d)算法实现在DefaultSimilarity类中,公式如下
3 coord(q,d) 是一个评分因子,基于(based on)有多少个查询terms在特定的文档(specified document)中被找到。通常(typically),一篇包含了越多的查询terms的文档将比另一篇包含更少查询terms的文档获得更高的分数。这是一个搜索时的因子(search time factor)是在搜索的时候起作用(in effect at search time),它在Similarity对象的coord(q,d)函数中计算
4 queryNorm(q) 是一个修正因子(normalizing factor),用来使不同查询间的分数更可比较(comparable)。这个因子不影响文档的排名(ranking)(因为搜索排好序的文档(ranked document)会增加(multiplied)相同的因数(same factor)),更确切地说只是(but rather just)为了尝试(attempt to)使得不同查询条件(甚至不同索引(different indexes))之间更可比较性。这是一个搜索时的因子是在搜索的时候起作用,由Similarity对象计算。缺省queryNorm(q)算法实现在DefaultSimilarity类中,公式如下
sumOfSquaredWeights(查询的terms)是由查询Weight对象计算的,例如一个布尔(boolean)条件查询的计算公式为
5 t.getBoost() 是一个搜索时(search time)的代表查询q中的term t的boost数值,具体指定在(as specified in)查询的文本中(参见查询语法),或者由应用程序调用setBoost()来指定。需要注意的是实际上(really)没有一个直接(direct)的API来访问(accessing)一个多个term的查询(multi term query)中的一个term 的boost值,更确切地说(but rather),多个terms(multi terms)在一个查询里的表示形式(represent as)是多个TermQuery对象,所以查询里的一个term的boost值的访问是通过调用子查询(sub-query)的getBoost()方法实现的。
6 norm(t,d) 是提炼取得(encapsulate)一小部分boost值(在索引时间)和长度因子(length factor):
ú document boost – 在添加文档到索引之前通过调用doc.setBoost()来设置。
ú Field boost – 在添加Field到文档之前通过调用field.setBoost()来设置。
ú lengthNorm(field) – 在文档添加到索引的时候,根据(in accordance with)文档中该field的tokens数目计算得出,所以更短(shorter)的field会贡献更多的分数。lengthNorm是在索引的时候起作用,由Similarity类计算得出。
当一篇文档被添加到索引的时候,所有上面计算出的因子将相乘起来(multiplied)。如果文档拥有多个相同名字的fields(multiple fields with same name),所有这些fields的boost值也会被一起相乘起来(multiplied together)
1. score_d: Document(d) 的得分
2. sum_t: Term(t) 的总和
3. tf_q: 是查询的词在文档中出现的次数的平方根 (d 中 t 的频度的平方根)
4. idf_t: 表示反转文档频率,观察了一下所有的文档都一样,所以那就没什么用处,不会起什么决定作用。
组成: idf_t : log(numDocs/docFreq_t + 1) + 1.0
5. numDocs: 索引中Document的数量
6. docFreq_t: 包含t的Document的数量
7. norm_q: sqrt(sum_t((tf_q*idf_t)^2))
8. norm_d_t: 在与 t 相同域的 d 中 tokens 数量的平方根
下面用代码和运行结果来进行说明:
Java代码
- public class ScoreSortTest {
- public final static String INDEX_STORE_PATH = "index";
- public static void main(String[] args) throws Exception {
- IndexWriter writer = new IndexWriter(INDEX_STORE_PATH, new StandardAnalyzer(), true);
- writer.setUseCompoundFile(false);
- Document doc1 = new Document();
- Document doc2 = new Document();
- Document doc3 = new Document();
- Field f1 = new Field("bookname","bc bc", Field.Store.YES, Field.Index.TOKENIZED);
- Field f2 = new Field("bookname","ab bc", Field.Store.YES, Field.Index.TOKENIZED);
- Field f3 = new Field("bookname","ab bc cd", Field.Store.YES, Field.Index.TOKENIZED);
- doc1.add(f1);
- doc2.add(f2);
- doc3.add(f3);
- writer.addDocument(doc1);
- writer.addDocument(doc2);
- writer.addDocument(doc3);
- writer.close();
- IndexSearcher searcher = new IndexSearcher(INDEX_STORE_PATH);
- TermQuery q = new TermQuery(new Term("bookname", "bc"));
- // TermQuery q2 = new TermQuery(new Term(“bookTitle”,”bc”);
- // BooleanQuery bq = new BooleanQuery();
- // bq.add(q);
- // bq.add(q2);
- // Searcher.search(bq);
- q.setBoost(2f);
- Hits hits = searcher.search(q);
- for(int i=0; i<hits.length();i++){
- Document doc = hits.doc(i);
- System.out.print(doc.get("bookname") + "/t/t");
- System.out.println(hits.score(i));
- System.out.println(searcher.explain(q, hits.id(i)));//
- }
- }
- }
运行结果:
引用
bc bc 0.629606
0.629606 = (MATCH) fieldWeight(bookname:bc in 0), product of:
1.4142135 = tf(termFreq(bookname:bc)=2)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=0)
ab bc 0.4451987
0.4451987 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=1)
ab bc cd 0.35615897
0.35615897 = (MATCH) fieldWeight(bookname:bc in 2), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.5 = fieldNorm(field=bookname, doc=2)
从结果中我们可以看到:
bc bc文档中bc出现了2次,tf为2的平方根,所以是1.4142135。而其他的两个文档出现了一次,所以是1.0
所有的三个文档的idf值都是一样的,是0.71231794
默认情况下,boost的值都是1.0,所以lengthNorm就是当前的fieldNorm的值。前两个文档的长度一致,为0.625,而排在最后的文档,因为长度要长一些,所以分值要低,为0.5
现在对f2这个字段增加激励因子:f2.setBoost(2.0f);
运行结果变为:
引用
ab bc 0.8903974
0.8903974 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
1.25 = fieldNorm(field=bookname, doc=1)
发现fieldNorm值有0.625变成了1.25,所以就是乘以了2.0
接下来再对第二个文档增加激励因子:doc2.setBoost(2.0f);
运行结果变为:
引用
ab bc 1.0
1.7807949 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
2.5 = fieldNorm(field=bookname, doc=1)
发现fieldNorm又乘以了2,所以说对于Document和Field的setBoost都会乘到一起。
因为该文档的最终的score超过了1.0变成1.7807949,所以其他的两个文档的最终得分都要除以该值,
分别变成:
引用
bc bc 0.35355335
ab bc cd 0.19999999
相信通过上面的解释,大家就可以形象得理解Lucene的打分机制,同时也知道如何来改变文档的得分。
要点:
查询词在一个 Document 中的位置并不重要。
如果一个 Document 中含有该查询词的次数越多,该得分越高。
一个命中document中,如果除了该查询词之外,其他的词越多,该得分越少。
- Lucene的排序算法
- Lucene基础排序算法
- lucene 排序算法思路
- Lucene基础排序算法改进
- 将BM25 用作lucene排序算法的实现步骤
- 排序字符串的前缀压缩算法,结合lucene
- 自定义的Lucene排序
- Lucene的排序搜索
- Lucene 的索引排序
- Lucene的算法原理
- lucene自定义排序的实现
- Lucene 的查询方式|排序
- Lucene的搜索结果排序
- 索引算法(Lucene的实现)
- Lucene的全文检索算法
- lucene排序
- Lucene排序
- lucene涉及到的算法----二元搜索算法
- 笔试题收集-2
- 网站关键字
- JAVA面试官
- 工作流宏语言iScript
- Lucene 倒排原理
- Lucene的排序算法
- asp.net 导出Excel时,解决纯数字字符串变成类似这样的 2.00908E+18 形式的代码
- 查看 MySql 字符集
- javascript中loose type的影响
- 数据库:使用SQL Server 数据库基础
- pb删除文件夹
- ubuntu 基本命令
- Vss2005 for vs 2008使用文档(仅局域网)
- 加快网站让百度收录的方法