亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

ElasticSearch 的分數 (_score) 是怎么計算得出 (2.X & 5.X)

2024-07-21 02:52:02
字體:
來源:轉載
供稿:網友

原文地址

上次寫了關于 Elasticsearch 如何分詞索引, 接著繼續寫 Elasticsearch 怎么計算搜索結果的得分(_score).

Elasticsearch 默認是按照文檔與查詢的相關度(匹配度)的得分倒序返回結果的. 得分 (_score) 就越大, 表示相關性越高.

所以, 相關度是啥? 分數又是怎么計算出來的? (全文檢索和結構化的 SQL 查詢不太一樣, 雖然看起來結果比較'飄忽', 但也是可以追根問底的)


在 Elasticsearch 中, 標準的算法是 Term Frequency/Inverse Document Frequency, 簡寫為 TF/IDF, (剛剛發布的 5.0 版本, 改為了據說更先進的 BM25 算法)

Term Frequency

某單個關鍵詞(term) 在某文檔的某字段中出現的頻率次數, 顯然, 出現頻率越高意味著該文檔與搜索的相關度也越高

具體計算公式是 tf(q in d) = sqrt(termFreq)

另外, 索引的時候可以做一些設置, "index_options": "docs" 的情況下, 只考慮 term 是否出現(命中), 不考慮出現的次數.

PUT /my_index{  "mappings": {    "doc": {      "PRoperties": {        "text": {          "type":          "string",          "index_options": "docs"        }      }    }  }}

Inverse document frequency

某個關鍵詞(term) 在索引(單個分片)之中出現的頻次. 出現頻次越高, 這個詞的相關度越低. 相對的, 當某個關鍵詞(term)在一大票的文檔下面都有出現, 那么這個詞在計算得分時候所占的比重就要比那些只在少部分文檔出現的詞所占的得分比重要低. 說的那么長一句話, 用人話來描述就是 "物以稀為貴", 比如, '的', '得', 'the' 這些一般在一些文檔中出現的頻次都是非常高的, 因此, 這些詞占的得分比重遠比特殊一些的詞(如'Solr', 'Docker', '哈蘇')占比要低,

具體計算公式是 idf = 1 + ln(maxDocs/(docFreq + 1))

Field-length Norm

字段長度, 這個字段長度越短, 那么字段里的每個詞的相關度也就越大. 某個關鍵詞(term) 在一個短的句子出現, 其得分比重比在一個長句子中出現要來的高.

具體計算公式是 norm = 1/sqrt(numFieldTerms)

默認每個 analyzed 的 string 都有一個 norm 值, 用來存儲該字段的長度,

用 "norms": { "enabled": false } 關閉以后, 評分時, 不管文檔的該字段長短如何, 得分都一樣.

PUT /my_index{  "mappings": {    "doc": {      "properties": {        "text": {          "type": "string",          "norms": { "enabled": false }        }      }    }  }}
最后的得分是三者的乘積 tf * idf * norm

以上描述的是最原始的針對單個關鍵字(term)的搜索. 如果是有多個搜索關鍵詞(terms)的時候, 還要用到的 Vector Space Model

如果查詢復雜些, 或者用到一些修改了分數的查詢, 或者索引時候修改了字段的權重, 比如 function_score 之類的,計算方式也就又更復雜一些.

Explain

看上去 TF/IDF 的算法已經一臉懵逼嚇跑人了, 不過其實, 用 Explain 跑一跑也沒啥, 雖然各種開方, 自然對數的, Google一個科學計算器就是了.

舉個例子

/*先刪掉索引, 如果有的話*/curl -XDELETE 'http://localhost:9200/blog'curl -XPUT 'http://localhost:9200/blog/' -d '{  "mappings": {     "post": {        "properties": {           "title": {              "type": "string",              "analyzer": "standard",              "term_vector": "yes"           }        }     }  }}'

存入一些文檔 (Water 隨手加進去測試的.)

curl -s -XPOST localhost:9200/_bulk -d '{ "create": { "_index": "blog", "_type": "post", "_id": "1" }}{ "title": "What is the best water temperature, Mr Water" }{ "create": { "_index": "blog", "_type": "post", "_id": "2" }}{ "title": "Water no symptoms" }{ "create": { "_index": "blog", "_type": "post", "_id": "3" }}{ "title": "Did Vitamin B6 alone work for you? Water?" }{ "create": { "_index": "blog", "_type": "post", "_id": "4" }}{ "title": "The ball drifted on the water." }{ "create": { "_index": "blog", "_type": "post", "_id": "5" }}{ "title": "No water no food no air" }'

bulk insert 以后先用 Kopf 插件輸出看一下, 5 個文檔并不是平均分配在 5 個分片的, 其中, 編號為 2 的這個分片里邊有兩個文檔, 其中編號為 0 的那個分片是沒有分配文檔在里面的.

接下來, 搜索的同時 explain

