首先說一下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的乙個特色就是它的相關度評分。這裡介紹一下它的自定義 相關度評分。在實際的業務中,可能不需要這麼複雜的相關度,是需要簡單粗暴的 按照我指定的規則計算相關度,並按照...