????????毫無疑問,使用同義詞是搜索工程師工具箱中最重要的技巧之一。盡管新手有時會低估同義詞的重要性,但幾乎所有搜索系統(tǒng)都離不開它。與此同時,人們有時仍會低估與使用同義詞相關(guān)的一些復(fù)雜情況和微妙情形,甚至高級用戶也不例外。
????????用好同義詞庫,在搜索的過程中,在提升召回率上,有著奇跡般的力量。
????????最近正在做同義詞庫的工作,在提升召回效果方面,確實有很大的貢獻(xiàn)。本篇文章中,將會詳細(xì)講解如何使用,其中的坑,以及各種玩法的最佳實踐。本篇博文還會回答一些有關(guān)同義詞使用方法的常見問題,并指出一些經(jīng)常需要注意的相關(guān)事項。
同義詞庫使用需求
- 提升召回率。提升召回效果。
- 詞庫熱更新需求。
前言、為什么要使用同義詞
這里引用官方博文的描述。
為幫助大家理解同義詞的巨大作用和靈活性,我們來快速看一下當(dāng)今大多數(shù)搜索引擎的內(nèi)在工作原理。搜索引擎會對文檔和查詢進(jìn)行分析并將其拆解為最小的單元(通常稱為詞元,實際上就是抽象的符號)。搜索時,匹配過程會使用簡單字串相似度,所以如果查詢中有一些十分微小的拼寫錯誤(例如“hous”,只比“house”少一個字母 e)或者使用名詞的復(fù)數(shù)形式(“houses”),即使文檔中包含名詞的單數(shù)形式(“house”),搜索引擎也不會匹配到這份文檔。詞干提取器或模糊查詢等工具雖然可以解決一些最常見的此類問題,但是它們并不能消除相關(guān)聯(lián)的概念或想法之間的差異,也不能將文檔或查詢中稍有不同的單詞用法視為等同。 這時同義詞就派上了大用場。同義詞的英文 synonym 來自于希臘語,分別是前綴 σ?ν(syn,表示“一起”)和 ?νομα(ónoma,表示“名稱”)。從它的詞源可以看出,同義詞表示的是在同一語言或領(lǐng)域中具有完全或基本相同意思的不同詞語。實際上,同義詞的范圍非常廣泛,包括一般同義詞(“疲勞”和“困倦”)、縮寫(英鎊的兩種寫法“l(fā)b.”和“pound”)、電商搜索中產(chǎn)品的不同拼寫(“iPod”和“i-Pod”)、細(xì)微的語言差異(例如均表示電梯的英式英語“l(fā)ift”和美式英語“elevator”)、專業(yè)用詞和普通用詞(例如“犬”和“狗”),甚至單純表示同一概念的兩種方式(“宇宙”和“太空”)。通過提供恰當(dāng)?shù)耐x詞規(guī)則,搜索工程師能夠就哪些詞在各自領(lǐng)域內(nèi)具有相似意思并應(yīng)該采取相似處理方法提供相關(guān)信息。 對搜索引擎而言,至為重要的是知道文檔中的哪個字詞與查詢內(nèi)容相匹配,即使它們可能看起來并不一樣。由于這涉及到十分具體的領(lǐng)域知識,所以用戶需要提供恰當(dāng)?shù)囊?guī)則。同義詞篩選器可在定制分析器中使用,其能夠基于用戶定義的規(guī)則替換或添加其他詞元,既可在索引時進(jìn)行以便在索引后的文檔中同時存儲這些內(nèi)容(例如詞語的兩種變體),也可在索引時進(jìn)行以擴(kuò)展搜索詞并匹配到更多相關(guān)文檔。我們稍后會討論這兩種方法的優(yōu)缺點。
官方的描述,總是很晦澀。其實很簡單,就是要解決我在本文開頭寫的兩個需求點。
一、關(guān)于同義詞最佳實踐問題
- 如何用好同義詞?
關(guān)于這個問題,其實應(yīng)該清楚它的工作原理。這里舉個例子,一篇文章中,用來描述被包圍了,可以用八方受敵,也可以用四面楚歌來描述。再結(jié)合ES的內(nèi)部存儲原理,我們可以選擇在索引階段,在文章中遇到八方來敵的時候,會在倒排表中添加八方來敵和四面楚歌這兩個詞,文檔id指向同一個。這個過程是同義詞在索引階段生效。
但是在索引階段生效,有很大的弊端。
- 由于必須對所有同義詞進(jìn)行索引,所以索引規(guī)模會變大。整體存儲空間增加一倍甚至是幾倍。這在超大規(guī)模的集群中使用,絕對是無法接受的。想想300個節(jié)點的集群,增加一倍或者兩倍,老板絕對不會同意。
- 搜索得分(依賴于字詞統(tǒng)計數(shù)據(jù))可能會受影響,因為同義詞也會計算在內(nèi),所以不常見單詞的統(tǒng)計數(shù)據(jù)會存在偏差。這里和BM25相關(guān)性分?jǐn)?shù)有關(guān),以為詞頻會發(fā)生很大的變化。
- 同義詞庫無法動態(tài)更新,除非進(jìn)行重新索引,否則無法針對既有文檔更改同義詞規(guī)則。在超大規(guī)模的集群中,更新一下詞庫,重跑一遍數(shù)據(jù),絕對不是一天兩天能完成的,動輒上月。
同義詞還可以在搜索階段生效。這可以完美的解決以上在索引階段生效的三個致命 的問題。其工作原理,理解起來也很容易,就是在搜索階段中的分詞的時候,匹配一下同 義詞。例如一次搜索中搜了八方受敵,但是,實際上邏輯是這樣的 (八方受敵 OR 四面 楚歌)。同樣,這樣做也是有代價的。它無法很大的應(yīng)對超多關(guān)鍵詞的檢索。假如你的一 次搜索 100個關(guān)鍵詞。經(jīng)過同義詞以后,有可能變成 200個甚至更多關(guān)鍵詞。
- 檢索過程中的性能損失。如果本身檢索的關(guān)鍵詞不多,那影響微乎其微。假如本來檢索關(guān)鍵詞就很多,又開啟同義詞,性能損失絕對會在一倍以上?。?!即使是這樣,在搜索階段使用同義詞,也遠(yuǎn)好于在索引階段使用同義詞。
- 檢索關(guān)鍵詞變多。檢索的過程中,花費的資源也會更多。這點主要體現(xiàn)在CPU上。
但是在搜索階段使用同義詞。它是能夠解決同義詞庫更新的需求的。統(tǒng)一詞庫可以隨 時變動。而這個更新成本,并不大。對于7.3版本以后的ES來說,僅僅是觸發(fā)一次reloadApi的事情。
POST my_index/_reload_search_analyzers
返回信息如下:
{
"_shards" : {
"total" : 3,
"successful" : 3,
"failed" : 0
},
"reload_details" : [
{
"index" : "my_index",
"reloaded_analyzers" : [
"synonym_analyzer" # 這里是我定義的帶有同義詞的分詞器。
],
"reloaded_node_ids" : [
"jiIC9zJyTES_dMIw0w6n8A",
"dMKuVhnvQySXkO7AfZCXrA",
"_6o86PMrRlegvJfB_G8bTw"
]
}
]
}
-
- 同義詞庫的格式問題
ES中,同義詞庫可以有不同的格式。這里也有很多妙用!我舉三個例子
- eg1 :上班 => 工作 干活
- eg2 :高興,快樂,娛樂,興奮
- eg3 : 工作 干活 => 上班
其中eg1,他的意思是,把上班,映射成兩個詞。假如你搜索上班,經(jīng)過分詞器以后,就變成了搜索 工作和干活。這樣適合在搜索階段使用??梢蕴嵘倩氐臄?shù)量和質(zhì)量。
其中eg2,它的意思是,遇到高興的時候,會分詞器會解析成,高興,快樂,娛樂,興奮這四個詞,同樣真正的搜索也是用這四個詞去搜索的。這樣適合在搜索階段使用??梢蕴嵘倩氐臄?shù)量和質(zhì)量。
其中eg3,它的意思是,把工作和干活映射成上班。這樣的可以應(yīng)用在索引階段。其實可以巧妙的幫業(yè)務(wù)去解決歸一化的問題。假如中國,cn,zh,chaina,中華人民共和國,都想映射成中國,做標(biāo)準(zhǔn)化的數(shù)據(jù),在檢索階段是可以提速的。同樣在索引階段也是可以節(jié)省倒排鏈的長度的。
二、實戰(zhàn)
實際操作一下。
- 是否使用插件?
同義詞其實是ES本身就有的能力。同義詞插件,通常是用來做熱更新的,或者是用來把詞庫放在遠(yuǎn)端(例如Nginx)。其實本質(zhì)上是解決更新問題的。假如說你的集群有幾百個節(jié)點,用本地詞庫,每次更新詞庫要更新幾百個節(jié)點,這操作起來多少有點麻煩。
- 如何使用同義詞?
在es里邊其實使用的是filter,添加一個filter即可,并把這個filte在分詞器中綁定。
Synonym token filter | Elasticsearch Guide [7.11] | Elastic
我這里只提幾個點。
PUT /test_index
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "whitespace",
# 這里引用了同義詞的filter
"filter": [ "synonym" ]
}
},
"filter": {
"synonym": {
"type": "synonym",
# 注意這里,analysis一個目錄,它是在es解壓后的config下的目錄。synonym.txt 是同義詞庫。具體文件,下邊會給。
"synonyms_path": "analysis/synonym.txt",
# 這個參數(shù),可以忽略同義詞庫中分詞有問題的錯誤行。
"lenient": true,
# 這個參數(shù)很重要,只有開其他,才能實現(xiàn)同義詞庫的熱更新。
"updateable": true
}
}
}
}
}
}
- 同義詞庫
https://github.com/zhoushineyoung/search-prod/blob/63dba77eaa98a81e29b9ac8e9179ac5b93538da3/solr-cloud/solr-4.7.0/solr/sentiment/conf/synonyms.txt#L1981
這里分享了一個同一個以詞庫。請注意詞庫的內(nèi)容。根據(jù)上述如何修改詞庫,自行決定。我是把同義詞用逗號分隔的。我把這個文件中的 => 替換成了逗號。文章來源:http://www.zghlxwxcb.cn/news/detail-785727.html
- 如何動態(tài)更新
POST article_info_test_1109_2/reload_search_analyzers
# 執(zhí)行結(jié)果
{
"_shards" : {
"total" : 3,
"successful" : 3,
"failed" : 0
},
"reload_details" : [
{
"index" : "article_info_test_1109_2",
# 這里可以看到有刷新的分詞器。
"reloaded_analyzers" : [
"synonym_analyzer"
],
"reloaded_node_ids" : [
"jiIC9zJyTES_dMIw0w6n8A",
"dMKuVhnvQySXkO7AfZCXrA",
"_6o86PMrRlegvJfB_G8bTw"
]
}
]
}
三、同義詞官方博文
借助同義詞讓 Elasticsearch 更加強(qiáng)大 | Elastic Blog文章來源地址http://www.zghlxwxcb.cn/news/detail-785727.html
到了這里,關(guān)于Elasticsearch同義詞最佳實踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!