原本輸出的 json 即使加了 pretty 也很難看, 換成 yaml 會好不少

curl -XGET "http://127.0.0.1:9200/blog/post/_search?explain&format=yaml" -d '{  "query": {    "term": {      "title": "water"    }  }}'

輸出如圖(json)

可以看到五個文檔都命中了這個查詢, 注意看每個文檔的 _shard

整個輸出 yml 太長了, 丟到最后面, 只截取了其中一部分, 如圖,

返回排名第一的分數是 _score: 0.2972674, _shard(2),

"weight(title:water in 0) [PerFieldSimilarity], result of:" 這里的 0 不是 _id, 只是 Lucene 的一個內部文檔 ID, 可以忽略.

排名第一和第二的兩個文檔剛好是在同一個分片的, 所以跟另外三個的返回結果有些許不一樣, 主要就是多了一個 queryWeight, 里面的 queryNorm 只要在同一分片下, 都是一樣的, 總而言之, 這個可以忽略(至少目前這個例子可以忽略)

只關注 fieldWeight, 排名第一和第二的的 tf 都是 1,

在 idf(docFreq=2, maxDocs=2) 中, docFreq 和 maxDocs 都是針對單個分片而言, 2號分片一共有 2個文檔(maxDocs), 然后命中的文檔也是兩個(docFreq).

所以 idf 的得分, 根據公式, 1 + ln(maxDocs/(docFreq + 1)) 是 0.59453489189

最后 fieldNorm, 這個 field 有三個詞, 所以是 1/sqrt(3), 但是按官方給的這個公式怎么算都不對, 不管哪個文檔. 后來查了一下, 說是 Lucene 存這個 lengthNorm 數據時候都是用的 1 byte來存, 所以不管怎么著都會丟掉一些精度. 呵呵噠了 = . =

最后的最后, 總得分 = 1 * 0.5945349 * 0.5 = 0.2972674.

同理其他的幾個文檔也可以算出這個得分, 只是都要被 fieldNorm 的精度問題蛋疼一把.

完整結果太長了, 貼個 gisthttps://gist.github.com/xguox/077e18afe24f52f6e2b45efb0b4e304f


Elasticsearch 5 (Lucene 6) 的 BM25 算法

Elasticsearch 前不久發布了 5.0 版本, 基于 Lucene 6, 默認使用了 BM25 評分算法.

BM25 的 BM 是縮寫自 Best Match, 25 貌似是經過 25 次迭代調整之后得出的算法. 它也是基于 TF/IDF 進化來的. Wikipedia 那個公式看起來很嚇唬人, 尤其是那個求和符號, 不過分解開來也是比較好理解的.

總體而言, 主要還是分三部分, TF - IDF - Document Length

IDF 還是和之前的一樣. 公式 IDF(q) = 1 + ln(maxDocs/(docFreq + 1))

f(q, D) 是 tf(term frequency)

|d| 是文檔的長度, avgdl 是平均文檔長度.

先不看 IDF 和 Document Length 的部分, 變成 tf * (k + 1) / (tf + k),

相比傳統的 TF/IDF (tf(q in d) = sqrt(termFreq)) 而言, BM25 抑制了 tf 對整體評分的影響程度, 雖然同樣都是增函數, 但是, BM25 中, tf 越大, 帶來的影響無限趨近于 (k + 1), 這里 k 值通常取 [1.2, 2], 而傳統的 TF/IDF 則會沒有臨界點的無限增長.

而文檔長度的影響, 同樣的, 可以看到, 命中搜索詞的情況下, 文檔越短, 相關性越高, 具體影響程度又可以由公式中的 b 來調整, 當設值為 0 的時候, 就跟之前 'TF/IDF' 那篇提到的 "norms": { "enabled": false } 一樣, 忽略文檔長度的影響.

綜合起來,

k = 1.2

b = 0.75

idf * (tf * (k + 1)) / (tf + k * (1 - b + b * (|d|/avgdl)))

最后再對所有的 terms 求和. 就是 Elasticsearch 5 中一般查詢的得分了.


Related:

http://opensourceconnections.com/blog/2015/10/16/bm25-the-next-generation-of-lucene-relevation/

What Is Relevance?

From:

