ES中分詞器Analyzer的組成
分詞器是專門處理分詞的元件,由三部分組成。
- Character filter:針對原始文本處理,例如去除html
- Tokenizer:按照規則切分為單詞
- Token Filter:将切分的單詞進行加工,小寫,删除stopwords,增加同義詞
以上三部分是串行處理的關系,除Tokenizer隻能一個外,其他兩個都可以多個。IK分詞器僅實作了Tokenizer
IK分詞器原理
IK分詞器在是一款基于詞典和規則的中文分詞器。具有以下特性:
- 采用了特有的“正向疊代最細粒度切分算法“
- 支援細粒度和智能分詞兩種切分模式
- 智能分詞模式支援簡單的分詞排歧義處理和數量詞合并輸出
- 采用了多子處理器分析模式,支援:英文字母、數字、中文詞彙等分詞處理,相容韓文、日文字元
IK内部有3個子分詞器(Segmenter),CJKSegmenter(中日韓文分詞器),CN_QuantifierSegmenter(中文數量詞分詞器),LetterSegmenter(英文分詞器)。
LetterSegmenter:從遇到第一個英文字元往後,直到碰到第一個非英文字元,這中間的所有字元則切分為一個英文單詞。
CN_QuantifierSegmenter:從遇到每一個中文數量詞,然後檢查該數量詞後一個字元是否為中文量詞(根據是否包含在中文量詞詞典中為判斷依據),如是,則分成一個詞,如否,則不是一個詞。
CJKSegmenter:處理邏輯較為複雜,整體思路是從字典樹中尋找比對的詞
分詞裁決器IKArbitrator:隻有在Smart模式才會生效,僅根據幾條可能是最佳的分詞實踐規則,并沒有用到任何機率模型,也不具有新詞發現的功能。
兩種分詞模式
智能模式
對應es的IK插件的ik_smart,會做最粗粒度的拆分。比如會将“中華人民共和國國歌”拆分為“中華人民共和國,國歌”,适合 Phrase 查詢。
細粒度模式
對用es的插件ik_max_word: 會将文本做最細粒度的拆分,比如會将“中華人民共和國國歌”拆分為“中華人民共和國,中華人民,中華,華人,華,人民共和國,人民,人,民,共和國,共和,和,國國,國歌”,會窮盡各種可能的組合,适合 Term Query。
IK分詞實踐
IK分詞的效果主要取決于詞庫,目前自帶主詞典擁有27萬左右的漢語單詞量。對于應用領域的不同,需要各類專業詞庫的支援。
分詞規律
es檢索的核心資料結構為反向索引,分詞是否合理正确,直接影響資料的檢索結果,在自定義詞典及分詞器時,可以采取以下方式來驗證分詞的結果:
GET /_analyze
{
"analyzer": "ik_max_word",
"text": ["甲三"]
}
ik_max_word
- 當查詢詞在詞典中不存在時,會按字拆分
例如:在北-->在,北
- 當查詢詞在詞典中存在,且長度為兩個字時,有時拆分有時不拆分
例如:甲乙-->甲乙
聯通-->聯通,聯,通
- 當查詢詞在詞典中存在,且查詢詞的一部分也在詞典在中存在,則分别拆分
例如:甲乙丙丁-->甲乙丙丁,甲乙,丙丁
中國聯通-->中國聯通,中國,國聯,聯通,通(沒弄明白為啥這裡聯通不拆成聯、通)
- 當查詢詞任意部分都不在詞典中存儲,則按字拆分
ik_smart
- 當查詢詞在詞典中存在,不做拆分
甲乙丙丁-->甲乙丙丁
依據上述規律,我們可以在寫入資料時使用ik_max_word,增加分詞數量,提高被命中幾率,在查詢資料時使用ik_smart,減少分詞數量,提升結果準确率,減少無關結果
去掉分詞結果中的單個字
使用es内置的token filter:length
POST _analyze
{
"text": "一中華人民共和國國歌",
"filter": [
{
"type": "length",
"min": "2"
}
],
"tokenizer": "ik_smart"
}
分詞結果中“一”被過濾掉,但對于某些查詢詞,例如“父與子”,該設定會導緻無分詞結果