はじめに
前回はAzureでOpenAIを使うまでを記事にしましたが、今回は埋め込み機能を使ったQA検索を試してみました。
埋め込み機能の紹介
Azure OpenAIのモデルファミリー
Azure OpenAIでは「GPT-3」「Codex」「埋め込み(Embeddinds)」の3つのモデルファミリーが使用できます。今回はQA検索を試すので「埋め込み(Embeddinds)」を利用します。
埋め込み(Embeddinds)は事前に文章をベクトル化(数値化)することで検索したい質問との関係性を計算して類似性が高いものを選ぶことができます。
参考
Azure OpenAIの埋め込み機能の紹介
埋め込み(Embeddinds)には「類似性」「テキスト検索」「コード検索」の3つのモデルファミリーが用意されています。今回は「類似性」「テキスト検索」の2つのモデルを利用してQA検索を比較していきます。
参考
以下にそれぞれのモデルファミリーについて説明します。
Similarity(類似性)
2つ以上のテキスト間の意味の類似度を計算することに適しています。モデルは以下の4つが用意されています。
- text-similarity-ada-001
- text-similarity-babbage-001
- text-similarity-curie-001
- text-similarity-davinci-001
GPT-3と同様に上から順にadaが一番速度が速く料金も安いですが一番能力が低いです。逆にdavinciは一番能力が高いですが料金も一番高くなっています。
Text search(テキスト検索)
回答の文章が質問に関連しているかを計算することに適しているモデルです。こちらのモデルは質問用と回答用にモデルが分かれていて、事前に回答の文章をベクトル化するために使うdocと質問のベクトル化に使うqueryの2種類がそれぞれのモデルごとに用意されています。
事前に回答の文章をベクトル化するdoc
- text-search-ada-doc-001
- text-search-babbage-doc-001
- text-search-curie-doc-001
- text-search-davinci-doc-001
質問をベクトル化するquery
- text-search-ada-query-001
- text-search-babbage-query-001
- text-search-curie-query-001
- text-search-davinci-query-001
QA検索の手順
手順の概要
簡単な手順は以下になります。
- モデルのデプロイ
- 回答が記載されている文章が入ったデータの準備
- 文章のベクトル化
- 質問のベクトル化と回答の類似性の算出
基本的にはこの手順で回答を検索します。
モデルのデプロイ
Azure OpanAI Studioで「リソース内のデプロイを管理します」からデプロイに移動します。
新しいデプロイをクリックします。
すでにデプロイしてしまっているのでデプロイ済みに表示されていますが「text-similarity-curie-001」「text-search-curie-doc-001」「text-search-curie-query-001」をデプロイします。
※1 普通のQA検索であれば「text-similarity-curie-001」は必要ありません
※2 埋め込みモデルは米国東部のリージョンはサポートされていないのでご注意ください
データの準備
子育てAIチャットボットのデータを使用します。子育てオープンデータ協議会がクリエイティブ・コモンズ・ライセンスの表示4.0国際に基づいてオープンデータとして公開している「子育てAIチャットボット」普及のための「FAQデータセット」を用いました。 データセットには662件の問い合わせと応答の組み合わせが含まれます。
(CC-BY 4.0 子育てオープンデータ協議会 )
文章のベクトル化
Microsoftのチュートリアルに書いてある内容を参考にNotebookで作っていきます。
参考
Azure OpenAI Service の埋め込みについてのチュートリアル - Azure OpenAI | Microsoft Learn
ライブラリなどの読み込み
データセットの読み込み
データの正規化
トークンの計算とデータクレンジング
APIが2000トークンまでなので2000トークン以上の行を削除します。
回答の文章をベクトル化して埋め込み
「text-search-curie-doc-001」を使って「answer」の列をベクトル化します。
以上で回答の文章のベクトル化は完了です。今回はcurieを使ったので4096次元にベクトル化されています。
参考
質問への回答
チュートリアル通りに質問をベクトル化してコサイン類似度の高い方から並べます。
コサイン類似度についての説明
Azure OpenAI Service の埋め込み - Azure OpenAI - embeddings and cosine similarity | Microsoft Learn
「出生届は夜間でもできる?」という質問を投げてみます。
するとQA集の
出生届は夜間でも届出できますか。
という質問に対する
夜間・休日窓口の場合、母子手帳の証明や届書の受理証明書などの発行、 子どもに関する手当・助成の受付はしていませんので、通常窓口で手続き・申請してください。▼詳しくはこちら(自治体HP内関連ページのURL)
という回答の行が一番類似性が高いということで一番上に表示されます。
次に「母子手帳を受け取りたいのですが、手続きを教えてください。」という質問を投げると本来のQA集にある
母子手帳を受け取りたいのですが、手続きを教えてください。
に対するこの回答は
窓口で妊娠届をご記入いただき、母子手帳をお渡しします。
住民票の世帯が別の方が代理で窓口に来られる場合は、委任状が必要になります。▼詳しくはこちら(自治体HP内関連ページのURL)
6番目に表示されます。
最初にご説明したように「テキスト検索」はQA集のQとAを紐づけているわけではないのでQA集の質問と同じ文章で検索しても必ずしもQA集通りの回答にはなりません。
類似性モデルで試してみる
今度は類似性モデルを使ってQA集の質問をベクトル化してその質問同士の類似性を試してみます。
質問の列のベクトル化
同じ手順で質問をベクトル化します。先ほどは「text-search-curie-doc-001」を使いましたが、今度は「text-similarity-curie-001」を使って「question」の列を指定します。
先ほどと同じ質問の「母子手帳を受け取りたいのですが、手続きを教えてください。」を「text-similarity-curie-001」使って聞くと
今度は意図したQA集の質問が一番上に表示されました。
またちょっと質問の内容を変えても手続きという単語が入っていると上位に来ます。
最後に
QA集通りということであれば類似性のモデルを使うことでかなり精度は高いのではないかと思いますが、そもそもQAとしてどちらが正しいのかを考えなくてはならないか思います。
テキスト検索のモデルを使った際に「母子手帳を受け取りたいのですが、手続きを教えてください。」という問い合わせに対して
母子手帳は、○○市役所本庁舎△△階××課窓口、◎◎出張所、………(その他の受け取り場所を適宜記載)………で受け取れます。
▼詳しくはこちら(自治体HP内関連ページのURL)
という回答がトップになっていて対してQA集では
窓口で妊娠届をご記入いただき、母子手帳をお渡しします。
住民票の世帯が別の方が代理で窓口に来られる場合は、委任状が必要になります。▼詳しくはこちら(自治体HP内関連ページのURL)
という回答になっています。
おそらくQA集では「窓口で妊娠届をご記入」のところが大切かと考えているかと思いますが、元々の「母子手帳を受け取りたいのですが、手続きを教えてください。」という問い合わせに対して「○○市役所の窓口で受け取れます」という場所が入っている方が良い回答なのではないかとも思います。
実際に問い合わせている方は「窓口で妊娠届をご記入」とあってもどこに行けばいいのかわからないので、その後に窓口の場所を検索しなくてはならない場合もあるのではないかと考えます。
そういった場合に上位数件の回答をGPT-3の機能で結合、要約して回答することによりより良いQA集が作れるのではないかと考えます。
また、テキスト検索モデルを使えば以前のような質問と回答がセットのQA集を作る必要はなく、説明の文章さえ作ればQA検索ができるので、QA検索を作る作業が格段に減るのではないかと考えます。
上田 英治(日本ビジネスシステムズ株式会社)
エンジニアとしてインフラ構築、システム開発やIoT基盤構築等を経験し、現在はクラウドアーキテクトとして先端技術の活用提案や新規サービスの立ち上げを担当。
担当記事一覧