Azure Cognitive Search を使って簡単ナレッジマイニングハンズオン（日本語対応）

# はじめに
組織内に貯まっている大量な構造化・非構造化データから、新たな価値を見出すためのフルマネージド全文検索サービスである [Azure Cognitive Search](https://www.youtube.com/watch?v=9GcjFofXdd0) を使えば、誰でも簡単に AI 搭載検索エンジンを開発することができます。今回はノーコード、画面上の操作だけで簡単に検索インデックスを作成する手順をハンズオン形式でご紹介します。

# 2021/07/01 Updates🎉
Azure Cognitive Search の検索機能を重点的に理解することにフォーカスを当てた[新たなワークショップ](https://qiita.com/nohanaga/items/2a90539f7667fa9e486a)を公開しましたのでこちらもご覧ください。

# 目次
1. [Azure Cognitive Search とは](#Azure-Cognitive-Search-とは)
1. [検索サービスの作成](#検索サービスの作成)
1. [Azure Blob Storage の作成](#azure-blob-storage-の作成)
1. [インデックスの作成](#インデックスの作成)
    1. [データに接続](#1-データに接続)
    1. [コグニティブ スキルの追加](#2-コグニティブ-スキルの追加)
    1. [インデックスのカスタマイズ](#3-インデックスのカスタマイズ)
1. [インデクサーの作成](#4-インデクサーの作成)
1. [インデクサーの実行](#インデクサーの実行)
1. [スキルセットの修正](#スキルセットの修正)
1. [デモアプリの作成](#デモアプリの作成)
1. [参考リンク](#参考リンク)

#Azure Cognitive Search とは
![011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/27424344-b09f-d65c-2631-6952bc8da670.jpeg)

Azure Cognitive Search は、クラウド上に貯まった様々なデータから、Microsoft の最先端の AI 技術を使って様々なメタデータを抽出し、それを検索インデックスにして検索できるようにするサービスです。構造化データや内部解析可能なドキュメントファイルから中身を取り出すことは簡単ですが、Azure Cognitive Search では上図のような [Cognitive Skill](https://docs.microsoft.com/azure/search/cognitive-search-predefined-skills) や [Custom Skill](https://docs.microsoft.com/azure/search/cognitive-search-custom-skill-web-api) を使って取り出す能力を拡張できるというのが大きな価値となります。

私が Azure Cognitive Search の概要を 30 分にまとめた[ビデオ](https://www.youtube.com/watch?v=jOzA48ZDyC4)がありますので、必要であればご覧ください。

#検索サービスの作成
[Azure Portal](https://portal.azure.com/) にログインし、新規でリソースグループを作成します。
作成したリソースグループの中に、検索サービスを追加します。マーケットプレイスで、「Azure Cognitive Search」と検索してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/2e668bc1-62e6-e835-9d98-328d0c4a505b.jpeg" width=450 /> 

新しい検索サービスウィザードで、必要事項を入力します。価格レベルでは、必要なプランを選択します。こちらの[料金表](https://azure.microsoft.com/pricing/details/search/)も参考にしてください。無料プランで始めることもできます。

![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/5e217c33-029f-daca-66ae-4c2ad00486d2.jpeg)

デプロイが完了し、作成された検索サービスをクリックすると、以下のようなポータル画面が表示されます。

![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/44ff810c-d587-ea6f-ebe3-9acd1f47a3cc.jpeg)

このポータル画面上でインデックス、インデクサー、データソース、スキルセットの作成や編集を行うことができます。

#Azure Blob Storage の作成

ここで一旦リソースグループに戻り、検索対象のデータを保管するためのストレージアカウントを追加します。
マーケットプレイスで、「ストレージ」と入れて検索してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/5b34e601-71e4-83f5-5254-ca1b880e3656.jpeg" width=450 /> 

今回は、ドキュメントファイルや画像データを保管できるシンプルな Blob Storage があればよいので、以下のように設定します。

![003a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/aa29dbaf-ee11-b32c-c548-9026c4d945bf.jpeg)

ストレージアカウントのデプロイが完了しましたら、ストレージアカウントの左メニューから「コンテナー」を選択し、以下のように新しいコンテナーを作成します。

![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/90dc1fd8-ca0d-b356-f836-494639d95326.jpeg)

作成したコンテナーの中に入り、サンプル画像ファイルを 1 枚アップロードします。PDF やワード、エクセルなど他にも検索してみたいファイルがある方は、こちらにアップロードしてください。ファイルが大量にある場合は、[Azure Storage Explorer](https://azure.microsoft.com/features/storage-explorer/) を使ってアップロードすることもできます。
サポートしているファイルフォーマットの一覧は[こちら](https://docs.microsoft.com/azure/search/search-blob-storage-integration#supported-content-types)を参照してください。

![吾輩は猫である画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/721575d6-15f0-9470-accd-716b7299023a.png)

このハンズオンでは、青空文庫の「[吾輩は猫である](https://www.aozora.gr.jp/cards/000148/files/789_14547.html)」のスキャン画像を利用します。

![screencapture-ms-portal-azure-2021-04-27-01_04_05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/b687d525-1a7a-31ba-d34d-b52aba216a0b.jpeg)

#インデックスの作成

それでは、先ほど作成した Blob Storage 内を検索するためのインデックスの作成を行います。

##1. データに接続

![008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/a03cd43d-6228-5b0e-7c9e-c674be54312d.jpeg)

検索サービスのポータルに戻り、ツールバーの「データのインポート」をクリックします。

![009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/bce37d58-a3c4-7a10-2d50-6019d69f8239.jpeg)

データのインポートウィザードでは、データソースに「Azure BLOB ストレージ」を選択し、データソース名を入力し、「既存の接続を選択します」リンクをクリックします。

ちなみに Azure Cognitive Search が対応しているデータソースには、Azure Cosmos DB や Azure SQL Database などがあり、2021 年 3 月には、[SharePoint Online (Preview)](https://docs.microsoft.com/azure/search/search-howto-index-sharepoint-online) にも対応しました。サポートしているデータソースの一覧は[こちら](https://docs.microsoft.com/azure/search/search-indexer-overview#supported-data-sources)にあります。
![screencapture-ms-portal-azure-2021-04-27-01_06_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/04f58468-10ae-b9fd-4f65-b645500d9503.jpeg)

すると、ストレージアカウント選択画面が開くので、左メニューから、先ほど作成したストレージアカウントを選択し、ファイルが保存されているコンテナーを選択します。

先ほどのデータのインポート画面のコンテナー名に、選択したコンテナーが自動で入力されたことを確認し、「次：コグニティブ スキルを追加します（省略可能）」ボタンをクリックします。

##2. コグニティブ スキルの追加

ここでは、検索インデックスをより豊かにするための、AI エンリッチメントを追加できます。AI エンリッチメントでは、[Azure Cognitive Services](https://azure.microsoft.com/services/cognitive-services/) の機能が使われるため、基本的に[利用料がかかります](https://docs.microsoft.com/azure/search/cognitive-search-attach-cognitive-services)。ただし今回はハンズオンですので、「Cognitive Services をアタッチする」では設定を行いません。そうすると自動で無料 (制限付きのエンリッチメント) リソースがセットされます。ただしインデクサーごとに、1 日あたり 20 ドキュメントまでのエンリッチに制限されます。 

![010a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/a419e41c-27d1-6563-da57-afa383e7f922.jpeg)

今回は、上図のようにチェックしてください。サンプル画像から、OCR を使って文字を読み取り、その文字に対して、エンティティの抽出等のテキスト解析を行います。また写真ファイルをアップロードする場合には、画像認識のスキルを有効化しておくことで画像からメタデータを抽出できます。

チェックが完了したら、「次：対象インデックスをカスタマイズします」をクリックします。

##3. インデックスのカスタマイズ

![sg001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/ae296914-b624-f5f8-f55f-9bb04d5506a7.jpeg)

対象インデックスのカスタマイズウィザードでは、検索インデックスとして格納するフィールドごとに、取得可能、フィルター可能、ソート可能、ファセット可能、検索可能、アナライザー、サジェスターという一般的な検索インデックスとしての設定を行う必要があります。各機能の説明は冒頭の動画でするとして、今回は上図のようにチェックしてください。

アナライザーにはデフォルトで、標準 Lucene アナライザーがセットされていますが、これは西洋語用のもので日本語の解析に対応していませんので、日本語の解析が必要なフィールドには、日本語アナライザーを設定する必要があります。日本語のアナライザーには Lucene アナライザーと、Microsoft アナライザーの [2 種類](https://docs.microsoft.com/azure/search/index-add-language-analyzers#comparing-lucene-and-microsoft-analyzers)が用意されていますが、それぞれトークナイズの手法に違いがあるので、要件によって選択するようにしてください。

 * `content`: ドキュメントの本文が格納されます。文字解析可能なドキュメントはここに値が格納されます。中身は日本語として解析される必要があるため、[日本語 Microsoft アナライザー](https://docs.microsoft.com/azure/search/index-add-language-analyzers)をセットします。
 * `metadata_storage_name`: ドキュメントのファイル名です。今回は検索結果に表示するために、取得可能にチェックします。
 * `people`: [人物エンティティ](https://docs.microsoft.com/azure/search/cognitive-search-skill-entity-recognition)が格納されます。日本語で解析できるようにします。
 * `organizations`: [組織エンティティ](https://docs.microsoft.com/azure/search/cognitive-search-skill-entity-recognition)が格納されます。日本語で解析できるようにします。
 * `locations`: [位置エンティティ](https://docs.microsoft.com/azure/search/cognitive-search-skill-entity-recognition)が格納されます。日本語で解析できるようにします。
 * `keyphrases`: [重要語](https://docs.microsoft.com/azure/search/cognitive-search-skill-keyphrases)が格納されます。日本語で解析できるようにします。
 * `language`: [言語検出スキル](https://docs.microsoft.com/azure/search/cognitive-search-skill-language-detection)による言語推定結果が格納されます。ISO 3166-1 alpha-2 の 2 文字の国番号が入るのでアナライザーはデフォルトにしておきます。
 * `merged_content`: ドキュメントの本文と、OCR による読み取り結果をマージした結果が格納されます。日本語で解析できるようにします。Suggester にチェックをいれることで、このフィールドが[オートコンプリートとサジェスト機能](https://docs.microsoft.com/azure/search/index-add-suggesters)対応になります。
 * `text`: [OCR スキル](https://docs.microsoft.com/azure/search/cognitive-search-skill-ocr)の読み取り結果が格納されます。日本語で解析できるようにします。
 * `layoutText`: [OCR スキル](https://docs.microsoft.com/azure/search/cognitive-search-skill-ocr) で抽出されたテキストと､そのテキストが検出された座標を記述した配列が格納されます。日本語で解析できるようにします。
 * `imageTags`: [画像解析](https://docs.microsoft.com/azure/search/cognitive-search-skill-image-analysis)して画像のコンテンツに関係する単語の一覧が格納されます。今回は設定省略します。（日本語にも対応しています）
 * `imageCaption`: [画像解析](https://docs.microsoft.com/azure/search/cognitive-search-skill-image-analysis)して画像のコンテンツを説明するための文が格納されます。今回は設定省略します。（日本語にも対応しています）

フィールドごとに一つ一つ設定していくのが面倒くさいと思った方はご安心ください。これらの設定はすべて JSON 形式でエクスポートできますので、JSON 形式で編集などをして、[Postman](https://www.postman.com/) を使って REST API 経由でインデックスに登録することができます。こちらは別記事にて紹介いたします。

設定が完了しましたら、「次：インデクサーの作成」をクリックしてください。

##4. インデクサーの作成

最後にインデクサーの作成を行います。インデクサーは、外部データソースから検索サービスの検索インデックスにドキュメントとコンテンツを転送するための、自動化されたワークフローを提供します。ここでは、データをプルする頻度をスケジューリングすることや、検索対象のファイルに対する処理の各種設定を行うことができます。

![013.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/bfdfd894-fafa-3afa-4d3e-9e671ef9baae.jpeg)

今回は、`metadata_storage_path` をドキュメントキーとしているため、`Base-64 エンコード キー` にチェックを入れておきます。
また、スケジュール設定はせず、デフォルトの `1度` にセットしておきます。

設定が完了したら、「送信」ボタンをクリックします。

#インデクサーの実行

さきほどインデクサーの実行スケジュールを `1度` にしておいたため、作成直後に自動的に 1 度だけ実行されます。

![014.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/901e8e35-edf6-937b-b4e3-13b3090e1524.jpeg)

「インデクサー」タブの対象インデクサーのステータスが `実行中` となっていると思います。これが `成功` となればインデキシング完了です。

#インデックスの検索

作成したインデックスの中身は、ポータル上で検索することができます。

![015.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/20d9fdad-53c8-39b0-78d0-491d334a2444.jpeg)

「インデックス」タブをクリックし、インデックス名を選択します。

![screencapture-ms-portal-azure-2021-04-27-01_11_40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/e5f3a385-5987-efa3-cea0-1c0769f788ee.jpeg)

すると検索エクスプローラー画面が表示されます。ここで、検索クエリーのテストや、実行結果の確認をすることができます。
ひとまずクエリ文字列に何も入れずに「検索」ボタンをクリックしてみてください。全件が検索されます。

文字化け？してるんじゃないかというような検索結果が表示されると思います。これは [OCR スキル](https://docs.microsoft.com/azure/search/cognitive-search-skill-ocr) のデフォルト言語設定が英語になっているため、正常に認識されていないことが原因です。

日本語 OCR 機能を利用しない場合は、ここまでの設定で完了です。PDF やワード、エクセルファイルなどの中身が検索できているかと思います。

開発者の方は、アプリケーションから以下のような検索クエリを発行して検索結果を得ます。検索クエリーの発行のしかたは、[ドキュメント](https://docs.microsoft.com/azure/search/search-query-create)を参照してください。

```
POST https://[service name].search.windows.net/indexes/[index-name]/docs/search?api-version=2020-06-30
{
    "search": "NY +view",
    "queryType": "simple",
    "searchMode": "all",
    "searchFields": "HotelName, Description, Address/City, Address/StateProvince, Tags",
    "select": "HotelName, Description, Address/City, Address/StateProvince, Tags",
    "count": "true"
}
```

#スキルセットの修正

OCR スキルを日本語に対応させる場合は一度ポータルに戻り、「スキルセット」タブをクリックし、スキルセット名を選択してください。

![016.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/1327d189-75f9-1b89-f908-55e17c937a1e.jpeg)

スキルセットは、各スキルの定義とその実行順を JSON 形式で定義したものです。ポータル画面から、閲覧と直接編集を行えます。

![017.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/ea623086-46f7-1d52-c38f-f8cf2358dee0.jpeg)

以下のように、`#Microsoft.Skills.Vision.OcrSkill` の部分の、`defaultLanguageCode` を `ja` に変更し、「保存」ボタンをクリックします。もし OCR したいドキュメントの言語がこの時点で不明の場合、`unk` と設定することで、言語が自動検出されます。

```json
    {
      "@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
       ...
      "defaultLanguageCode": "ja",
       ...
    }
```

保存が完了したら、今度はポータルからインデクサーを開き、「リセット」ボタンを押してから「実行」ボタンを押します。
[リセット](https://docs.microsoft.com/azure/search/search-howto-run-reset-indexers#reset-an-indexer)を行うことで、一度インデキシングされたデータをクリアして、再度インデキシングすることができるようになります。

![018.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/1ce12066-3bd7-3f31-950a-1ac2fabae65a.jpeg)

#インデックスの検索（日本語 OCR）

インデクサーの実行が成功したら、再度インデックスの検索エクスプローラー画面を開きます。

![screencapture-ms-portal-azure-2021-04-27-01_15_05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/1b0626aa-4947-35fb-864f-f9fb51af1651.jpeg)

今度はどうでしょうか？しっかりと `merged_content` や `text` フィールドに日本語で検索結果が入っていることが確認できます。

![screencapture-ms-portal-azure-2021-04-27-01_15_44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/ee708b97-699e-453d-79dd-74af8c7f361a.jpeg)

`keyphrases` フィールドにも単語が入っていることが分かります。

うん、分かるのですが、なんかおかしい。。。

全然日本語じゃないし。。。しかも空白が入ってて、うまく検索できないし。

はい、2021 年 4 月現在、日本語 OCR には[コチラ](https://qiita.com/nohanaga/items/988cdb7b15b2050b364b)で解説しているような問題があるんです。これを迂回するためのトリックはリンク先にて紹介しているのですが、そこでは**カスタムスキル**という機能を使います。

[カスタムスキル](https://qiita.com/nohanaga/items/986887b82cf76dc7b0a9)というのは Azure Cognitive Search の重要な機能の一つでして、オリジナルの検索インデックスを作るために必要となります。仕組みとして、インデクサーがスキャンしたデータを外部 Web API に飛ばすことができるので、外部にテキスト分類機械学習モデルや要約モデル、画像分類モデルなどをデプロイしておけば、オリジナルの AI エンリッチメントパイプラインを構築することができます。

この後、カスタムスキルを使って上記日本語 OCR 問題を何とかするハンズオンを用意いたします。テキスト処理するだけのめちゃくちゃシンプルな作りなので、カスタムスキルの学習用として有用かと思います。

# デモアプリの作成

Azure Cognitive Search の機能は基本的に REST API での提供となりますが、デモのために簡易的な Web 検索フロントエンドを作成してくれる機能があります。検索エクスプローラー画面の上にある「デモ アプリの作成」ボタンをクリックしてください。

![screencapture-ms-portal-azure-2021-04-27-15_34_43.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/ed60d27c-2ce7-0e81-9cd4-d509adc4f514.jpeg)

デモ アプリの作成ウィザードでは、検索画面に表示するフィールドの設定を行うことができます。
まずは検索結果画面に表示したいフィールドを選択して「次へ」をクリックします。

![screencapture-ms-portal-azure-2021-04-27-15_14_11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/75344ff2-3e4e-8228-e1fb-92a1a7c33f35.jpeg)

サイドバー設定では、検索画面の左側に表示されるフィルター項目を設定することができます。この設定を行えば、[ファセットフィルター](https://docs.microsoft.com/azure/search/search-filters-facets)機能のデモをすることができます。

![screencapture-ms-portal-azure-2021-04-27-15_34_59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/7a9089fc-d92a-84be-8e4f-f4551bc1ac12.jpeg)

[インデックスのカスタマイズ](#3-インデックスのカスタマイズ)セクションで、Suggester の設定を行っていたので、この画面でサジェスト対象のフィールド `merged_content` を選択します。

最後に、「デモ アプリの作成」ボタンをクリックすれば、デモ用の HTML ファイルがダウンロードできます。

![sg002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/19ffbe17-93fd-4a72-bed7-0a6200a5b8b2.jpeg)

ローカルでダウンロードした HTML ファイルをブラウザで開き、上部の検索ボックスにキーワードを入れると、このように検索結果が表示されます。簡易的ですが、検索デモとして使うことができます。左ペインは、検索結果に応じて動的に生成される[ファセットフィルター](https://docs.microsoft.com/azure/search/search-filters-facets)です。検索ボックスに何か単語を入力すると、[サジェスト機能](https://docs.microsoft.com/azure/search/search-add-autocomplete-suggestions#suggestions)によるドロップダウンが表示されます。

※注意：HTML ファイル内に接続情報を含んでいるため、このファイルをそのまま運用環境に用いることはできません。

#まとめ
以上で、Azure Portal 上で Azure Cognitive Search のインデックス作成から検索までの流れを体験いただきました。
この次は、[Postman を使った REST API 経由での作成方法](https://qiita.com/nohanaga/items/633b4f3d4ac77154d286)や、[デバッグセッション機能を使ったカスタムスキル開発](https://qiita.com/nohanaga/items/26355ffba58ba4c71c6e)についてご紹介したいと思います。

#参考リンク
[Azure Cognitive Search のカスタムスキルを作成しよう](https://qiita.com/nohanaga/items/986887b82cf76dc7b0a9)
[Azure Cognitive Search のデバッグセッションを使ってカスタムスキルを追加しよう](https://qiita.com/nohanaga/items/26355ffba58ba4c71c6e)
[Azure Cognitive Search の OCR を日本語環境で使えるようにする Tips](https://qiita.com/nohanaga/items/988cdb7b15b2050b364b)
[ナレッジマイニング ソリューションアクセラレーター](https://github.com/nohanaga/azure-search-knowledge-mining)