文章轉自:http://blog.csdn.net/duck_genuine/article/details/6257540
首先說一下lucene對文檔的評分規則:
| score(q,d) = coord(q,d) ·queryNorm(q) · | ∑ | (tf(t in d) ·idf(t)2·t.getBoost() ·norm(t,d)) |
具體可以查看相關文章:http://blog.chenlb.com/2009/08/lucene-scoring-architecture.html
這里先考慮三個因素coord(q,d)與tf(t in d),當查詢串中,命中的詞越多,coord計算的值則越大,某個詞在文檔中出現的次數越多則tf的值越大。還有就是norm(t,d),這個主要是文檔boost與字段boost的影響。值越大,對整體評分的影響越重。
首先說tf對搜索結果的影響:
這里是在于本站使用的搜索評分開始是默認的評分器的情況下,但發現有些不足之處。因為站內搜索主要是視頻的標題與標簽。對于一個視頻文檔來說,標題或者與標簽重復的詞本身就是無意義的,比如標題為"[java]view plaincopy 別小看這段代碼 ,因為使用這種評分,對于一個文檔來說,一個term在文檔出現的頻率并不影響,即是不用擔心作弊的情況,因為在這方面上他們的分數都是一樣的。之前還考慮了對標題與標簽的重復字符串的處理,采用后綴樹結構來處理公共子串,后來發現這種方法來得更簡潔。 因為使用的是solr來作搜索服務來架構,所以首先修改solr默認的Similarity類。在solr 的配置文件schemal.xml,最后中修改或增加: <similarity class="com.wole.solr.search.MySimilarity"/> 設置為自定義的評分器,重啟solr服務后,自定義的評分器就生效了。搜索" 美女"后,不再出現“美女美女美女美女”文檔靠前排的效果了。 接著說一下coord的影響: 搜索“htc Incredible S” 三個詞,由于沒有這完全命中,則使用了寬松規則,即命中一個詞也返回進行排序,之前的評分,前幾條的結果為: 可以看到,命中的詞S 的文檔給排到較前,本應該讓命中越來的詞的文檔分數更高,但因為這三個文檔在其它方面影響到評分,使得它的最后分數高于命中多個詞的文檔,而排到最前,所以這樣的搜索體驗不夠好,好的體驗應該是讓命中的詞越多排得越高,所以我首先降低計算norm(t,d)的值。測試調了其權重值,讓coord占更大的比例值,效果馬上出來更好的,其前三條記錄為: 這里命中兩個詞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) · | &PRod; | f.getBoost() |
| fieldfindnamed ast |
搜索組件為dismax,其中文檔bf的計算是由三個字段
public_time (視頻發布時間)^15,times(視頻播放數)^15,hd(視頻高清)^4
字段的bf值為
qf=Subject^1+tag^0.3
如果想讓coord的值靠前,計算文檔 boost 與字段boost 的值應該降低一個級別。
改為:
public_time (視頻發布時間)^1.5,times(視頻播放數)^1.5,hd(視頻高清)^0.4
這樣 norm計算的值就遠遠小于 coord ,使命中越多詞分數越高的效果
| norm(t,d) = doc.getBoost() ·lengthNorm(field) · | ∏ | f.getBoost() |
| fieldfindnamed ast |
新聞熱點
疑難解答