【アップデート】Amazon Elasticsearch Service に Phonetic Analysis プラグインが追加されました

明けましておめでとうございます、藤本です。

昨年一年間で気づけば切りよく 77本のブログをエントリしました。今年は 100本の大台目指して頑張ります。

さて、昨年の12月22日に久しぶりに Amazon Elasticsearch Service にアップデートがありました。

Amazon Elasticsearch Service はプラグインを追加できない制約があります。そんな Amazon Elasticsearch Service にプラグインの追加がありました。Phonetic Analysis プラグインです。

Phonetic Analysis プラグインは知らなかったので、調べて、試してみました。

Phonetic Analysis プラグイン

Phonetic Analysis プラグインは単語を発音へ変換するトークンフィルターを提供します。これにより聞き間違いにより誤って入力した単語も検索できるようになります。例えば、機械的に音声から読み取ったが同音異義語の意図しないメッセージで保管されたデータを、正しいメッセージで検索することができます。RDBMS だけでは実現できない検索エンジンならではの機能ですね。

先日の AWS re:Invent 2016 で Amazon Polly、Amazon Lex といった音声によるインタフェース「VUI」に関連したサービスのリリース、発表がありました。Phonetic Analysis プラグインはこれら VUI への Amazon Elasticsearch Service によるアプローチなのかな、と感じました。

また発音の解析方式はいくつかありますので、ふわっとした解析から、きっちりした解析と色々なのがありますので、適切な解析方式を見つけてください。

提供環境

Phonetic analysis プラグインは Elasticsearch バージョン 2.3 にのみ提供されます。バージョン 2.3 のドメインを立ち上げると、インストール済みで利用を開始することができます。既存のドメインにもインストールされていました。

試してみた

プラグイン確認

インストールされているプラグインを確認してみます。

$ curl https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/_cat/plugins
Kyle Gibney analysis-icu        2.3.2 j
Kyle Gibney analysis-kuromoji   2.3.2 j
Kyle Gibney analysis-phonetic   2.3.2 j
Kyle Gibney cloud-aws           2.3.2 j
Kyle Gibney elasticsearch-jetty 2.2.0 j
Kyle Gibney kibana              2.3.2 s /_plugin/kibana/ 

analysis-phoneticが追加されていることが分かります。

インデックス作成

phoneticトークンフィルターを有効化したアナライザーを適用したインデックスを作成します。また比較のためにstandardアナライザーのフィールドも用意します。

$ curl -XPUT https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index -d '{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "filter": [
              "phonetic"
            ]
          }
        }
      }
    }
  },
  "mappings": {
    "type": {
      "properties": {
        "message": {
          "type":     "string",
          "analyzer": "standard",
          "fields": {
            "phonetic": { 
              "type":  "string",
              "analyzer": "my_analyzer"
            }
          }
        }
      }
    }
  }
}'
{"acknowledged":true}

データを入れて、検索する

サンプルとして、meetmeatで試してみます。I meet youというメッセージを入れたいのに音声認識がI meat youでインデキシングされたとします。

$ curl -XPOST https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index/type -d '{"message": "I meat you"}'
{"_index":"index","_type":"type","_id":"AVljBD_MsclxS0ti6cU3","_version":1,"_shards":{"total":2,"successful":1,"failed":0},"created":true}

これに対してmeetで検索します。まずはstandardアナライザのフィールドを検索します。

$ curl https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index/_search -d '{
  "query": {
    "match": {
      "message": "meet"
    }
  }
}'
{"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

単語が誤っているので検索にヒットしませんでした。

続いて、phoneticトークンフィルターを割り当てたアナライザのフィールドを検索します。

$ curl https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index/_search -d '{
  "query": {
    "match": {
      "message.phonetic": "meet"
    }
  }
}'
{"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":1,"max_score":0.15342641,"hits":[{"_index":"index","_type":"type","_id":"AVljBD_MsclxS0ti6cU3","_score":0.15342641,"_source":{"message": "I meat you"}}]}}

I meat youがヒットしました!

どのようにヒットしている?

さて、どのようにアナライズされていることで、meatに、meetでヒットしているのでしょうか?_analyzeクエリで確認してみましょう。

$ curl https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index/_analyze -d '{
  "analyzer": "my_analyzer",
  "text": "meat"
}'
{"tokens":[{"token":"MT","start_offset":0,"end_offset":4,"type":"<ALPHANUM>","position":0}]}

$ curl https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index/_analyze -d '{
  "analyzer": "my_analyzer",
  "text": "meet"
}'
{"tokens":[{"token":"MT","start_offset":0,"end_offset":4,"type":"<ALPHANUM>","position":0}]}

両方共、MTというトークンになっていますね。けっこうふわっとした解析ですね。多くのケースで検索にヒットしそうです。

$ curl https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index/_search -d '{
  "query": {
    "match": {
      "message.phonetic": "mat"
    }
  }
}'
{"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":1,"max_score":0.15342641,"hits":[{"_index":"index","_type":"type","_id":"AVljBD_MsclxS0ti6cU3","_score":0.15342641,"_source":{"message": "I meat you"}}]}}

うん、matでもヒットしました。。

このふわっと具合を初めの方に説明した解析方式で変更することができます。デフォルトの解析方式はmetaphoneが設定されます。以下のようなインデックスのフィルター設定で encoder のオプションで解析方式を指定可能です。

$ curl -XPUT https://search-phonetic-xxxxxxxxxxxxxxxxx.us-east-1.es.amazonaws.com/index -d '{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "filter": [
              "my_metaphone"
            ]
          }
        },
        "filter": {
          "my_metaphone": {
            "type": "phonetic",
            "encoder": "refinedsoundex"
          }
        }
      }
    }
  }
}'
{"acknowledged":true}

これでもmatはヒットしちゃいましたが。。

まとめ

いかがでしたでしょうか?

Amazon Elasticsearch Service に音声に関するプラグインが追加されました。Amazon Elasticsearch Service は制約が多くあるので、プラグインが増えたり、サポートAPI がどんどん増えることに期待したいです。

参考サイト