Kuromojiのカスタム辞書をインデックスの設定で指定

Posted by johtani on Wednesday, April 22, 2020

目次

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
    }
  ]
}

これで、カスタム辞書を使用することでグランベリーで検索された場合に、グランベリーパークもヒットするという仕組みです。

_analyzeexplainというパラメータも持っており、こちらを利用することで、単語の品詞情報なども取得できます。これを使うことで、実際に設定がきちんと動作しているかの確認に利用できます。

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_dictionaryuser_dictionary_rules両方指定した場合はエラーとなります。 ファイルをベースにしつつ、追加の設定をするという使い方はできないので、注意しましょう。

それ以外の注意点については、別途ブログを書きました。 「辞書の更新についての注意点」、こちらも合わせてご覧ください。

まとめ

カスタム辞書をファイルではなくインデックスの設定値として設定する方法を紹介しました。こちらは、Elasticsearch 7.4で導入された機能になります。7.4以降を利用している場合はこちらを利用することも検討してはいかがでしょうか? また、_analyze APIも便利なので合わせて活用してみてください。


comments powered by Disqus