自定義評分器Similarity,提高搜尋體驗

2021-05-28 17:47:19 字數 4337 閱讀 9721

首先說一下lucene對文件的評分規則:

score(q,d)   =   coord(q,d) ·  querynorm(q) ·∑(

tf(t in d) ·  idf(t)2 ·  t.getboost() ·  norm(t,d) )

這裡先考慮三個因素coord(q,d)與tf(t in d),當查詢串中,命中的詞越多,coord計算的值則越大,某個詞在文件中出現的次數越多則tf的值越大。還有就是norm(t,d),這個主要是文件boost與字段boost的影響。值越大,對整體評分的影響越重。

首先說tf對搜尋結果的影響:

view plain

copy to clipboard

print?

/*** @author yuzhy

* 實現自已的評分器

* 文件中重複多少個詞不影響分數**/

public

class mysolrsimilarity extends defaultsimilarity   

@override

public

float tf(int freq)   

}  別小看這段** ,因為使用這種評分,對於乙個文件來說,乙個term在文件出現的頻率並不影響,即是不用擔心作弊的情況,因為在這方面上他們的分數都是一樣的。之前還考慮了對標題與標籤的重複字串的處理,採用字尾樹結構來處理公共子串,後來發現這種方法來得更簡潔。

因為使用的是solr來作搜尋服務來架構,所以首先修改solr預設的similarity類。在solr 的配置檔案schemal.xml,最後中修改或增加:

設定為自定義的評分器,重啟solr服務後,自定義的評分器就生效了。搜尋" 美女"後,不再出現「美女美女美女美女」文件靠前排的效果了。

接著說一下coord的影響:

搜尋「htc incredible s」 三個詞,由於沒有這完全命中,則使用了寬鬆規則,即命中乙個詞也返回進行排序,之前的評分,前幾條的結果為:

view plain

copy to clipboard

print?

<

doc>

<

strname="subject"

>s.h.e愛而為一的魔力 幕後全紀錄

str>

<

strname="tag"

>she selina hebe ella 愛而為一

str>

<

intname="public_time"

>1103150000

int>

<

intname="times"

>370

int>

<

intname="hd"

>1

int>

doc>

−  <

doc>

<

strname="subject"

>1000種死法-s04-01.1024x576.x264

str>

<

strname="tag"

>1000種死法    

str>

<

intname="public_time"

>1103140000

int>

<

intname="times"

>692

int>

<

intname="hd"

>1

int>

doc>

−  <

doc>

<

strname="subject"

>p-s-1

str>

<

strname="tag"

>

str>

<

intname="public_time"

>1103150000

int>

<

intname="times"

>58

int>

<

intname="hd"

>1

int>

doc>

可以看到,命中的詞s 的文件給排到較前,本應該讓命中越來的詞的文件分數更高,但因為這三個文件在其它方面影響到評分,使得它的最後分數高於命中多個詞的文件,而排到最前,所以這樣的搜尋體驗不夠好,好的體驗應該是讓命中的詞越多排得越高,所以我首先降低計算norm(t,d)的值。測試調了其權重值,讓coord佔更大的比例值,效果馬上出來更好的,其前三條記錄為:

view plain

copy to clipboard

print?

<

doc>

<

strname="subject"

str>

<

strname="tag"

str>

<

intname="public_time"

>1009250000

int>

<

intname="times"

>29758

int>

<

intname="hd"

>0

int>

doc>

−  <

doc>

<

strname="subject"

>不可思議 htc incredible 比拼 蘋果 iphone 3gs

str>

<

strname="tag"

str>

<

intname="public_time"

>1009250000

int>

<

intname="times"

>20231

int>

<

intname="hd"

>0

int>

doc>

−  <

doc>

<

strname="subject"

>htc incredible拆解全過程

str>

<

strname="tag"

>手機 htc incredible droid系列 

str>

<

intname="public_time"

>1005030000

int>

<

intname="times"

>3649

int>

<

intname="hd"

>0

int>

doc>

1009250000

297580−

不可思議 htc incredible 比拼 蘋果 iphone 3gs

1009250000

202310−

htc incredible拆解全過程

手機 htc incredible droid系列

1005030000

3649

0這裡命中兩個詞htc incredible的文件給排到最前面來,顯然這才更符合使用者需要的。即使沒有完全命中,它的相關性會更逼近。

最後講一下norm(t,d):

沒有norms 意味著

索引階段禁用了文件boost 和域的boost 及長度標準化。好處在於節省記憶體,不用在搜尋階

段為索引中的每篇文件的每個域都占用乙個位元組來儲存norms 資訊了。但是對norms 資訊

的禁用是必須全部域都禁用的,一旦有乙個域不禁用,則其他禁用的域也會存放預設的

norms 值。因為為了加快norms 的搜尋速度,lucene 是根據文件號乘以每篇文件的norms

資訊所占用的大小來計算偏移量的,中間少一篇文件,偏移量將無法計算。也即norms 信

息要麼都儲存,要麼都不儲存。

norm(t,d)壓縮幾個索引期間的加權和長度因子:

以上所有因子相乘得出 norm 值,如果文件中有相同的字段,它們的加權也會相乘:

norm(t,d)   =   doc.getboost() ·  lengthnorm(field) ·

∏f.getboost()

fieldfin d named ast

搜尋元件為dismax,其中文件bf的計算是由三個字段

欄位的bf值為

qf=subject^1+tag^0.3

如果想讓coord的值靠前,計算文件 boost 與字段boost  的值應該降低乙個級別。

改為:這樣 norm計算的值就遠遠小於 coord ,使命中越多詞分數越高的效果

solr自定義評分器

solr服務搭建完成 索引已建立,可以進行搜尋 現象 搜尋 美女 後,美女美女美女美女 文件會出現第一位。但實際系統中可能並不需要 這種結果 這個時候的解決辦法 根據自己業務需要進行重寫評分器 1.自定義評分器 package cn.xxt.solr.util import org.apache.l...

自定義評分器Similarity,提高搜尋體驗

首先說一下lucene對文件的評分規則 score q,d coord q,d querynorm q tf t in d idf t 2 t.getboost norm t,d 這裡先考慮三個因素coord q,d 與tf t in d 當查詢串中,命中的詞越多,coord計算的值則越大,某個詞在...

solr 相關度評分,自定義評分

ps 臨時寫的,大體的實現和簡單版,以後會不斷完善 部落格和 solr是基於lucene的全文檢索 搜尋引擎,和一般查資料庫相比,solr的乙個特色就是它的相關度評分。這裡介紹一下它的自定義 相關度評分。在實際的業務中,可能不需要這麼複雜的相關度,是需要簡單粗暴的 按照我指定的規則計算相關度,並按照...