はてだBlog(仮称)

私的なブログど真ん中のつもりでしたが、気づけばWebサイト系のアプリケーション開発周りで感じたこと寄りの自分メモなどをつれづれ述べています。2020年6月現在、Elasticsearch、pandas、CMSなどに関する話題が多めです。...ですが、だんだんとより私的なプログラムのスニペット置き場になりつつあります。ブログで述べている内容は所属組織で販売している製品などに関するものではなく、また所属する組織の見解を代表するものではありません。

Elasticsearchの便利機能のユースケースmemo(便利機能5選)

はじめに

タイトル負けしているが以下の5つ。

(注:Elasticsearchがタイトル負けしているわけではなく、まとめの内容がデス)

  1. More Like This Query
  2. Term Vectors API
  3. significant terms
  4. percolator
  5. Field Collapsing

それぞれどんな機能か、ユースケースの例としてどのようなものがあるかあげてみた。

(1)More Like This Query

なんぞや

同じ単語を含む文章は類似文書というアイディアのもと、ドキュメントのIDと類似判定対象とするフィールド名を投げると、類似文書の一覧を返してくれる。

medium.com

ユースケース

  1. なんちゃって協調フィルタリング

(2) Term Vectors API

なんぞや

類似文書検索。

More Like This Queryとの違いは次↓にまとめてくださっている。

speakerdeck.com

ユースケース

More Like This Queryと同じだが、手間をかければもっとリッチなことや精度を上げたようなことができるというところだろうか。

5選のうち、2選がカブってしまった気がする。

(3) significant terms

なんぞや

検索結果のドキュメント群から検索語に関連して特徴的なワードの一覧を返す。 5つの計算手法があるらしい。 その内の一つは、

codezine.jp

によると

JLH = 絶対割合変化 × 相対割合変化

 絶対割合変化 = 指定範囲での出現割合 - 全体での出現割合

 相対割合変化 = 指定範囲での出現割合 ÷ 全体での出現割合

とのこと。

これ自体はピンとこなかったが、書籍によると、「車種の検索をしたら、広島県ではマツダ車が特筆して多い...」のような例を見かけた。

------- 要追記 ---------

ユースケース

特徴的なワードの選択基準次第のところもあるが、

  1. インデックスの全ドキュメントを検索して、インデックス全体を特徴付けるワードの一覧を取得。これをドキュメントのカテゴリ分けワードとする。MECE的なものにはならないかもしれないことに注意。
  2. 前項と同じような方法でタグクラウド生成
  3. 話題のニュースのキーワード一覧。特徴的なワード...ということからするとこれがもっともイケている使い方か。引用のリンク先の例のとおり、出力された特徴的なワードから無駄なワードを除去するしかけが重要なのかな。
  4. 初回検索ワードと関連性の強い絞り込みファセットの実現。... って元の定義のまんまだけど、無印のファセットは、ある検索結果のドキュメント一覧のなかから、規定の属性でグループ化したものを一覧表示するが、significant termsの場合は、初回検索ワードとの関連がより強いワードがドキュメント内容からあぶり出されるので、検索サービス側が予想していないパターンの検索行動でもある程度動的にかつ利用者の探している情報にマッチしたドキュメントに誘導できるようなファセットを提示できるような気がする。

(4) percolator

なんぞや

通常、検索語にマッチするドキュメントを検索するが、percolatorはドキュメントを与えると、それにマッチする検索条件を返してくれる...??? !?

むむ。分からん。

本家の英語の説明も、皆さんの解説を読んでもよく分からなかったが、なんとか分かったので自分なりに言い直してみる。

まず、percolatorでどういう検索条件でどういうリザルトが得られるかはさておく。

percolatorの実現にあたって、Elasticsearchでは

  1. 検索クエリ自体をインデックスに登録できる。
  2. この検索クエリには、クエリID = "4WDの車"のような名付けができる。
  3. 別の検索クエリをインデックスに追加登録する。
  4. 追加登録したクエリのクエリIDは、"オープンカー"というものにしたとしよう。

