はじめに
日本語でsynonymを追加しょうと考えたが、
なぜか下記のような設定にしていると「株式会社」といった同義語を追加しようとするとエラーになる現象があった。
「株式会」や「式会社」「株式」「会社」のどれでもエラーにならないにも関わらず、「株式会社」でエラーになる。
Pythonを利用しているが、他の環境でもおそらく同様の事象が起きると思われる。
# python辞書(JSONではない。pythonでelasticsearchを利用しているため。)
{
"settings": {
"analysis": {
"analyzer": {
"default": {
"tokenizer": "kuromoji_tokenizer",
"filter": [
"my_synonym"
]
}
},
"filter": {
"my_synonym": {
"type": "synonym",
"synonyms": [
'株式会社,アメリカンフットボール'
]
}
}
}
}
}
elasticsearch.exceptions.RequestError: TransportError(400, 'illegal_argument_exception', 'failed to build synonyms')
このようなエラーが出る。
日本語で上手く行っていない人の例。
これと同じ現象に見舞われた。
Webで調べてみた
tokenizer? filter?
ここによると
This means that all your synonym rules are analyzed with an icu_tokenizer and the following filters
とあり、特殊文字がtokenizerによって処理されることが書かれている。
'% => pour cent' is not accepted because % is removed by the icu_tokenizer and therefore could never be found in a text that pass through this analyzer.
%はicu_tokenizerによってなくなってしまう。
The phonetic filter should be put after the synonym filter. The synonyms should not be checked against the phonetic form and we disallow rules that have multiple rewriting (original form + phonetic form for instance).
filterの順番も重要らしい。
ここによると、
Is there any other way to fix this, other than having to delete the synonyms?
I think it would be possible to extend the SynonymMap parsing so that it could handle graph tokenstreams, but it wouldn't be simple. The other immediate workaround would be to see if you really need to have the word delimiter filter in there.
解決はシンプルではない・・・など話されていて悩ましい。
その他参考:
文字コード?
ファイルで読み込み、ファイルエンコードをutf-8とすれば解決したとのこと。
こちらも文字コードと言われている。
色々実験してみた
tokenizerの変更
tokenizerをwhitespaceやstandardにしてみた。
どうやらsynonym追加には成功するらしい?
ただし、肝心のsynonymが正常動作しない。
tokenizerのカスタマイズ
kuromojiトークナイザーのmodeを修正する
# python辞書(JSONではない)
{
"settings": {
"analysis": {
"analyzer": {
"default": {
"tokenizer": "ja_tokenizer",
"type": "custom",
"filter": [
"my_synonym"
]
}
},
"tokenizer": {
"ja_tokenizer": {
"type": "kuromoji_tokenizer",
"mode": "normal",
}
},
"filter": {
"my_synonym": {
"type": "synonym",
"synonyms": [
'株式会社,アメリカンフットボール'
]
}
}
}
}
}
このように記述すると成功した。
ただし、kuromoji_tokenizerをsearchモードで使う場合にはどうしたらよいかわからなかった。
こちらの例ではstandard tokenizerを使っているようです。
フレーズ検索をつかっているためかstandard tokenizerを使うとヒットしないんですよね。
こちらはkuromoji_tokenizerを使っているが、きゃりーぱみゅぱみゅのテキストを入れてみてもエラーにならなかったので、たまたま問題を回避している?
こちらもkuromoji_tokenizerをつかってsearchモードで行っているが、icu_normalizerのおかげだろうか?
それともタマタマエラーが出なかっただけ?
- Amazon Elasticsearch Service で類義語(Synonym)を扱う | Developers.IO
- 研究開発:elasticsearchで表記ゆれ対応設定 - livedoor Blog(ブログ)
この人達もエラーがたまたま出ていないだけのようなきがする。
他に考えられるのはAnalyzerがsearch_analyzerかindex_analyzerかで変わっている?
searchとindexのアナライザーを個別に設定
ここあたりを参考にmappingにsearch_analyzerとanalyzerを指定してみたが、変化は無かった。
※index_analyzerはanalyzerとして指定するように途中のバージョンから変わったらしい。
結論
時間の関係でまだ完全に調査しきれていないが、kuromoji_tokenizerでsynonymを扱うときにはsearchモードが利用できないのではないかと思われる。その場合はkuromoji_tokenizerをやめるか、normalモードにする必要あり?
synonymをファイルで扱うものは検証していないが、もしかしたらそちらでは解決するかもしれません。
また、explain等を利用してanalyzerによる結果をもう少し詳しく分析できれば他にも解決方法があるかもしれません。
もしも他に情報がありましたら教えていただきたいです。