在 Elasticsearch 5.x 之前的版本所采用的是 tf-idf 來(lái)計(jì)算相關(guān)度, 而在 5.x 版本開(kāi)始所采用的是 bm25 來(lái)計(jì)算相關(guān)度。
bm25 是在 tf-idf 的基礎(chǔ)上增加了兩個(gè)參數(shù)來(lái)控制詞頻不會(huì)因?yàn)閿?shù)量的激增而飄高.
相關(guān)度是由TF-IDF和一組參數(shù)的組合運(yùn)算得出的結(jié)果,用于評(píng)估一個(gè)詞在文檔中的近似匹配程度。
TF(Term frequency): 詞頻, 用于評(píng)估詞在文檔中出現(xiàn)的次數(shù), 次數(shù)越高分值越高.
(關(guān)閉詞頻: index_options: docs)
IDF(Inverse document frequency): 倒排文檔頻率, 用于評(píng)估包含詞的文檔數(shù)量,數(shù)量越多詞的分值越低.
FLN(Field-length norm): 文本長(zhǎng)度歸一化(規(guī)范化), 用于評(píng)估不同字段的長(zhǎng)度, 字段文本越短分值越高.
(關(guān)閉字段長(zhǎng)度規(guī)范化: norms: {"enabled": false})聯(lián)合參數(shù):
coord(The Coordination Factor): 用于配合bool復(fù)合條件查詢, 具體介紹不知道.
boost: 該參數(shù)用于調(diào)整字段權(quán)重.
?
Python版BM25實(shí)現(xiàn)
def bm25(doc_count, doc_freq):
# idf: 逆向文檔頻率: 包含詞的文檔數(shù)量越多, 詞的權(quán)重就越低.
idf = log(1 + (doc_count - doc_freq + 0.5) / (doc_freq + 0.5), e)
idf = round(idf, 7)
# tf: 詞頻: 詞在文檔中出現(xiàn)的次數(shù)越高, 分值越高.
freq = 2.0
# 新特性: 該參數(shù)控制詞頻飽和(非線性上升速度)的規(guī)范化
k1 = 1.2
# 新特性: 該參數(shù)的用意是抵消字段越短,權(quán)重越高;
# 他將所有字段的長(zhǎng)度做一個(gè)平均長(zhǎng)度然后在做詞頻相關(guān)度計(jì)算。
b = 0.75
avg_field_length = 3.0
field_length = 4.0
tf = (freq * (k1 + 1)) / \
(freq + k1 * (1 - b + b * field_length / avg_field_length))
tf = round(tf, 7)
# 相關(guān)度: 詞頻分值 * 權(quán)重分值
score = round(tf * idf, 7)
return tf, idf, score
?