『検索システム 実務者のための開発改善ガイドブック』を読んだ

https://www.lambdanote.com/products/ir-system

『検索システム -実務者のための開発改善ガイドブック』を読んだ

### 感想

一応実務で全部検索エンジンは複数実装しており、ランキングのためのスコア調整やフリガナ検索、N-gramを使ったインデックス構築など行っていたものの、検索という分野に対しての体系的な知識がなく、次の検索システムを構築する際に学び直したいと思ったので手に取った。
ググったときにサジェストで出てくるアレはクエリ提案と呼ばれるものなんだよ〜みたいなところから、改善のためにどういうデータを取るのが良いのか、検索クエリをクラスタリングする際のアルゴリズムまで一通り知ることが出来てよかった。
とはいえ、アルゴリズムの具体的な式の部分はちょっと理解を諦めた部分が多いが…
最初からガチガチのものを作るよりはありもののライブラリを使って手触りを感じながら進めていくほうが良いと思うので後々の課題にしておく

### 読んでいた時のメモ

#### p.37 高次元密ベクトルのインデックス
画像、音声、動画みたいなデータの検索は一旦ベクトルデータにして近似最近傍検索を解くことで実現されている。
ライブラリも色々あって、今の所使う予定はないけど見るのも面白そう

https://qiita.com/wasnot/items/20c4f30a529ae3ed5f52

#### p.43 ステミング
表記ゆれへの対処のために語形の変化を取り除くことをステミングという。
日本語だと`読んだ` `読もう` `読みます`を全て`読む`として扱う。名前忘れてたのでメモ

https://note.com/makeadent/n/ne23a367d0eeb

#### p.49 Unicode正規化
`が`と`か + ゛` を同じものとして検索できるようにする。
ESだとicu_normalizerとかでやってた

https://qiita.com/ikawaha/items/79fdd69c524310db065e

#### p.55 AND検索のアルゴリズム
ソート済みのポスティングリストの先頭からカーソルを進めていって、全てのタームを含むドキュメントを検索結果に加えていっている

#### p.74 スキップリスト
単方向連結リストを階層的に重ねたデータ構造を用意することでポスティングリストの走査にかかる時間を短縮できる。
電車の各駅、急行みたいな例えがわかりやすかったかも

#### p.88 クローリングとスクレイピング
クローリングはサイトを巡回してデータを貯めること、スクレイピングはHTMLとかからタグを除去したりして情報を抽出すること
ごっちゃになってた感じがするのでメモ

#### p.93 キーフレーズ抽出 固有表現抽出
N-gramより高度なフレーズ抽出として、キーフレーズ抽出があり、辞書に登録されていないような専門用語を抽出できる
ライブラリも色々あるよう

http://gensen.dl.itc.u-tokyo.ac.jp/pytermextract/#:~:text=termextract%E3%81%AF%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89,%E6%80%A7%E3%81%8C%E9%AB%98%E3%81%8F%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%EF%BC%89%E3%80%82

https://www.ogis-ri.co.jp/otc/hiroba/technical/similar-document-search/part5.html

固有表現抽出は、テキストデータから事前に定義しておいた分類(人名、組織名とか)に固有表現を抽出すること(?)
こっちは機械学習が一般的らしい

https://www.intellilink.co.jp/column/ai/2021/120700.aspx

#### p.95 測地系は日本で2種類が存在している
日本測地系と世界測地系があるので気をつけないといけないかも
今は国土地理院で世界測地系を使うよう定められているとのこと

#### p.101 フィードバックを提供する
ユーザーは検索対象となる分野に詳しくない、また自分が何を本当に検索しているのかが分かっていないことが多い、ということを想定して検索ごとにクエリ提案やオートコンプリートのようなフィードバックを提供する必要がある

#### p.102 検索結果が0件のときの表示を工夫する
検索結果が0件だとユーザーが離脱する可能性があるので、0件だったときのページを工夫する(クエリ提案など)必要がある

#### p.108 文書サロゲート
検索結果のタイトルの下に出てくる要約とか日付の集合を文書サロゲートと呼ぶ
確かにこれとかハイライトとかないとどの程度クエリと関連してるかがパッと分からないので必要だと思った
逆にタイトル中に検索クエリが含まれているときはそれほど重要でない

#### p.115 Googleの検索インターフェースを参考にしない
あれぐらいシンプルなものを目指すのではなく、サービスに合わせて色々なナビゲーションのための機能を実装するほうがコスパがいいはず

#### p.117 ESのAggregationでファセット用のメタデータを取得する
queryと一緒に使うことで絞り込みを行った上で、カテゴリごとの件数を取得できる

