全文検索エンジンについて調べたので社内LT会で話しました
検索エンジンことはじめ2019/10/2 Makuake LT party #22
View Slide
convtojisibariTwitter: @convtoGithub: convto2
もくじ- 全文検索エンジンとは- 転置インデックス- 非英語圏への対応: n-gram, 形態素解析- 辞書の実装で使われる木構造- 転置リストの実装で考慮すること- インデックス構築- 検索- まとめ
全文検索エンジン
全文検索エンジンを対象にした
たけのこ レシピ驚きのたけのこ!~~~~~~~~~~~~~~~~~~~~~~レシピはこちら~~~~~~~~~~~自炊術~~~~~~~~~~~~~~~~~~~~~~おすすめのたけのこレシピも載せておきます~~~~~~~~~~~n-gramについて~~~~~~~~~~~~~~~~~~~~~~一定の文字長でトークナイズする~~~~~~~~~~~驚きのたけのこ!, 自炊術
全文検索エンジンとは- 複数の文章の全文を対象にした検索エンジン- ElasticSearch, Groonga, Solr あたりが有名- Lucene 系列と Groonga 系列があるっぽい
もくじ- 全文検索エンジンとは- 転置インデックス- 非英語圏への対応: n-gram, 形態素解析- 辞書の実装で使われる木構造- 転置リストの実装で考慮すること- インデックス構築- 検索
インデックス- 素直にすべての文字を舐めて探索してもいいが、負荷が大きい(grep型とか言われたり言われなかったりするらしい)- 事前に検索される形で表を作っておき、計算量が下がるような形で保持することで検索を効率化する
転置インデックス- 「ページ内で使われている単語の表」を「ある単語が使われているページの表」に変換して作ったインデックス- 表の縦と横を変換することを転置というので、日本語では転置インデックスという- 本の索引と論理は同じ
ドキュメント内の単語リストを単語が属するドキュメントリストに変換Document id 単語リスト1 おどろき, の, たけのこ, !, …略2 自炊, 術, ...略単語 Doc1 Doc2おどろき ○ ×の ○ ○たけのこ ○ ○! ○ ×変換例
ドキュメント内の単語リストを単語が属するドキュメントリストに変換Document id 単語リスト1 おどろき, の, たけのこ, !, …略2 自炊, 術, ...略単語 Doc1 Doc2おどろき ○ ×の ○ ○たけのこ ○ ○! ○ ×変換例ポスティング
ドキュメント内の単語リストを単語が属するドキュメントリストに変換Document id 単語リスト1 おどろき, の, たけのこ, !, …略2 自炊, 術, ...略単語 Doc1 Doc2おどろき ○ ×の ○ ○たけのこ ○ ○! ○ ×変換例ポスティングリスト
ドキュメント内の単語リストを単語が属するドキュメントリストに変換Document id 単語リスト1 おどろき, の, たけのこ, !, …略2 自炊, 術, ...略単語 Doc1 Doc2おどろき ○ ×の ○ ○たけのこ ○ ○! ○ ×変換例転置リスト
ドキュメント内の単語リストを単語が属するドキュメントリストに変換Document id 単語リスト1 おどろき, の, たけのこ, !, …略2 自炊, 術, ...略単語 Doc1 Doc2おどろき ○ ×の ○ ○たけのこ ○ ○! ○ ×変換例転置リストの情報を木構造などで持たせて計算量を下げたものが転置インデックス
ドキュメント内の単語リストを単語が属するドキュメントリストに変換Document id 単語リスト1 おどろき, の, たけのこ, !, …略2 自炊, 術, ...略単語 Doc1 Doc2おどろき ○, 1回, 1番目 ×の ○, 2回, 2,N番目 ○, 3回, L,M,N番目たけのこ ○, 1回, 3番目 ○, 1回, N番目! ○, 1回, N番目 ×変換例精度計算やフレーズ一致のためにメタ情報を付与する場合もある
Full text searchengine
Full text searchenginefull text search engine句読点で分離
アジア圏の言語は明確な単語の区切りが少ない- アジアに共通して言えるらしい- ある程度品詞を解釈して分けたり、文字数決め打ちで無理やり単語として分けたりするのが一般的
n-gram- 文字数を決め打ちして分けるパターン- 1,2,3文字分けをそれぞれ uni-gram, bi-gram,tri-gram というらしい- mysql などにも n-gram の機能あって、デフォはbi-gram になっている
全文検索エンジン全文 分検 検索 索エn-gram で分割エン ンジ ジン
n-gram メリデメ- メリット: 一文字ずつずらして単語わけするので、検索もれがない- デメリット: 京都 と調べたときに 東京都 も該当する(東京、京都の2つの単語があるとみなされるため)- デメリット: 単語数が多くなることがおおく、形態素解析に比べて実行が遅くなる可能性が高い
形態素解析- 品詞などで単語分けする- 枯れた実装がそこそこある- 自作するのは無理ゲーだと思う
全文検索エンジン全文 検索形態素解析で分割エンジン
形態素解析 メリデメ- メリット: n-gram に比べて実行が早い可能性が高い- デメリット: 分けられ方によっては検索漏れが発生する場合がある(`たけのこ` が `たけ` `の` `こ` と単語分けされて転置インデックスが構築されたケース、など)
どっちも大事
場合によって使い分けられるようにしとこう- 有名な検索エンジンはだいたいどちらも対応している- ユースケースによって適切な方を使い分けているらしい
ここでいう辞書とは- ポスティングリストの参照を持った node でできた木構造- ポスティングリストはサイズが膨大な場合が多いので、計算量以外にもストレージへの読み書き発行回数なども考慮した木構造がよい
検索エンジン向けの木- B+ tree: B tree の派生で、ノードをファイルシステムのページサイズを意識して管理するのでストレージデバイスとのI/O回数が減る- mysql デフォのストレージエンジンInnoDBはこれ- BKD tree: まだ概要は把握していないが、色々な検索エンジンで実績がある- ElasticSearch などはこれ
辞書と転置リストの関係
単語A単語B単語C単語D...辞書 転置リスト1, 1, 3, 2, 1, 2
単語A単語B単語C単語D...辞書 転置リスト1, 1, 3, 2, 1, 2Doc id, 登場回数, 登場位置などの情報が数値の列として保存されるこの例では 4byte * 6 = 一つのポスティングあたり 24byte
転置リスト実装で考慮すること- 物理的に連続した位置に配置する- ポスティングリストは数字の形式でストレージに書き込むので、数値向けの圧縮をする
ソートして構築する方法- 単語とポスティングのペアをストレージに書き込みしていく- 全部書き込んだら単語のalphabet順にソート- ソート結果を順番にみてポスティングリスト構築
マージして構築する方法- 設定したメモリ上限に達するまでポスティングリストを構築していく- メモリ上限に達したらファイルに書き下ろしてまた次のポスティングリストを作る- 全件探索し終えたら部分的なポスティングリストをマージして最終的なポスティングリストを得る
マージして構築する方法- 設定したメモリ上限に達するまでポスティングリストを構築していく- メモリ上限に達したらファイルに描き下ろしてまた次のポスティングリストを作る- 全件探索し終えたら部分的なポスティングリストをマージして最終的なポスティングリストを得るマージのほうが読み書き回数少なくて一般にはパフォーマンスがよい
マージして構築する方法- 設定したメモリ上限に達するまでポスティングリストを構築していく- メモリ上限に達したらファイルに描き下ろしてまた次のポスティングリストを作る- 全件探索し終えたら部分的なポスティングリストをマージして最終的なポスティングリストを得るマージのほうが読み書き回数少なくて一般にはパフォーマンスがよいカーネルは投機読み込みや遅延して読み取りマージなどブロックデバイスのI/O補助があるため、ソートでも問題ないケースもありそう
ブーリアン検索- AND OR などの論理演算子で要素をつなげて検索すること- 文字で論理操作を受け取れるようにして、実装で配列などの操作に変換すれば対応できる
関連度計測- 出現回数、出現位置などのメタデータを使ってを使って関連度を図って返す、などもできる- 出現クエリが存在しなくても関連度はわかるが、走査対象のデータが全件になるので要件によってトレードオフ
まとめ- 検索エンジン用語や使われる要素技術などざっくりとした外観を学んだ- 次回はホビープロジェクトを引っさげて発表したい
- プレゼンテーションテーマは SlidesCarnival の ヨークプレゼンテーションテンプレート を利用していますクレジット表記
ご清聴ありがとうございました