Elasticsearch 的分數(_score)是怎么計算得出Elasticsearch 5.X(Lucene 6) 的 BM25 相關度算法


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
最近2019免费中文字幕视频三| 亚洲高清免费观看高清完整版| 国产欧美精品va在线观看| 亚洲跨种族黑人xxx| 在线观看国产精品91| 国产免费一区二区三区香蕉精| 日本在线观看天堂男亚洲| 欧美日韩中国免费专区在线看| 久久亚洲精品一区| 亚洲精品自拍视频| 成人精品视频99在线观看免费| 黄色一区二区三区| 国产精品小说在线| 欧美黄色片在线观看| 亚洲欧美激情精品一区二区| 久久久精品一区| 欧美黑人极品猛少妇色xxxxx| 国产精品日韩欧美大师| 6080yy精品一区二区三区| 精品久久久久人成| 亚洲国产精品999| 91理论片午午论夜理片久久| 欧美日韩久久久久| 精品av在线播放| 日韩在线播放视频| 俺去亚洲欧洲欧美日韩| 日韩精品在线播放| 久久精品99无色码中文字幕| 亚洲男人av在线| 亚洲男人第一av网站| 97视频在线观看免费高清完整版在线观看| 久久天天躁狠狠躁夜夜躁| 国产在线98福利播放视频| 国产做受高潮69| 欧美剧在线观看| 97婷婷大伊香蕉精品视频| 久久久久久国产精品三级玉女聊斋| 久久久久久久影院| 亚洲视频综合网| 91精品视频在线免费观看| 国产精品丝袜视频| 亚洲综合中文字幕在线观看| 国产亚洲xxx| 国产精品久久久久久久久粉嫩av| 97在线视频国产| 亚洲免费伊人电影在线观看av| 亚洲色图第一页| 91九色国产视频| 欧美xxxx14xxxxx性爽| 日韩成人激情在线| 久久久久久久久中文字幕| 日韩最新在线视频| 亚洲激情自拍图| 日韩成人av在线播放| 欧美色道久久88综合亚洲精品| 久久久久久久久91| 国产精品青青在线观看爽香蕉| 国产精品人成电影| 亚洲女在线观看| 欧美肥老太性生活视频| 久久综合免费视频| 国产精品91视频| 中文字幕免费国产精品| 欧美在线观看网站| 欧美激情第1页| 久久精品在线播放| 欧美黑人性生活视频| 久久免费福利视频| 国产精品毛片a∨一区二区三区|国| 久久久久国产视频| 日本精品免费一区二区三区| 国产一区二区三区高清在线观看| 久久五月天综合| 亚洲精品电影久久久| 在线观看精品国产视频| 久久99亚洲热视| 亚洲人成在线免费观看| 青青草99啪国产免费| 成人a在线视频| 亚洲精品中文字幕av| 欧美激情亚洲综合一区| 欧美高清性猛交| 自拍偷拍亚洲一区| 最新中文字幕亚洲| 国产成人精品一区| 久久久精品一区二区三区| 在线观看精品国产视频| 久久久视频精品| 欧美成aaa人片在线观看蜜臀| 青草青草久热精品视频在线网站| 91九色蝌蚪国产| 国产精自产拍久久久久久蜜| 日韩欧美视频一区二区三区| 97在线看免费观看视频在线观看| 久久偷看各类女兵18女厕嘘嘘| 欧美成人免费网| 国产手机视频精品| 亚洲永久在线观看| 日本欧美一级片| 亚洲电影中文字幕| 国产精品日韩在线观看| 久久国产精品久久国产精品| 午夜精品一区二区三区在线播放| 97人人爽人人喊人人模波多| 成人精品aaaa网站| 亚洲欧美国产精品久久久久久久| 高跟丝袜一区二区三区| 久久亚洲综合国产精品99麻豆精品福利| 麻豆国产精品va在线观看不卡| 国产免费成人av| 久久精品亚洲94久久精品| 97超碰蝌蚪网人人做人人爽| 91国产美女在线观看| 亚洲一区二区三区sesese| 国产午夜精品久久久| 亚洲毛茸茸少妇高潮呻吟| 福利精品视频在线| 欧美日韩国产综合新一区| 欧美人成在线视频| 最近2019中文字幕一页二页| 日韩在线观看网站| 在线精品视频视频中文字幕| 亚洲欧美中文在线视频| 欧美激情视频播放| 精品在线欧美视频| 欧洲成人在线观看| 国产亚洲激情在线| 欧美亚洲成人网| 97人洗澡人人免费公开视频碰碰碰| 亚洲免费高清视频| 欧美成人小视频| 韩国三级日本三级少妇99| 国产精品亚洲片夜色在线| 亚洲精品综合久久中文字幕| 成人免费在线视频网站| 影音先锋欧美在线资源| 中文字幕精品久久| 92国产精品久久久久首页| 欧美日韩国产123| 亚洲最大成人免费视频| 91精品国产91久久久久久最新| 国产视频在线观看一区二区| 欧美日韩国产一区二区三区| 国产精品成人品| 亚洲www永久成人夜色| 亚洲综合小说区| 亚洲第一区在线| 日韩精品电影网| 国产在线观看精品一区二区三区| 日韩欧美综合在线视频| 亚洲欧美变态国产另类| 日本人成精品视频在线| 2019中文字幕在线| 日韩av综合网站| 亚洲xxx大片| 日本精品va在线观看| 国语自产偷拍精品视频偷| 欧美大人香蕉在线| 免费99精品国产自在在线| 97碰在线观看| 亚洲人成人99网站| 亚洲最大成人在线| 免费91麻豆精品国产自产在线观看| 欧美日韩高清在线观看|