こんにちは。サイオステクノロジー OSS サポート担当 山本 です。
今回は前回紹介した Solr がなぜ早いのかと、Solr を使いこなすためには必須となる概念についてお話ししてみようと思います。
■Solr の検索が早いカラクリ
繰り返しになりますが Solr の主な強みは検索が超高速であることです。
その検索の早さを支えているのは、インデックスという仕組みです。
Solr のインデックスはその名のとおり登録されたドキュメント (データ) の目次であり、基本的にはドキュメントを登録する際に自動的に作成されます。
※ 前回似ていると紹介した RDB にもインデックスという概念はありますが、Solr のそれとはやり方が大きく異なるものです。
そして、検索の際にはこのインデックスから検索を行うことで超高速な文字列検索を実現できる、というわけです。
さて、ではどのようにしてこの「目次」を作っているのかと言うと……スキーマにおいて各フィールドで設定した内容に応じてドキュメント内の文章を解析して、その解析結果から作られています。
特に日本語を使いたい場合、この解析のために必要になってくるのが自然言語処理の一種である形態素解析というものです。
■形態素解析をなんとなく知る
自然言語処理は非常にざっくり言ってしまえば、人間が普段使っている言葉をコンピュータで適切に処理できるようにするための技術・学問です。
形態素解析は自然言語処理の一分野で、文章を単語に分けて品詞の種類や原形などを特定する、ということを扱います。
コンピュータの分野では、更に細分化して単語に分ける部分だけをトークナイズなどと呼んだりもするようです。
トークナイズの例を考えてみましょう。
以下の文章を単語に分けてみてください。
This is a red pencil.
これは…
This / is / a / red / pencil / .
こうですね。
このように単語に分割するのがトークナイズで、更に分けた単語の品詞などを特定してやれば形態素解析、と言えるでしょう(非常にざっくりとした考え方でよければ、という前提は付きますが)。
さて、この例で見てもらった英語を含め、大半の言語では最初から単語ごとにスペースで区切って文章を書きます。
そのため、コンピュータで扱う場合でも基本的には機械的に「スペース」という文字が出てきたら区切る、という処理で単語に分けられる(一部例外はあり)ため、形態素解析というものは原則としてあまり難しいものではないようです。
一方で日本語はというと……例えば以下の文章を単語に分けてみましょう。
これはあかいえんぴつです。
これは…
これ / は / あかい / えんぴつ / です / 。
こうなりますね。
さて、我々のように日常的に日本語を使っている人間であれば特に問題なく単語に分割できるでしょうが、これをコンピュータでやりたいとなるとどうでしょう。
日本語というのは改めて見てみると、明確な区切りとなる目安がなく、文法も比較的自由で、活用形だったり造語だったり口語やスラングなど変則的な単語が乱れ飛ぶ……
そうです。日本語の形態素解析というのは、非常に難しいものなのです。
現在の日本語の形態素解析は、コンピュータに単語を判別するための辞書データを登録した上で、上手く解析するための様々なアプローチ……例えば
・考えうる区切り方を全て抜き出して、品詞の繋がり方などから一番それっぽい区切り方を選ぶ
・「ここで区切ると前後が適切な言語になるか」を逐一チェックしていく
などのような処理を実装した、いくつかのアルゴリズムがあるとされています。
現在では高い精度で形態素解析をすることができますが、先述のとおり日本語があまりにも変則的で自由な言語であるため、100% 完璧に正しく形態素解析をできる保証はない、というのが現状です。
色々ごちゃごちゃとお話しましたが、Solr で日本語を使う上では、
・なんか単語に分けてるらしい
・単語に分けるために形態素解析って考え方を使うらしい
・形態素解析には辞書データってものが必要らしい
・確実に意図した通りの単語に区切れるとは限らないらしい
という点を覚えておいてください。
余談ですが、例えば英語だと同じスペルでも違う品詞だったり全く違う意味を持つ単語が多数あるため、単語に分割した後の適切な意味を判定するステップが難しかったりするなど、それぞれの言語で違った自然言語処理の難しさがあったりします。
■Solr のインデックス作成の様子を見てみる
前置きが長くなりましたが、最初にお話した Solr のインデックス作成 (=インデキシング) がどのように行われるか見てみましょう。
Solr ドキュメントの登録時には、フィルタと呼ばれる一連の処理を複数組み合わせて、その処理結果をインデックスとして登録します。
フィルタはフィールドごとに組み合わせ方を設定することができます。
また、検索時にも設定した組み合わせでフィルタの処理を行った結果を、実際の検索ワードとして使用します。
フィルタにはデフォルトで用意されているものだけでも様々な種類がありますが、一例としては
・文章を単語に分割して品詞を特定する
・単語を基本形に戻す
・半角文字を全角文字に直す
・助詞・助動詞・代名詞など検索に適さない要素を削除する
などのようなものがあります。(ここで形態素解析の概念を使っていますね)
前回見た Solr の管理画面で実際のインデキシングの処理の様子を確認することができるので、今回もデモ用環境を使って試してみましょう。
デモ環境の立ち上げは以下のコマンドで、
## 前回の環境を消してしまっている場合 $ podman run -dt --name test-solr -p 8984:8983 solr solr-demo ## 前回の環境から続けて試す場合 $ podman start test-solr
管理用の WebUI はブラウザで以下のアドレスにアクセスすれば OK でしたね。
http://(IPアドレス or ホスト名):8984/solr
WebUI にアクセスできたら、「プルダウンから “demo” を選ぶ」→「Analysis」の順に遷移しましょう。
この画面からインデキシングの処理のテストができます。
今回は “Analyse Fieldname / FieldType” を、デフォルトで用意されている日本語向けの設定である “text_ja” にして試してみましょう。
画面上部の入力部分にテストしてみたい文章を入れて、”Analyse Values” ボタンを押下すると、設定されているフィルタごとの処理結果が順に表示されるはずです。
実際にインデックスとして登録される(または検索ワードとして使用される)のは、設定された全てのフィルタを適用した結果となる一番下に表示されているものです。
■うまくいかない例も見てみる
折角なので思い通りにいかない例も見てみましょう。
先の “Analysis” のページで、今度は「うらにわにはにわにわとりがいる。」という文章を解析させてみましょう。
これはご存じのとおり
裏庭 / に / は / 二羽 / 鶏 / が / いる / 。
なので、このとおりになってほしいところですが……
結果はご覧のとおり、「うら / に / わに / はにわ / にわとり / が / いる」と何か鰐や埴輪が生えてきてしまっています。あくまで実験として見るだけなら、ちょっと愉快な感じですね。
ともあれ、このように意図した通りの形になってくれないケースもあり得る、ということは覚えておいてください。
余談ですが、解析させる文章を「裏庭には二羽鶏がいる」と漢字も使った形にしてやれば、大体ちゃんと上手くやってくれます。
意図しない形になってしまう可能性があるのは、あくまで文法として正しい、意図しない分け方がある場合という点も気を付けてください。
■最後に
今回は Solr のカラクリの核である “インデックス” と、インデックスを考える上で必要不可欠になる “形態素解析” という概念についてお話ししてみました。
見てもらった通り、Solr では登録されたドキュメントを単語に分割して “インデックス” を作成するので、例えば登録したデータ (ドキュメント) から「ぶどう」という単語が含まれているものを探す、というような処理に圧倒的に強くなります。
前回似ている部分もあるというお話をした RDB ではこのような機能はないため、同じようなことをしようとすると検索のたびに逐一全てのデータをチェックする必要があり、例えるなら「本の目次から目標を探す」か「その本を全て読みながら目標を探す」かくらいの差が出る、というわけです。
※ RDB でも “LIKE” 句で似たようなことはできますし、文字列検索という限定的な用法以外では原則 RDB のほうが便利な点には留意してください。
ここさえ押さえてしまえば、あとはデータの登録手順を覚えれば Solr を使えると言っても差し支えないはずです。
あとは思い通りにいかなかった場合の対処案などもありますが……そのあたりはまたいずれ。