ElasticSearch之ICU分詞器

Moshow鄭鍇發表於2020-04-07

分詞器

分詞器 接受一個字串作為輸入,將 這個字串拆分成獨立的詞或 語彙單元(token) (可能會丟棄一些標點符號等字元),然後輸出一個 語彙單元流(token stream) 。

一個analyzer分詞器包含三個部分:

  • character filter:分詞之前的預處理,過濾掉HTML標籤、特殊符號轉換等。
  • tokenizer:分詞
  • token filter:標準化

ES內建分詞器

事實上,ElasticSearch中有一些內建分詞器:

  • Standard 分詞器:預設分詞器,會將詞彙單元轉成小寫形式並且去除停用詞和標點符號,支援中文采用的方法為單字切分。
  • Simple 分詞器:首先會通過非字母字元來分割文字資訊,然後將詞彙單元統一為小寫形式。該分詞器會去除掉數字型別的字元。
  • Whitespace 分詞器:僅僅是去除空格,對字元沒有lowcase化,不支援中文;並且不對生成的詞彙單元進行其他標準化處理。
  • Stop 分詞器:相比Simple Analyzer多了去除請用詞處理,停用詞指語氣助詞等修飾性詞語,如the, an, 的, 這等
  • Keyword 分詞器:不分詞,直接將輸入作為一個單詞輸出
  • Pattern 分詞器:通過正規表示式自定義分隔符,預設是\W+,即非字詞的符號作為分隔符
  • Language 分詞器:特定語言的分詞器,不支援中文。如 english 、french 和 spanish 分析器。

應該說,standard 分詞器是大多數西方語言分詞的一個合理的起點。 事實上,它構成了大多數特定語言分析器的基礎,如 english 、french 和 spanish 分析器。 它也支援亞洲語言,只是有些缺陷(=.=To Be Honest , 你輸入任何中文,都會被拆成一個一個的文字來分詞,簡直不要太糟糕),你可以考慮通過 ICU 外掛的方式使用 icu_analyzer 進行中文分詞更合理。

附錄有更詳細的分詞器列表。

分詞API

作為REST的搜尋引擎,ES可以直接 POST http://localhost:9200/_analyze 來查詢分詞的情況。

{
    "text": "I'm going to Guangzhou museum",
    "analyzer": "standard"
}
curl -X POST \
  http://localhost:9200/_analyze \
  -d '{
    "text": "I'\''m going to Guangzhou museum",
    "analyzer": "standard"
}'

curl或者postman都可以:

在這裡插入圖片描述
ICU 分析器外掛

Elasticsearch的 ICU 分析器外掛 使用 國際化元件 Unicode (ICU) 函式庫提供豐富的處理 Unicode 工具。 這些包含對處理亞洲語言特別有用的 icu_分詞器 ,還有大量對除英語外其他語言進行正確匹配和排序所必須的分詞過濾器。

ICU 外掛是處理英語之外語言的必需工具,非常推薦你安裝並使用它,不幸的是,因為是基於額外的 ICU 函式庫, 不同版本的ICU外掛可能並不相容之前的版本,當更新外掛的時候,你需要重新索引你的資料(=。=根據你的ES版本替換後面的版本號,例如我是6.8.1,則用6.8.1,你用7.3.0就用7.3.0,類推)。

#自動安裝
sudo bin/elasticsearch-plugin install analysis-icu
#手動安裝
(自行下載)https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-6.8.1.zip
(Linux)sudo bin/elasticsearch-plugin install file:///path/to/plugin.zip
(Windows)bin\ elasticsearch-plugin.bat install file:///C:\Users\Administrator\Downloads\analysis-icu-6.8.1.zip
#安裝成功
[=================================================] 100%??
-> Installed analysis-icu

ICU分詞

