深入解析 Elasticsearch IK 分詞器:ik_smart 和 ik_max_word 的區(qū)別與應(yīng)用場(chǎng)景
1、Elasticsearch ik 分詞器常見(jiàn)問(wèn)題
最近在 git 上看看 ik 的相關(guān)問(wèn)題,發(fā)現(xiàn)大家問(wèn)的比較多的是 ik 分詞器的 ik_smart 和 ik_max_word 兩個(gè)分詞模式,以及它倆之間的分詞差異。
圖片
圖片
這里來(lái)集中解釋一波,期望對(duì)大家有幫助。
2、ik_smart 與 ik_max_word 的異同
首先來(lái)看下官方的FAQs
What is the difference between ik_max_word and ik_smart?
ik_max_word: Performs the finest-grained segmentation of the text. For example, it will segment "中華人民共和國(guó)國(guó)歌" into "中華人民共和國(guó),中華人民,中華,華人,人民共和國(guó),人民,人,民,共和國(guó),共和,和,國(guó)國(guó),國(guó)歌", exhaustively generating various possible combinations, suitable for Term Query.
ik_smart: Performs the coarsest-grained segmentation of the text. For example, it will segment "中華人民共和國(guó)國(guó)歌" into "中華人民共和國(guó),國(guó)歌", suitable for Phrase queries.
Note: ik_smart is not a subset of ik_max_word.
官方這里簡(jiǎn)單的描述了一下使用用途,即:
- ik_smart 比較適合 match_phrase query,而 ik_max_word 更合適 term query。
- ik_smart 的分詞結(jié)果并不是 ik_max_word 的分詞結(jié)果的子集。
那這兩個(gè)分詞器在具體實(shí)現(xiàn)上會(huì)有什么不一樣呢?
哪些場(chǎng)景兩個(gè)分詞器的分詞結(jié)果肯定不同呢?
造成分詞結(jié)果不一樣的原因是什么?
3、ik 分詞器源碼分析
3.1. 量詞處理源碼剖析
這里先看一下這段代碼。
private void compound(Lexeme result){
if(!this.cfg.isUseSmart()){
return ;
}
//數(shù)量詞合并處理
if(!this.results.isEmpty()){
if(Lexeme.TYPE_ARABIC == result.getLexemeType()){
Lexeme nextLexeme = this.results.peekFirst();
boolean appendOk = false;
if(Lexeme.TYPE_CNUM == nextLexeme.getLexemeType()){
//合并英文數(shù)詞+中文數(shù)詞
appendOk = result.append(nextLexeme, Lexeme.TYPE_CNUM);
}else if(Lexeme.TYPE_COUNT == nextLexeme.getLexemeType()){
//合并英文數(shù)詞+中文量詞
appendOk = result.append(nextLexeme, Lexeme.TYPE_CQUAN);
}
if(appendOk){
//彈出
this.results.pollFirst();
}
}
//可能存在第二輪合并
if(Lexeme.TYPE_CNUM == result.getLexemeType() && !this.results.isEmpty()){
Lexeme nextLexeme = this.results.peekFirst();
boolean appendOk = false;
if(Lexeme.TYPE_COUNT == nextLexeme.getLexemeType()){
//合并中文數(shù)詞+中文量詞
appendOk = result.append(nextLexeme, Lexeme.TYPE_CQUAN);
}
if(appendOk){
//彈出
this.results.pollFirst();
}
}
}
}
這里由 smart 模式觸發(fā)的 合并英文數(shù)詞+中文量詞 的處理中,把 token 的屬性修改成了 TYPE_CQUAN (中文數(shù)量詞)。
這是 smart 模式下?lián)碛卸?nbsp;max 模式下沒(méi)有的分詞方式和 token 類型。
舉個(gè)例子:“7天” 這個(gè)詞的分詞結(jié)果,結(jié)果中分別展示了位置:內(nèi)容:類型
ik_max_word:
0-1 : 7 : ARABIC
1-2 : 天 : COUNT
ik_smart
0-2 : 7天 : TYPE_CQUAN
也就是說(shuō) ik_max_word 與 ik_smart 在‘英文數(shù)詞+中文量詞’的分詞場(chǎng)景下,分詞結(jié)果必定不一樣。
3.2. 切分模式和歧義消除剖析
ik分詞器的算法原則還是基于中文字典進(jìn)行字典樹(shù)的匹配。
也就是說(shuō)詞元匹配的前提是豐富的中文字典庫(kù)(ik 已經(jīng)默認(rèn)加載了幾十萬(wàn)的字典庫(kù)了)。
我們先來(lái)看 ik_max_word 的切分模式:執(zhí)行文本的最細(xì)粒度分割,將分段詳盡地生成各種可能的組合。
來(lái)看下“中華人民共和國(guó)國(guó)歌”的例子,這里為了更加直觀的體現(xiàn)字典樹(shù)的匹配模式,我們把字典庫(kù)的內(nèi)容也列出來(lái)。
文本:中華人民共和國(guó)國(guó)歌
字典庫(kù):中華人民共和國(guó)國(guó)歌,中華人民,中華,華人,人民共和國(guó),人民,共和國(guó),共和,國(guó)國(guó),國(guó)歌
ik_max_word 分詞結(jié)果:
0-9 : 中華人民共和國(guó)國(guó)歌 : CN_WORD
0-4 : 中華人民 : CN_WORD
0-2 : 中華 : CN_WORD
1-3 : 華人 : CN_WORD
2-7 : 人民共和國(guó) : CN_WORD
2-4 : 人民 : CN_WORD
4-7 : 共和國(guó) : CN_WORD
4-6 : 共和 : CN_WORD
6-8 : 國(guó)國(guó) : CN_WORD
7-9 : 國(guó)歌 : CN_WORD
可以看出 ik_max_word 分詞器把所有的字典結(jié)果都匹配出來(lái)了,同時(shí)也看到了好幾個(gè)詞元的位置是有重疊的,比如:“中華人民”“中華”“華人”這幾個(gè)詞元,位置在0-4這段有著不同的重疊。
這也就是造成了代碼中所需要處理的“歧義”,我們這里可以把“歧義”理解為多個(gè)詞元組合去代表一段內(nèi)容。
而 ik_smart 分詞器主要作用就是通過(guò)對(duì)詞元組合進(jìn)行歧義裁決來(lái)消除詞元間的歧義,消除歧義后的直觀體現(xiàn)就是不再會(huì)有位置重疊的詞元(這也是 ik_smart 更適合 match_phrase 查詢的原因)。
ik_smart 遵循歧義裁決的主要原則順序如下:
- 比較有效文本長(zhǎng)度,越長(zhǎng)越好;
- 比較詞元個(gè)數(shù),越少越好;
- 路徑跨度越大越好;
- 根據(jù)統(tǒng)計(jì)學(xué)結(jié)論,逆向切分概率高于正向切分,因此位置越靠后的優(yōu)先;
- 詞元位置權(quán)重比較,詞長(zhǎng)越平均越好。
同樣的文本內(nèi)容,同樣的字典庫(kù),ik_smart 的分詞結(jié)果如下:
ik_smart 分詞結(jié)果:
0-9 : 中華人民共和國(guó)國(guó)歌 : CN_WORD
由于字典庫(kù)中“中華人民共和國(guó)國(guó)歌”可以覆蓋整個(gè)文本,并滿足上訴大多數(shù)條件,ik_smart 就只保留了第一個(gè)詞元。
為了更直觀的感受,我們把“中華人民共和國(guó)國(guó)歌”從詞庫(kù)中去除。
字典庫(kù):中華人民,中華,華人,人民共和國(guó),人民,共和國(guó),共和,國(guó)國(guó),國(guó)歌
ik_smart 分詞結(jié)果:
0-4 : 中華人民 : CN_WORD
4-7 : 共和國(guó) : CN_WORD
7-9 : 國(guó)歌 : CN_WORD
對(duì)于 ik_smart 歧義裁決原理有興趣的同學(xué)可以看源碼中 LexemePath 類的 compareTo 方法。
4、使用建議
- 召回要求高,對(duì)分詞詞元匹配精準(zhǔn)的,使用 ik_max_word,并結(jié)合 term 查詢。
- 召回要求低,分詞切分要求較低,節(jié)省存儲(chǔ),比如日志場(chǎng)景,可以考慮 ik_smart 進(jìn)行 match_phrase查詢。
- 索引分詞器和搜索分詞器原則上保持一致,如果索引使用 ik_max_word 而搜索使用 ik_smart,則有詞元匹配失敗的可能。
作者介紹
金多安,Elastic 認(rèn)證專家,Elastic資深運(yùn)維工程師,死磕Elasticsearch知識(shí)星球嘉賓,星球Top活躍技術(shù)專家,搜索客社區(qū)日?qǐng)?bào)責(zé)任編輯