內容集合了多個 博文和ppt spa
lucene的評分公式以下: orm
一 概念: 排序
一、Token:倒排表最小單位,即分詞中 詞。 文檔
二、Term:query的最小單位 get
三、Tf:一個term在一個文檔中出現的次數 it
四、Idf:一個term在多少個文檔中出現過 搜索
二 向量空間模型的計算 lucene
一、餘弦定理 im
二、Vq爲 query向量,Vd爲document向量,通過分詞以後成爲 多個term,query與要搜索的document造成一個N維數量空間。 查詢
查詢向量爲Vq = <w(t1, q), w(t2, q), ……, w(tn, q)>
文檔向量爲Vd = <w(t1, d), w(t2, d), ……, w(tn, d)>
Term的權重: W=tf*idf,即表示 該Term在該 文檔(query或者document)中的權重
由於,在query中,
則:
Vq*Vd = w(t1, q)*w(t1, d) + w(t2, q)*w(t2, d) + …… + w(tn ,q)*w(tn, d)
=tf(t1, q)*idf(t1, q)*tf(t1, d)*idf(t1, d) + …… + tf(tn,q)*idf(tn, q)*tf(tn, d)*idf(tn, d)
三、
由於,在 query中,不太可能分詞後出現多個相同的term,假設這種狀況成立,即tf(t,q)=1,
又由於 query與 要搜索的多個document相比,詞量實在太少。因此, idf(t,q)約等於idf(t,d)
Vq*Vd = tf(t1, d)*idf(t1, d)^2+......+ tf(tn, d)*idf(tn, d)^2
四、接着,咱們就開始 計算向量模了,即 V
Lucene採用的Similarity,認爲在計算文檔(document)的向量長度的時候,每一個Term的權重(W=tf*idf)就再也不考慮在內了,而是所有爲一.若是按權重去計算的話,由於
查詢語句中tf都爲1,idf查詢語句這篇小文檔 即idf(t,q) = idf(t,d),獲得以下公式
代入餘弦公式,即獲得
加上lucene本身的各類boost和coord
3、繼續細分理解
一、協調因子 coord(q,d)
overlap(命中查詢個數)
maxOverlap(總查詢個數)
搜索語句爲: 圖書名稱:」紅樓夢」 || 做者:」紅樓夢」
doc1: 圖書名稱:紅樓夢 做者:曹雪芹 coord(q,d) = 1/2,查詢了兩個域,命中了一個
doc2: 圖書名稱: 紅樓夢 做者:紅樓夢編委 coord(q,d) 2/2 (高),查詢了兩個域,命中了兩個
3.文檔詞頻因子 tf(t in d)
tf(t in d) = Math.sqrt(freq)
例如 搜索 圖書名稱:紅樓夢
文檔1:圖書名稱:紅樓夢 tf=1
文檔2:圖書名稱:紅樓夢曹雪芹簽名版紅樓夢 tf=1.414 (高,由於它在該一個文檔中,出現一次)
四、文檔出現頻率因子 idf(t)
idf(t) = 1.0 + log(numDocs/(docFreq+1))
numDocs(總文檔數)
docFreq(有幾個文檔中出現了查詢的詞)
例如搜索語句爲:圖書名稱:「紅樓夢」 || 做者:「曹雪芹」 總文檔數爲1000
若是圖書名稱中包含圖書名稱「紅樓夢」的文檔數爲100 idf= 2.0
做者名稱中包含做者「曹雪芹」的文檔數爲10 idf= 3.0 (高)
五、查詢權重t.getBoost
在solr中的寫法爲:itemName:紅樓夢^10.0 itemDesc:紅樓夢
六、標準化因子 norm(t,d)
norm(t,d) = doc.getBoost()· lengthNorm· ∏ f.getBoost() (注意:4.0之後沒有了 doc.getBoost())
lengthNorm = 1.0 / Math.sqrt(numTerms)
doc.getBoost() (在每一個文檔上設置的權重)
f.getBoost() (在每一個字段上設置的權重
lengthNorm = 1.0 / Math.sqrt(numTerms)
表示字段長度對打分的影響
例如:文檔1:圖書名稱:紅樓夢 lengthNorm = 1/1.7 (高)
文檔2:圖書名稱: 紅樓夢新刊第28期 = 1/3
4、將上面1-6部分細化的部分代入上面公式獲得 score(q,d) = (overlap / maxOverlap )·(1/(q.getBoost()^2·∑( idf(t)·t.getBoost() )^2) ) · ∑( tf(t in d)·idf(t)^2·t.getBoost()· doc.getBoost()· lengthNorm· ∏ f.getBoost() )