{
    "text": "基於ELK打造強大的日誌收集分析系統(springboot2+logback+logstash+elasticsearch+kibana)",
    "analyzer": "icu_analyzer"
}
{
    "tokens": [
        {
            "token": "基於",
            "start_offset": 0,
            "end_offset": 2,
            "type": "<IDEOGRAPHIC>",
            "position": 0
        },
        {
            "token": "elk",
            "start_offset": 2,
            "end_offset": 5,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "打造",
            "start_offset": 5,
            "end_offset": 7,
            "type": "<IDEOGRAPHIC>",
            "position": 2
        },
        {
            "token": "強大",
            "start_offset": 7,
            "end_offset": 9,
            "type": "<IDEOGRAPHIC>",
            "position": 3
        },
        {
            "token": "的",
            "start_offset": 9,
            "end_offset": 10,
            "type": "<IDEOGRAPHIC>",
            "position": 4
        },
        {
            "token": "日誌",
            "start_offset": 10,
            "end_offset": 12,
            "type": "<IDEOGRAPHIC>",
            "position": 5
        },
        {
            "token": "收集",
            "start_offset": 12,
            "end_offset": 14,
            "type": "<IDEOGRAPHIC>",
            "position": 6
        },
        {
            "token": "分析",
            "start_offset": 14,
            "end_offset": 16,
            "type": "<IDEOGRAPHIC>",
            "position": 7
        },
        {
            "token": "系統",
            "start_offset": 16,
            "end_offset": 18,
            "type": "<IDEOGRAPHIC>",
            "position": 8
        },
        {
            "token": "springboot2",
            "start_offset": 19,
            "end_offset": 30,
            "type": "<ALPHANUM>",
            "position": 9
        },
        {
            "token": "logback",
            "start_offset": 31,
            "end_offset": 38,
            "type": "<ALPHANUM>",
            "position": 10
        },
        {
            "token": "logstash",
            "start_offset": 39,
            "end_offset": 47,
            "type": "<ALPHANUM>",
            "position": 11
        },
        {
            "token": "elasticsearch",
            "start_offset": 48,
            "end_offset": 61,
            "type": "<ALPHANUM>",
            "position": 12
        },
        {
            "token": "kibana",
            "start_offset": 62,
            "end_offset": 68,
            "type": "<ALPHANUM>",
            "position": 13
        }
    ]
}

驗證設想

{
    "text": "北京大學與解放軍總醫院第一附屬醫院婦產科",
    "analyzer": "icu_analyzer"
} 

之前有個設想:北京大學,分詞器會分一個北京一個大學和一個北京大學
結果發現:太天真了,根本沒有北京大學這個分詞。。。。。。
請看下文結果

{
    "tokens": [
        {
            "token": "北京",
            "start_offset": 0,
            "end_offset": 2,
            "type": "<IDEOGRAPHIC>",
            "position": 0
        },
        {
            "token": "大學",
            "start_offset": 2,
            "end_offset": 4,
            "type": "<IDEOGRAPHIC>",
            "position": 1
        },
        {
            "token": "與",
            "start_offset": 4,
            "end_offset": 5,
            "type": "<IDEOGRAPHIC>",
            "position": 2
        },
        {
            "token": "解放",
            "start_offset": 5,
            "end_offset": 7,
            "type": "<IDEOGRAPHIC>",
            "position": 3
        },
        {
            "token": "軍",
            "start_offset": 7,
            "end_offset": 8,
            "type": "<IDEOGRAPHIC>",
            "position": 4
        },
        {
            "token": "總",
            "start_offset": 8,
            "end_offset": 9,
            "type": "<IDEOGRAPHIC>",
            "position": 5
        },
        {
            "token": "醫院",
            "start_offset": 9,
            "end_offset": 11,
            "type": "<IDEOGRAPHIC>",
            "position": 6
        },
        {
            "token": "第一",
            "start_offset": 11,
            "end_offset": 13,
            "type": "<IDEOGRAPHIC>",
            "position": 7
        },
        {
            "token": "附屬",
            "start_offset": 13,
            "end_offset": 15,
            "type": "<IDEOGRAPHIC>",
            "position": 8
        },
        {
            "token": "醫院",
            "start_offset": 15,
            "end_offset": 17,
            "type": "<IDEOGRAPHIC>",
            "position": 9
        },
        {
            "token": "婦產科",
            "start_offset": 17,
            "end_offset": 20,
            "type": "<IDEOGRAPHIC>",
            "position": 10
        }
    ]
}

Smart Chinese Analyzer Plugins

中文分詞器,聽說Elastic Stack 8.0會自帶,但是還沒release,靜候佳音吧。

Smart Chinese Analysis外掛將Lucene的Smart Chinese分析模組整合到elasticsearch中。

提供中文或混合中英文字的分析器。 該分析器使用概率知識來查詢簡體中文文字的最佳分詞。 首先將文字分成句子,然後將每個句子分割成單詞。

sudo bin/elasticsearch-plugin install analysis-smartcn

相關文章