Azure Cognitive Search 全文検索の新機能セマンティックアンサー・キャプションを表示するデモ

# はじめに

組織内に貯まっている大量な構造化・非構造化データから、新たな価値を見出すためのフルマネージド全文検索サービスである [Azure Cognitive Search](https://www.youtube.com/watch?v=9GcjFofXdd0) を使えば、誰でも簡単に AI 搭載検索エンジンを開発することができます。

今回は[**セマンティック構成**](https://learn.microsoft.com/ja-jp/azure/search/semantic-how-to-query-request?tabs=semanticConfiguration%2Cportal#create-a-semantic-configuration)機能を用いてセマンティック検索をしてみたいと思います。セマンティック構成機能は、2021-04-30-Preview API に新しく追加されたものであり、セマンティック検索クエリーを投げる際の必須パラメーターとなりました。この設定はインデックス内のどのフィールドがセマンティック検索に最も重要であるかをモデルに伝える役割を担っています。詳しい設定方法は[こちら](https://learn.microsoft.com/azure/search/semantic-how-to-query-request?tabs=semanticConfiguration%2Cportal#create-a-semantic-configuration)。
![015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/fdab16a9-8d3b-1837-894b-b8b0a84475a2.png)
Azure Portal から設定する場合は、インデックスの設定の中の「セマンティック構成」タブから行います。セマンティック検索に用いる以下の特定のフィールドを指定します。
 
- タイトル フィールド
- コンテンツ フィールド
- キーワード フィールド

データによってはタイトルやキーワードフィールドが存在しないケースがあるかと思いますが、存在しない場合はコンテンツフィールドのみでも構いません。（ただし指定しない場合セマンティック検索の精度に影響があります）

# セマンティック検索
そもそもセマンティック検索ってどんな検索なの？と思う方も多いと思います。`semantic` とは"意味" とか "意味論" と訳されまして、セマンティック検索というと検索エンジンがユーザーの意図や目的を理解して、検索結果を生成する手法です。これまでの全文検索エンジンで用いられていたトークンの出現頻度をベースにした TF-IDF タイプの全文検索とは異なる検索手法です。

Azure Cognitive Search におけるセマンティック検索とは、セマンティックランキングに加えてセマンティックアンサー、セマンティックキャプション、セマンティックハイライトを加えた機能群のことです。

このセマンティック検索がどういったものかというのは実際に見てみるのが一番です。今回は鎌倉時代の人物の Wikipedia のデータをインデックスに登録して検索してみます。

# セマンティックアンサー
`上総広常が討ち取られたのはいつ` というキーワードで検索をかけます。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/6d14bc26-5a37-28f8-78fc-99ee48df5d43.png)
これまでの検索結果の上にこのような箱が出現しました。
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/9ae1f75f-fab9-a84c-55ff-5f3f4b4701d1.png)
Azure Cognitive Search ではこの箱を「セマンティックアンサー」と呼びます。セマンティックアンサーは、検索ドキュメントから答えにもっとも近いと思われる一節を取り出して表示する特殊なレスポンスです。一節の中でもさらに回答に近いと思われる部分には自動的にハイライトを付加します。実際、ハイライトの箇所は`上総広常が討ち取られたのはいつ` というキーワードの意図・目的に沿った回答を含んでいます。

最近の一般的な検索エンジンでも質問に対するピンポイントな回答が検索結果の一番上に表示されることが増えてきているかと思います。セマンティックアンサーはそのような一般的な検索エンジンで用いられるような機能を誰でも実装できるようにしたものです。
![014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/f741338f-0773-f5c5-515a-aa6e58c69e02.png)
セマンティックアンサーを返すには、回答の言語特性を持つフレーズまたは文が検索ドキュメントに存在している必要があり、検索クエリ自体が質問として提示されている必要があります。モデルは利用可能なコンテンツから一連の潜在的な回答を生成し、十分に高い信頼水準に達するときだけセマンティックアンサーを提案しますので出現しない場合もあります。

# セマンティックキャプション
また、ピンポイントでセマンティックアンサーが得られなった場合でも、セマンティックキャプションと言って、検索結果のタイトルの下に表示されている、関連性の高い検索結果の一部を取り出す（抽出的要約）ことができます。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/fb6be823-b7f7-bb41-0c19-f135f71dd623.png)
このように、セマンティックキャプションに対してもハイライトが入る場合があります。

