Lucene的评分(score)机制的简单解释
生活随笔
收集整理的這篇文章主要介紹了
Lucene的评分(score)机制的简单解释
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Lucene的評分(score)機制的簡單解釋
在Lucene中score簡單說是由 tf * idf * boost * lengthNorm計算得出的。
tf:是查詢的詞在文檔中出現的次數的平方根
idf:表示反轉文檔頻率,觀察了一下所有的文檔都一樣,所以那就沒什么用處,不會起什么決定作用。
boost:激勵因子,可以通過setBoost方法設置,需要說明的通過field和doc都可以設置,所設置的值會同時起作用
lengthNorm:是由搜索的field的長度決定了,越長文檔的分值越低。
所以我們編程能夠控制score的就是設置boost值。
還有個問題,為什么一次查詢后最大的分值總是1.0呢?
因為Lucene會把計算后,最大分值超過1.0的分值作為分母,其他的文檔的分值都除以這個最大值,計算出最終的得分。
下面用代碼和運行結果來進行說明:
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"));?? ????????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)));//?? ????????}?? ????}?? }?? 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"));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的打分機制,同時也知道如何來改變文檔的得分。
- 博客分類:
- Lucene
在Lucene中score簡單說是由 tf * idf * boost * lengthNorm計算得出的。
tf:是查詢的詞在文檔中出現的次數的平方根
idf:表示反轉文檔頻率,觀察了一下所有的文檔都一樣,所以那就沒什么用處,不會起什么決定作用。
boost:激勵因子,可以通過setBoost方法設置,需要說明的通過field和doc都可以設置,所設置的值會同時起作用
lengthNorm:是由搜索的field的長度決定了,越長文檔的分值越低。
所以我們編程能夠控制score的就是設置boost值。
還有個問題,為什么一次查詢后最大的分值總是1.0呢?
因為Lucene會把計算后,最大分值超過1.0的分值作為分母,其他的文檔的分值都除以這個最大值,計算出最終的得分。
下面用代碼和運行結果來進行說明:
Java代碼 ?
運行結果:
引用 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的打分機制,同時也知道如何來改變文檔的得分。
總結
以上是生活随笔為你收集整理的Lucene的评分(score)机制的简单解释的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lucene学习总结之六:Lucene打
- 下一篇: Exercise: Linear Reg