Solr + kuromoji で単語の切れ方がおかしかったのでガッツリ調べてみた、理由と調べ方その方法を公開します!
調査のきっかけは「デジタル一眼レフ」という文字列が含まれているフィールドに「一眼レフ」で検索してもヒットしないという現象です。日本語の形態素解析をつかった検索では結構在りがちで、大体ユーザー辞書に登録すれば良くなるのですが*1、今回は表面的な対策だけでなく、根本原因を探ってみることにしました。
追記 9/17:タイトルに solr とありますが、中で kuromoji を使っているのは同じなので本質的には elasticsearch でも通用するネタです。ただし、Elasticsearch については、デフォルトで analysis の画面が無いので、分析には plugin を入れるなどちょっとだけ手間が必要かもしれません。(要調査)
参考:elasticsearch-kopfの紹介(analysis画面) - @johtaniの日記 2nd
環境
- solr 4.9.0
- kuromoji (solrに標準で入っているものなので mecab-ipadic)
原因調査
まず、solr の analysis 画面で単語の切れ方を調べてみることにしました。画面左の field value (Index) に、文書に含まれている「デジタル一眼レフ」を入力し、画面右の field value (Query) に「一眼レフ」を入力すると、検索されたときの文字列の処理の状況が再現できます。ちなみに、青くハイライトされた箇所は、マッチした単語(形態素)になり、全て青くなると field value (Index) に入力した単語を含む文書が field value (Query) で検索した場合にヒットすることを示しています。
以下は、そのスクリーンショットです。一見して、query と index を比較すると、index 側が「一眼」が「一」「眼」と切れており、単語の切れ方が異なるためヒットしないことがわかりました。まあ、予想通り。
kuromoji の使っている辞書の中身を探ってみる
次に、根本原因としては、多分、辞書が原因だろうとあたりを付けて、辞書を kuromoji.jar から抽出して調査しました。わかったのは、mecab-ipadic-2.7.0-20070801 というバージョンがコンパイルされた状態で含まれているということ。なので、jar を展開しても、辞書の中身を直接見ることが出来ないので、別途コンパイル前のもともとの mecab-ipadic をダウンロードしてきます。
mecab-ipadic の構造について
ダウンロードしてきたファイルを展開します。展開されたファイルは色々な種類があるのですが、今回の課題を分析するために関連しそうな辞書のファイルを調査、ピックアップしました。
- *.csv に単語および単語コストが記載されている
- matrix.def に連結コストが記載されている
- さらなる詳細な説明は、以下の本家サイトで。 http://mecab.googlecode.com/svn/trunk/mecab/doc/dic-detail.html
形態素解析の分割ロジック
なぜ上記で、単語と連結コストしか調べてないかというと、今回の原因は単に辞書に単語が無いか、連結がおかしいかのいずれかだと推測したからです。形態素解析は、どの数ある単語(形態素)からどれを正解として選択するか決定するために、コスト最小化法というロジックを採用しているからです。以下、簡単な説明です。
- 辞書には分割後の単語の一覧と、単語がどのように連結されるかの一覧が含まれる
- 単語と連結には、それぞれコストと呼ばれる数値が設定されている
- 入力された文字列と、辞書の単語と連結から、形態素の候補を複数あげる
- その際に、候補の中から、単語コストと連結コストを足した結果が最も小さい並びを形態素解析結果として出力する
- コスト最小法の説明は、以下の13スライド目を参照するととても分かりやすい
http://www.slideshare.net/torotoki/ss-9720666
ちなみに、コストは予めコーパスと呼ばれる、大量の文章を元に、CRFや隠れマルコフモデルなどで機械学習的に推定し作成するそうです。 (mecab は CRF)
辞書の中身はどうだったのか?
というわけで、単語コストと連結コストをピックアップして整理したのが以下です。結論としては、やはり予想通り、変な切れ方をしている方がコストの合計が若干少ないことがわかりました。以下は、辞書から、連結コストと単語コストのレコードを、抽出して列挙したものです。
- 連結コスト、形態素、連結コスト・・・という繰り返しで行ごとに記載
- 単語(形態素)の行の、左から4つめの数字が単語コスト。「デジタル」のコストは 3083 です。
まず、実際に切れている、「デジタル」「一」「眼」「レフ」についてコストを羅列したもの。合計で 10767
-283 デジタル 1285 1285 3083 名詞 一般 * * * * デジタル デジタル デジタル -1625 一 1295 1295 3485 名詞 数 * * * * 一 イチ イチ -1579 眼 1285 1285 4540 名詞 一般 * * * * 眼 メ メ 62 レフ 1285 1285 3657 名詞 一般 * * * * レフ レフ レフ -573
一方、こう切って欲しい、「デジタル」「一眼」「レフ」の場合のコストは、上記よりも大きい。こちらは 10780。わずか 3 の差です。
-283 デジタル 1285 1285 3083 名詞 一般 * * * * デジタル デジタル デジタル 62 一眼 1285 1285 5117 名詞 一般 * * * * 一眼 イチガン イチガン -283 レフ 1285 1285 3657 名詞 一般 * * * * レフ レフ レフ -573
じゃあ対策は?
「デジタル」「一眼」「レフ」をユーザー辞書に登録しておくのが一番オーソドックスで間違いのない方法かと思います。コストを手動で直接いじるのは、全体に影響があるため、とてもリスクが大きいと考えられます。というのは、連結の定義が記載されている matrix.def ファイルを見ると単語同士の連結が ID でしめされているのですが、ID を共有する単語がいくつもあることが簡単にわかります。そうすると、一つのコストを動かすと他も動くし、連動して変な箇所で切れるようになったりする、と予想されます。
他の方法としては、辞書の作り直し、辞書に単語追加して CRF で再学習させるってのもありますが、こんど試してみようかと思います。
確認の仕方が面倒くさいんだけど
実は、kuromoji 限定ですが、UIで確認できる方法があります。それは次回に。。。
続きはこちらから!
kuromoji のサイトに行くと、トークナイズの処理を分析することができる。 - よしだのブログ
参考
[改訂新版] Apache Solr入門 ~オープンソース全文検索エンジン (Software Design plus)
- 作者: 大谷純,阿部慎一朗,大須賀稔,北野太郎,鈴木教嗣,平賀一昭,株式会社リクルートテクノロジーズ,株式会社ロンウイット
- 出版社/メーカー: 技術評論社
- 発売日: 2013/11/29
- メディア: 大型本
- この商品を含むブログ (7件) を見る
*1:結論は出たw