Neil Zhu,簡(jiǎn)書ID Not_GOD奴曙,University AI 創(chuàng)始人 & Chief Scientist由驹,致力于推進(jìn)世界人工智能化進(jìn)程。制定并實(shí)施 UAI 中長(zhǎng)期增長(zhǎng)戰(zhàn)略和目標(biāo)炫惩,帶領(lǐng)團(tuán)隊(duì)快速成長(zhǎng)為人工智能領(lǐng)域最專業(yè)的力量僻弹。
作為行業(yè)領(lǐng)導(dǎo)者,他和UAI一起在2014年創(chuàng)建了TASA(中國(guó)最早的人工智能社團(tuán)), DL Center(深度學(xué)習(xí)知識(shí)中心全球價(jià)值網(wǎng)絡(luò))他嚷,AI growth(行業(yè)智庫(kù)培訓(xùn))等蹋绽,為中國(guó)的人工智能人才建設(shè)輸送了大量的血液和養(yǎng)分。此外筋蓖,他還參與或者舉辦過各類國(guó)際性的人工智能峰會(huì)和活動(dòng)卸耘,產(chǎn)生了巨大的影響力,書寫了60萬(wàn)字的人工智能精品技術(shù)內(nèi)容粘咖,生產(chǎn)翻譯了全球第一本深度學(xué)習(xí)入門書《神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》蚣抗,生產(chǎn)的內(nèi)容被大量的專業(yè)垂直公眾號(hào)和媒體轉(zhuǎn)載與連載。曾經(jīng)受邀為國(guó)內(nèi)頂尖大學(xué)制定人工智能學(xué)習(xí)規(guī)劃和教授人工智能前沿課程瓮下,均受學(xué)生和老師好評(píng)翰铡。
理解“query then fetch”和“dfs query then fetch”
在上篇文章中,我們遇到一個(gè)返回查詢結(jié)果相當(dāng)奇怪的情形唱捣。
上篇文章并沒有翻譯两蟀,請(qǐng)看原文。 :P
在此我們?cè)俳o出那個(gè)查詢的代碼:
$ curl -XGET localhost:9200/startswith/test/_search?pretty -d '{
"query": {
"match_phrase_prefix": {
"title": {
"query": "d",
"max_expansions": 5
}
}
}
}' | grep title
"_score" : 1.0, "_source" : {"title":"drunk"}
"_score" : 0.30685282, "_source" : {"title":"dzone"}
"_score" : 0.30685282, "_source" : {"title":"data"}
"_score" : 0.30685282, "_source" : {"title":"drive"}
為何文檔“drunk”分?jǐn)?shù)為1.0
震缭,而其余的分?jǐn)?shù)是0.3
赂毯?難道這些文檔不應(yīng)該是相同的分?jǐn)?shù)么,因?yàn)樗麄兌纪鹊仄ヅ淞恕癲”。答案是肯定的党涕,但是這個(gè)分?jǐn)?shù)本身也有比較合理的地方烦感。
相關(guān)性打分
ES使用的打分算法包含了稱之為“TF-IDF”的統(tǒng)計(jì)信息來幫助計(jì)算處于那個(gè)索引中的文檔的相關(guān)性。
TFIDF基本思想就是“一個(gè)項(xiàng)在文檔中出現(xiàn)的次數(shù)越多膛堤,那么這個(gè)文檔更加相關(guān)手趣;但相關(guān)性會(huì)被這個(gè)項(xiàng)在整個(gè)文檔庫(kù)中的次數(shù)削弱”。
稀有項(xiàng)出現(xiàn)在相對(duì)少的文檔中肥荔,那么任何查詢匹配了一個(gè)稀有項(xiàng)的相關(guān)性就變得很高绿渣。相反,平常項(xiàng)到處都有燕耿,他們的相關(guān)性就低了中符。
當(dāng)用戶執(zhí)行一個(gè)搜索時(shí),ES面對(duì)一個(gè)有趣的困境誉帅。你的查詢需要找到所有相關(guān)的文檔淀散,但是這些文檔分布在你的cluster中的任何數(shù)目的shard中。
每個(gè)shard是一個(gè)Lucene的索引蚜锨,保存了自身的TF和DF統(tǒng)計(jì)信息档插。一個(gè)shard只知道在其自身中出現(xiàn)的次數(shù),而非整個(gè)cluster亚再。
但是相關(guān)算法使用了TF-IDF郭膛,它需要知道對(duì)于整個(gè)索引的而不是對(duì)每個(gè)shard的TF和DF么?
默認(rèn)搜索類型:query then fetch
答案:是也不是针余。默認(rèn)情形下饲鄙,ES會(huì)使用一個(gè)稱之為Query then fetch
的搜索類型。它運(yùn)作的方式如下:
- 發(fā)送查詢到每個(gè)shard
- 找到所有匹配的文檔圆雁,并使用本地的Term/Document Frequency信息進(jìn)行打分
- 對(duì)結(jié)果構(gòu)建一個(gè)優(yōu)先隊(duì)列(排序忍级,標(biāo)頁(yè)等)
- 返回關(guān)于結(jié)果的元數(shù)據(jù)到請(qǐng)求節(jié)點(diǎn)。注意伪朽,實(shí)際文檔還沒有發(fā)送轴咱,只是分?jǐn)?shù)
- 來自所有shard的分?jǐn)?shù)合并起來,并在請(qǐng)求節(jié)點(diǎn)上進(jìn)行排序烈涮,文檔被按照查詢要求進(jìn)行選擇
- 最終朴肺,實(shí)際文檔從他們各自所在的獨(dú)立的shard上檢索出來
- 結(jié)果被返回給用戶
這個(gè)系統(tǒng)一般是能夠良好地運(yùn)作的。大多數(shù)情形下坚洽,你的索引有足夠的文檔來平滑Term/Document frequency統(tǒng)計(jì)信息戈稿。因此,盡管每個(gè)shard不一定擁有完整的關(guān)于整個(gè)cluster的frequency信息讶舰,結(jié)果仍然足夠好鞍盗,因?yàn)閒equency在每個(gè)地方基本上是類似的需了。
但是在我們開頭提起的那個(gè)查詢,默認(rèn)搜索類型有時(shí)候會(huì)失敗般甲。
dfs query then fetch
在上篇文章中肋乍,我們默認(rèn)建立了一個(gè)索引,ES通常使用5個(gè)shard敷存。接著插入了5個(gè)文檔進(jìn)入索引墓造,向ES發(fā)送請(qǐng)求返回相關(guān)結(jié)果和準(zhǔn)確的分?jǐn)?shù)。其結(jié)果并不是很公平锚烦,對(duì)吧觅闽?
這是由于默認(rèn)的搜索類型導(dǎo)致的,每個(gè)shard僅僅包含一個(gè)或者兩個(gè)文檔(ES使用hash確保隨機(jī)分布)挽牢。當(dāng)我們要求ES計(jì)算分?jǐn)?shù)時(shí)候谱煤,每個(gè)shard僅僅擁有關(guān)于五個(gè)文檔的一個(gè)很窄的視角摊求。所以分?jǐn)?shù)是不準(zhǔn)確的禽拔。
幸運(yùn)的是,ES并沒有讓你無(wú)所適從室叉。如果你遇到了這樣的打分偏離的情形睹栖,ES提供了一個(gè)稱為“DFS Query Then Fetch”。這個(gè)過程基本和Query Then Fetch類型茧痕,除了它執(zhí)行了一個(gè)預(yù)查詢來計(jì)算整體文檔的frequency野来。
- 預(yù)查詢每個(gè)shard,詢問Term和Document frequency
- 發(fā)送查詢到每隔shard
- 找到所有匹配的文檔踪旷,并使用全局的Term/Document Frequency信息進(jìn)行打分
- 對(duì)結(jié)果構(gòu)建一個(gè)優(yōu)先隊(duì)列(排序曼氛,標(biāo)頁(yè)等)
- 返回關(guān)于結(jié)果的元數(shù)據(jù)到請(qǐng)求節(jié)點(diǎn)。注意令野,實(shí)際文檔還沒有發(fā)送舀患,只是分?jǐn)?shù)
- 來自所有shard的分?jǐn)?shù)合并起來,并在請(qǐng)求節(jié)點(diǎn)上進(jìn)行排序气破,文檔被按照查詢要求進(jìn)行選擇
- 最終聊浅,實(shí)際文檔從他們各自所在的獨(dú)立的shard上檢索出來
- 結(jié)果被返回給用戶
如果我們使用這個(gè)新的搜索類型,那么獲得的結(jié)果更加合理了(這些都一樣的):
$ curl -XGET 'localhost:9200/startswith/test/_search?pretty=true&search_type=dfs_query_then_fetch' -d '{
"query": {
"match_phrase_prefix": {
"title": {
"query": "d",
"max_expansions": 5
}
}
}
}' | grep title
"_score" : 1.9162908, "_source" : {"title":"dzone"}
"_score" : 1.9162908, "_source" : {"title":"data"}
"_score" : 1.9162908, "_source" : {"title":"drunk"}
"_score" : 1.9162908, "_source" : {"title":"drive"}
結(jié)論
當(dāng)然现使,更好準(zhǔn)確性不是免費(fèi)的低匙。預(yù)查詢本身會(huì)有一個(gè)額外的在shard中的輪詢,這個(gè)當(dāng)然會(huì)有性能上的問題(跟索引的大小碳锈,shard的數(shù)量顽冶,查詢的頻率等)。在大多數(shù)情形下售碳,是沒有必要的强重,擁有足夠的數(shù)據(jù)可以解決這樣的問題佩迟。
但是有時(shí)候,你可能會(huì)遇到奇特的打分場(chǎng)景竿屹,在這些情況中报强,知道如何使用DFS query then fetch
去進(jìn)行搜索執(zhí)行過程的微調(diào)還是有用的。