Lucene打分規則

2021-09-01 19:49:20 字數 3767 閱讀 7971

搜尋排序結果的控制

lucnen作為搜尋引擎中,應用最為廣泛和成功的開源框架,它對搜尋結果的排序,有一套十分完整的機制來控制;但我們控制搜尋結果排序的目的永遠只有乙個,那就是資訊過濾,讓使用者快速,準確的找到其想要的結果,豐富使用者體驗。

以前看過乙個牛人的部落格,總結了4個地方,可對lucene檢索結果的排序進行控制,現在已經記不住。我自己簡單整理了下面幾個,若有疏漏,歡迎補充:

1.    通過lucene自有的查詢表示式:lucene提供相當豐富的表示式解析,要細講就多了去了;這裡只強調下,我在專案中用的比較多的是通過對指定域的加權,來影響檢索結果(例如:field1:(***)^10 or field2:(***)^5;其中***是使用者提交的檢索)

2.    權重的控制:這是在建索引的時候就寫入索引的,查詢時只是讀取出來,用乘的方式來對一些檢索結果加分。據我自己看lucene**,similarity中也能在建索引時,對權重的寫入進行控制;後面會細講。

3.    controller 模組:lucene的排序流程控制模組,裡面提供的一些介面能讓你對打分後的搜尋結果進行一些篩選和調整。

4.    similarity 模組:lucene的搜尋結果打分控制模組,也是這裡要詳細分析的模組。他能讓你對乙個檢索結果的打分進行優化,或面目全非,哈哈。

lucene的打分公式

要理解similarity模組對打分結果控制,首先要了解lucene自己評分原理:相似度評分公式;此公式是目前公認的使用者體驗較好的乙個,原理是根據餘弦定理。下面是在摘自《lucene實戰》(第二版)的公式表示式:

其中q 為查詢語句,t 是q 分詞後的每一項, d為去匹配的文件。

接下來對公式中的每乙個函式,進行詳解,他們都能在 similarity 模組中進行控制。

lucene打分流程

首先,我簡單說明下,lucene對一次查詢是如何封裝;這涉及到對打分公式是如何呼叫的,如此一來更能全面的了解打分流程:

第一步的處理肯定是分詞,查詢語句 => term_1, term_2 …  term_n(n∈[1,∞]),緊接著是將這些term 封裝成query物件,總的query物件是booleanquery,它裡面包含和分詞數相同termquery,和分詞後的詞項一一對應;這是對乙個域的查詢,若你多個域聯合查詢,那就會有多個這樣的booleanquery,被乙個更大的booleanquery包裹著。

而打分公式,貫穿所有query,其中一部分在termquery中計算,一部分在booleanquery計算,最後按此計算出的得分進行排序,就得到了我們的搜尋結果。

下面是我通過explain(query query, int doc) 匯出的打分解釋:

對照lucene的打分解釋,我們一層一層往裡撥(上述每個縮排為一層),每乙個函式都能在similarity中進行控制。

1.      首先第一層:3.3936599 = (match) product of:,是此條記錄的總得分。

2.      第二層:8.48414992 = (match) sum of: 它對應乙個booleanquery,它把它包含的termquery的得分累加起來,由於termquery總共有5個,此條結果中只匹配了2個,所以最後一行將得分乘以了0.4得到最後的打分,coord()在similarity中的預設實現如下:

/** implemented asoverlap / maxoverlap. */

@override

public float coord(int overlap, int maxoverlap)

你也可以繼承similarity對此方法重寫。

3.      第三層:(match) weight(field:*** in m), product of: 有2個,它們分別是「三國」、「無雙」對應的詞項查詢termquery的得分。

再往裡,就是termquery的打分規則了,裡面的函式已經和公式有所對應了,下面就詳細介紹termquery中每一項計算的作用。

similarity 函式詳解

termquery中有4個函式,都是similarity裡可以控制的函式,他們分別是querynorm、tf、idf、fieldnorm

querynorm:

對於某一次搜尋中結果的排序沒有影響,在一次搜尋中querynorm的值是固定的。這裡就不介紹了

tf(t in q)

此函式表示詞項t 在該文件中的該字段裡 出現的頻率;對應到上圖的例子中:既是分詞後的詞項(三國或 無雙)在此條記錄中name欄位裡出現的頻率。當然出現的次數越多,它返回的值越大,也正好反映了此文件的重要性。下面是defaultsimilarity 中的預設實現的預設實現。    

/** implemented assqrt(freq). */

@override

public float tf(float freq)

預設實現是開平方。同樣你可以重寫此函式。

idf(t)

此函式出現了兩次,也剛好對應公式中的 idf(t)^2;

這個函式被稱作倒頻率,表示詞項t 在所有文件中出現的頻率。若它在所有文件中出現的次數越多,表明這個詞項t 越不重要;以下是defaultsimilarity的預設實現。

/** implemented aslog(numdocs/(docfreq+1)) + 1. */

@override

public float idf(int docfreq, int numdocs)

此函式實際對結果排序的影響,在於當一次搜尋包含多個詞項時,文件a和b分別包含了其中乙個詞項;比如a包含「三國」,b包含「無雙」;那麼「三國」和「無雙」的倒頻率就會影響,讓a、b的得分產生差異了。若詞項只有乙個,那本次搜尋idf(t) 實際對結果排序不會產生影響。

fieldnorm (t)

3.0以後:computenorm(string field, fieldinvertstate state)

/** decodes a normalization factor stored in an index. *

*warning: if you override this method, you should change the default

*    similarity to your implementation with .

*    otherwise, your method may not always be called, especially if you omit norms

*    for some fields.

* @see #encodenormvalue(float) */

public float decodenormvalue(byte b)

至此lucene打分流程和similarity模組的函式已經將的差不多了。可以通過這些函式讓你的搜尋展示出完全不一樣的效果,這也需要根據不同的業務慢慢除錯,才能得出最優化的搜尋結果 。

Solr搜尋的排序打分規則

使用solr搭建搜尋引擎很容易,但是如何制定合理的打分規則 boost 做排序卻是乙個很頭痛的事情。solr本身的排序打分規則是繼承自 lucene的文字相關度的打分即boost,這一套演算法對於通用的提供全文檢索的服務來講,已經夠用了,但是對於一些專門領域的搜尋來講,文字相關度的 打分是不合適的。...

lucene打分機制

lucene採用的是基於vsm 向量空間模型 的相似度演算法,查詢向量 query vector 與搜尋出來的文件向量 document vector 形成n個夾角,計算q 和d 之間的夾角,最小的 就是相 似 度最高的。看下lucene的打分公式 tf 乙個term在乙個文件中出現的次數 idf ...

橋牌記分規則

橋牌記分一覽表 無局方最 終定 約 結果c或d h或s無將 加倍再加倍 加倍再加倍 加倍再加倍1 1 2 3 4 5 6 70 140 230 90 240 430 110 340 630 130 440 830 150 540 1030 170 640 1230 190 740 1430 80 1...