# セマンティックランキング
今度は既存の頻度ベース（[TF-IDF タイプの BM25](https://learn.microsoft.com/azure/search/index-similarity-and-scoring)）のランキングアルゴリズムと、セマンティックランキングを比較してみましょう。

`上総広常が討ち取られたのはいつ` というキーワードで検索をかけます。使用するアナライザーを `ja.lucene` に統一して検索すると `上総` `広常` `討ち取る` の 3 つのトークンに分割して OR で検索します。左が `queryType:simple`、右が`queryType:semantic` です。
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/0e65dcac-748a-7285-4eec-89036da3462e.png)
ほう、面白い結果が得られました。

Standard Ranking（頻度ベース）では「和田義盛」が 1 位となっていましたが、セマンティックランキングで並べなおした結果「梶原景時」が 1 位に浮上しています。`上総広常が討ち取られたのはいつ` というキーワードの意図・目的に沿った回答を含むドキュメントが 1 位になっていることが分かります。

検索キーワードがより自然文に近づく、より長文になるようなユースケースですと、既存の頻度ベースのランカーが質問意図を解釈せずに単にそれぞれのトークンの出現頻度をベースにランキングを生成してしまうため、欲しい結果が得られなくなる可能性がありますのでセマンティックランキングを利用することをお勧めします。

# 制限
セマンティックランキングは頻度ベースのランカーの次に適用されるランカーでして、検索パフォーマンス的理由から頻度ベースの上位 50 件に対してのみ行われます。つまり、欲しいドキュメントが頻度ベースのランカーの 50 位以内に入っていなければセマンティックランカーの恩恵が受けられません。そのため、データセットによっては既存のランカーに対するチューニングが必要になる場合があります。

# その他の検索例
## 守護・地頭を設置した人
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/81da2e61-e520-5a76-817e-7f7573e27c77.png)
これは面白いですね、セマンティックアンサーが守護・地頭の設置を最終決定した源頼朝ではなく、文官で政策決定に重要な役割を果たした「大江広元」がピックアップされていますね。
![012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/772152ca-70d0-9a19-5ba7-e2945d6d7e32.png)
ランキングを頻度ベースと比較してみると、1 位は同じですが 2 位以降の結果が大きく異なり、セマンティックランキングの方に`守護・地頭を設置した人` の意図を含む「源頼朝」と「北条時政」が上位に浮上しています。

## 三浦義澄って何した人 vs 三浦義澄
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/16b1272d-5fae-a160-8b4e-3522e2e64da6.png)
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/25899346-dbb4-a413-4fc0-9806f794fd46.png)
`三浦義澄` だけでもセマンティックアンサーが出現。ただし、`三浦義澄って何した人` とセマンティックハイライトされる場所が異なります。検索ワードの微妙な違いによって出る出ないが別れたり、意図と違った部分がハイライトされることもあるので、使用するデータセットでの検証が必要かと思います。

## 修善寺に墓があるのは
![013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/f4645950-fb1b-31af-15b8-a1314fe018e1.png)
修善寺に墓があるのは「源頼家」と「源範頼」ですが頻度ベースでは「和田義盛」が 1 位になってしまっています。セマンティックランキングでは「源範頼」が 1 位に浮上していますね。ナイスです。

このような感じでセマンティック検索ではこれまでできなかった全文検索ができるようになるので、ぜひ利用してみてはいかがでしょうか。

# 参考
 - 使用したデータセット：[kamakura_busho.zip](https://github.com/nohanaga/semantic-search-demo/raw/main/kamakura_busho.zip)
 - 検索 UI：[Simple Cognitive Search Tester](https://github.com/nohanaga/Simple-Cognitive-Search-Tester)
 - インデックス構築手順：[Azure Cognitive Search Workshop](https://github.com/nohanaga/Azure-Cognitive-Search-Workshop/blob/main/CreateIndex.md)
 - [Azure Cognitive Search 全文検索の新機能セマンティック検索を試せるデモ](https://qiita.com/nohanaga/items/08ad56fd989f474b5f8a)