ここまでが前準備。

続いて、実際の使い方、

  1. percolatorのクエリに、ある車種の解説がしてあるドキュメント(このドキュメントのID=12345としよう)を指定する。
  2. percolatorのクエリは、リザルトとして、クエリID="4WD"を応答してきた。裏返して言うと、通常のドキュメント検索において、クエリID="4WD"の検索条件で検索した場合に、ドキュメントID 12345のドキュメントがhitするという関係だ。

... ということになる。

通しで見ると、ドキュメントの特徴やカテゴリ(カテゴリ名をAとしよう)にあたるものを検索クエリQAで表記する。この検索クエリで、あるドキュメントがヒットすることが確かめられた。すなわち、このドキュメントはカテゴリAである。

... というのがpercolatorの仕組みを使って得られる演算である。

ここまで書いて見ると、勘の良い人向けには、わざわざここまで書く必要がなかった気がしてくるが、なかなか分からなかったんだよね〜。

前段の「クエリをインデックスに登録する」というのが他のクエリのユースケース同様、単なるデータの仕込みだと思いこんでいると、percolatorクエリで検索する意図が見えづらくなってしまう。percolatorクエリは、この場合、SQLで言うと、EXISTS句みたいな位置付け。

ユースケース

  1. ドキュメント追加時や内容更新時にカテゴリ分けを行う。(基本的には全てこれのバリエーションのような気がする。)
  2. percolatorに投げるものをいろいろ変えてみる。カテゴリ分け→ネガ・ポジの判定などにとらえ直してみる。ユーザ属性を投げてプロフィール分析したり、検索キーワード自体を投げて、興味分析をしたり。もちろん、チューニングは必要。禁止ワードが含まれていないか、お題に該当するテキストや単語がある程度含まれているかの雑なチェックもできるかも。
  3. キューなどに流れてくるドキュメントやドキュメントに限らずログなどをpercolatorにかけて、リザルトに応じて、通知やアラートを送る。S3のトリガーと相性が良さそうだね。判定ロジックを外出しできるし、全文検索が織り込まれているESのクエリでの判定なので、よく鍛えられた機械学習ほど精度は高くないものの、通常のif文や論理式での実装に比べると、人の目に近い一方で一定の判定ロジックで仕分けできるのが非常に良いと思う。

この他、なるほどな〜と思ったのがこちら。

techlife.cookpad.com

品川区のエリアのカクカクを表す緯度経度ポリゴンの範囲検索のクエリを登録。港区など他のエリアも登録。例えば、品川駅の緯度経度をpercolatorにかけると、港区であることが判定できるという寸法。

(5) Field Collapsing

なんぞや

検索結果のリストを指定のフィールドでグループ化して階層化した検索結果にしてくれる模様。 Aggregations全般が、件数を数えたり、分類相当を返すのに比べて、これ自体は検索結果のhitsをinner_hitsの2段階にしてくれるという違いだと考えれば良いのだろうか。ちゃんと説明するには例が必要だが、毎度のとおり人様のページにリンクする。

ElasticsearchのField Collapsingで検索結果をグルーピングする | ニフティものづくりブログ

ユースケース

  1. よく似た検索結果を省略するのに使えるかもしれない。が、Field Collapsingのものと無印のものの検索結果のJSONをページのHTML編集方法をうまく共通化するのがめんどくさそうなので少し腰が引けてしまう。(共通化自体は昨今のフレームワークやらなんやらでさほど難しくないかもしれないが、今回は共通化されているパーツをhitsに対して使うのかinner_hitsについて使うのかを判定するところがアドホックで場当たり的な処理方法になりそう。)

さいごに

膨らませ不足感はあるが、適宜追記することとしよう。

別観点でまとめ直して理解を深めたい。

例えば、Elasticsearchの標準機能を活用した「おすすめのお店一覧」のいろんな実現バリエーションというのが面白いかも。