目次
Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Serviceでカスタム辞書ファイルを読み込める機能が発表されたようです。
実は、Elasticsearchの7.4からファイルを使用しなくても日本語のTokenizerでカスタム辞書を利用することができるようになっています。
カスタム辞書をインデックスの設定で指定
やり方はドキュメントに記載があります。
トークナイザーの設定をインデックスの設定に記述しますが、このときに
user_dictionary_rules
という設定を利用することでカスタム辞書を指定できます。
PUT custom_dic_sample
{
"settings": {
"index": {
"analysis": {
"tokenizer": {
"kuromoji_user_dict": {
"type": "kuromoji_tokenizer",
"mode": "extended",
"user_dictionary_rules": [
"グランベリーパーク,グランベリー パーク,グランベリー パーク,カスタム名詞",
"高輪ゲートウェイ,高輪 ゲートウェイ,タカナワ ゲートウェイ,カスタム名詞"]
}
},
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "kuromoji_user_dict"
}
}
}
}
}
}
辞書の内部は"単語,出てきてほしい単語列(スペース区切り),読みの単語列(スペース区切り),品詞名"
になります。配列で設定可能で、複数の単語を登録したい場合は、カンマ区切りで登録していきます(上記例では2つの単語を登録しています)。
_analyzeを利用して設定の確認
実際に上記の設定がうまく動作するかは_analyze
のエンドポイントを利用します。
GET custom_dic_sample/_analyze
{
"text": "グランベリーパークがオープンしました。",
"analyzer": "my_analyzer"
}
出力は以下のようになります。
{
"tokens" : [
{
"token" : "グランベリー",
"start_offset" : 0,
"end_offset" : 6,
"type" : "word",
"position" : 0
},
{
"token" : "パーク",
"start_offset" : 6,
"end_offset" : 9,
"type" : "word",
"position" : 1
},
{
"token" : "が",
"start_offset" : 9,
"end_offset" : 10,
"type" : "word",
"position" : 2
},
{
"token" : "オープン",
"start_offset" : 10,
"end_offset" : 14,
"type" : "word",
"position" : 3
},
...(省略)
]
}
ちなみに、デフォルトのkuromoji
を利用した場合は、グランベリーパーク
が1単語として出力されます。
GET _analyze
{
"text": "グランベリーパークがオープンしました。",
"analyzer": "kuromoji"
}
## レスポンス
{
"tokens" : [
{
"token" : "グランベリーパーク",
"start_offset" : 0,
"end_offset" : 9,
"type" : "word",
"position" : 0
},
{
"token" : "オープン",
"start_offset" : 10,
"end_offset" : 14,
"type" : "word",
"position" : 2
}
]
}
これで、カスタム辞書を使用することでグランベリー
で検索された場合に、グランベリーパーク
もヒットするという仕組みです。
_analyze
はexplain
というパラメータも持っており、こちらを利用することで、単語の品詞情報なども取得できます。これを使うことで、実際に設定がきちんと動作しているかの確認に利用できます。
GET custom_dic_sample/_analyze
{
"text": "グランベリーパークがオープンしました。",
"analyzer": "my_analyzer",
"explain": true
}
## レスポンス(一部のみ)
{
"detail" : {
"custom_analyzer" : true,
"charfilters" : [ ],
"tokenizer" : {
"name" : "kuromoji_user_dict",
"tokens" : [
{
"token" : "グランベリー",
"start_offset" : 0,
"end_offset" : 6,
"type" : "word",
"position" : 0,
"baseForm" : null,
"bytes" : "[e3 82 b0 e3 83 a9 e3 83 b3 e3 83 99 e3 83 aa e3 83 bc]",
"inflectionForm" : null,
"inflectionForm (en)" : null,
"inflectionType" : null,
"inflectionType (en)" : null,
"partOfSpeech" : "カスタム名詞",
"partOfSpeech (en)" : null,
"positionLength" : 1,
"pronunciation" : null,
"pronunciation (en)" : null,
"reading" : "グランベリー",
"reading (en)" : "guramberi",
"termFrequency" : 1
},
{
partOfSpeech
にカスタム辞書で設定したカスタム名詞
が出力されていますね。
_analyze
のAPIはこのように、アナライザーの挙動の確認に非常に便利なので是非活用してみてください。
KibanaでこのAPIを使うためのプラグインも開発していますので、こちらも合わせて利用してみてください。
注意点
ちなみに、user_dictionary
とuser_dictionary_rules
を両方指定した場合はエラーとなります。
ファイルをベースにしつつ、追加の設定をするという使い方はできないので、注意しましょう。
インデックスの設定で書くことにより、バックアップ・リストアは楽になるかな。ただ、クラスターステートに取り込まれるから、あまりにも巨大なカスタム辞書だと心配かなぁ。ファイルの場合はクラスターステートには取り込まれないので、そこは圧迫しない。
— Jun Ohtani (@johtani) April 22, 2020
それ以外の注意点については、別途ブログを書きました。 「辞書の更新についての注意点」、こちらも合わせてご覧ください。
まとめ
カスタム辞書をファイルではなくインデックスの設定値として設定する方法を紹介しました。こちらは、Elasticsearch 7.4で導入された機能になります。7.4以降を利用している場合はこちらを利用することも検討してはいかがでしょうか?
また、_analyze
APIも便利なので合わせて活用してみてください。
comments powered by Disqus
See Also by Hugo
- 辞書の更新についての注意点
- Apache LuceneのKuromojiのUniDicビルド対応パッチについて
- インデックステンプレートとLogstash
- validate APIの利用
- Elasticsearchの新しいJavaクライアント(2024年3月版)