https://kazuhira-r.hatenablog.com/entry/20160212/1455288439

https://qiita.com/NAO_MK2/items/9f0a04d4042503579082

#### p.126 タグとキーワードを分ける
同じ単語でもキーワード検索としてのものなのか、タグとしてのものなのか区別を付けたほうがよい
例えば`#全文検索` とかってするとタグだと明示することができる

#### p.127 検索履歴の保存
ユーザーが再利用したいと思うような項目に絞って検索履歴の保存を行うとよい

#### p.133 AND OR 検索のフォロー
AND検索とOR検索で適合率、再現率への影響が反対なのでそれに合わせたフォローをしてあげる必要がある
また、複数キーワード・タグの入力時に、デフォルトをユーザーに伝えそれを変えられるようにしておいたほうがよい

#### p.170 フリーズドインデックス
評価のために本番のデータセット作成時に同じインデックスを保存しておく、これをフリーズドインデックスという

#### p.172 検索クエリの分析要素
最低限下記の項目で集計する
- 特定の期間における検索回数のランキング
- 期間比で増えた検索クエリのランキング
- ヒット数がゼロ件で終わった検索クエリのうち検索回数が多かったもののランキング

#### p.187 がっかり体験指標
ゼロ件マッチ、再検索、離脱・直帰などの件数を確認することでユーザーの検索体験を測定する

#### p.191 インターリービング
ランキングアルゴリズムの検証でA/Bテストよりも少ないサンプルサイズで実験できる手法としてインターリービングがある
ランキングを混ぜてどちらのクリック数が多かったかを集計することでランキングの優劣比較ができる

#### p.207 暗黙的なクエリ提案
こういうやつ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215937/877aa713-98e3-c09a-aa46-547137ae1a8d.png)

勝手にクエリを書き換えているのでユーザーが入力した元のワードでも検索できるようにしてあげる

#### p.210 スペル修正
暗黙的に修正されるケースもあるが、その場合もユーザーに分かるようにしたり、元のクエリでの検索結果とランキングを混ぜて表示する
オートコンプリートと合わせて使うときは、元のクエリにオートコンプリートがあればそれと混ぜて表示、なければスペル修正されたものに対してオートコンプリートを行い、合わせて表示する

#### p.213 関連検索提案の遅延読み込み
関連検索提案はユーザーが既にほしい情報を得られたときは不要なので、一番下にスクロールしたときに呼び出しを行うことによってリクエスト数を減らすことができる

#### p.215 共起
> ある単語に他の語が同時に出現すること。 

https://ja.wiktionary.org/wiki/%E5%85%B1%E8%B5%B7#:~:text=%E5%90%8D%E8%A9%9E&text=%E3%81%82%E3%82%8B%E5%8D%98%E8%AA%9E%E3%81%AB%E4%BB%96%E3%81%AE,%E8%B5%B7%E3%81%99%E3%82%8B%E3%81%A8%E3%81%AF%E8%A8%80%E3%81%88%E3%81%AA%E3%81%84%E3%80%82

クエリ提案の項目で出てきた

#### p.222 クエリ提案の精度
あんまり理解できてないのでそのうち再読

#### p.229 検索結果のクラスタリングではセントロイドが「検索者が探しているアイテムを見つけ出すためのガイド」として意味をなさない
セントロイド、が分からなくてちょっと理解できなかった

#### p.238 検索のゴール
検索クエリを案内型、情報収集型、取引型に分類することでゴールを把握する

#### p.242 機械学習をクエリの分類に使う

#### p.273 クエリの再定式化
再読予定

#### p.276 SearchTemplate
ESでよく使うクエリを予め登録しておくことによって簡単なリクエストで複雑なクエリを呼び出すことができる

https://itdepends.hateblo.jp/entry/2020/05/26/234011

#### p.287 LMDirichlet
言語モデルによる類似度計算をしたいときに使用するよう定義できる

https://www.elastic.co/guide/en/elasticsearch/reference/master/index-modules-similarity.html

#### p.289 boost
ランキングのためのスコア計算のときにどの項目を重く見るか設定できる、これはよく使ってた
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/mapping-boost.html

#### p.298 ランキング学習プラグイン
機械学習によって得られたランキングモデルをESに組み込むことができる

https://techblog.zozo.com/entry/elasticsearch-learning-to-rank-plugin

### 終わりに
まとめていて思ったが後半の方は気合で読み飛ばしただけにかなり内容がふわっとしている…
まぁ次の実装時にやりたいこと、できそうなことは多く見つけられたので、より高度な改善を行うときに読み直すようにしたい