フォーム読み込み中
2023年5月9日掲載
システムエンジニアの成瀬です。
日々刻々と進化を続けているAIやクラウドサービスを検証したり、AIを活用したアプリを作ったりしています。
突然ですが、スプレッドシートに以下のような表があった場合、「質問の例文」にマッチする「回答」を検索するにはどうすればよいでしょうか?
| A | B | |
|---|---|---|
| 1 | 質問の例文 | 回答 |
| 2 | トイレはどこですか? | ここから一番近いトイレは左手のエレベータの奥にございます。 |
| 3 | 駐車場は何時間まで無料ですか? | お買い物の有無にかかわらず1時間まで無料ですが、3000円以上のお買い上げレシートと引き換えに3時間まで無料となります。 |
| 4 | 営業時間を教えてください | 平日は朝9時から夜9時まで、土日祝日は朝10時から夜8時まで営業しております。 |
| 5 | PayPayは使えますか? | もちろん使えます。 |
| 6 | ベビーカーの貸し出しはありますか? | はい。入口の手前に貸出用の受け付けがございます。 |
色々テクニックがあるかと思いますが、このような場合によく使われるのは VLOOKUP関数ではないでしょうか?
VLOOKUP関数の使い方は、検索テキスト、検索列と結果列の範囲、結果として返す列の位置を指定します。
例えば、「トイレはどこですか?」に対する回答を検索する場合は以下の式になると思います。
=VLOOKUP("トイレはどこですか?", A2:B6, 2 )
式を入力したセルには期待した通りの回答がセットされるはずです。
では、実際の質問が「トイレに行きたいのですが」だった場合、どのように検索すればよいでしょうか?
VLOOKUP関数は探したいテキストにワイルドカードを使うことができるので、「トイレ」というキーワードで検索すればヒットします。
しかし、実際の質問からキーワードをどうやって抜き出せばいいのでしょうか...
このような自然言語による検索という課題をスマートかつ手軽に解決するために、Google スプレッドシートのカスタム関数とWatson Discovery を利用する方法を紹介してみたいと思います。
Google スプレッドシートでは標準の関数以外に、ユーザ独自の関数を作ることができます。
例えば、インターネットの天気予報サービスのAPIを呼び出して、愛知県犬山市の明日の天気を取得できたりします。
IBM Watson Discovery (以降、Discoveryと省略します)は IBM Cloud のドキュメント指向の検索エンジンです。
Discovery の特長の一つに、自然言語で検索できる機能があります。
質問の文脈を理解した検索が可能になるため、質問の例文「トイレはどこですか?」に対して、実際の質問「トイレに行きたいのですが」でもヒットできるようになります。(常に100%というわけではありません)
Discoveryにもドキュメントを検索できるAPIがあるので、質問に対する回答を検索できるカスタム関数を作ってみましょう。
まずは、Discoveryの環境の準備から始めます。
Discoveryではさまざまなタイプのドキュメントを登録できますが、今回はGoogle スプレッドシートの表からCSVファイルを作成します。
タイトル「TOARU_MALL」、シート名「FAQ」
Discovery は無料で試すことができますが、IBM Cloud のアカウントが必要になります。
まだアカウントを登録していない場合は、アカウント登録ページから手続きをしてください。
(現在のところ、法人以外は利用できなくなっているようです)
Discoveryのサービスを利用するためには、サービスインスタンス(以後、インスタンスと省略します)を作成します。
インスタンスの作成が開始されると、リソースリストが表示されます。
Discoveryのインスタンスは「AI/機械学習」カテゴリに表示されます。
Discoveryが検索するドキュメント空間は「プロジェクト」という単位になりますが、実際のドキュメントはプロジェクトの下の「コレクション」という単位で管理します。
続いて、プロジェクトの中にコレクションを作成します。
※ 用途によっては、複数のコレクションを作成して、横断検索もできます。
続いて、コレクションに登録するドキュメント(CSVファイル)をアップロードします。
アップロードしたドキュメントが登録されるまで少し時間がかかります。(数秒から数分程度)
これで、Discoveryの準備は完了です。
ここからはカスタム関数の作成に入ります。
今回作成するカスタム関数の使用方法を以下のように決めておきます。
入力されたテキストの質問をDiscoveryのドキュメントから検索して回答を返します。
DISCOVERY_QUERY( テキスト )
テキスト:検索する質問です。
DISCOVERY_QUERY( "トイレに行きたいのですが" )
DISCOVERY_QUERY( A1 ) ※セルの値がテキストなら参照も可能です
Discovery で文書を検索する場合は query APIを使用します。
query APIの仕様について、公式APIリファレンスから以下に抜粋します。
POST {インスタンスのURL}/v2/projects/{プロジェクトID}/query?version={バージョン日付}
※1 インスタンスのURL、プロジェクトIDの取得方法については、「資格情報の設定」で説明します。
※2 バージョン日付は公式APIリファレンスに記載されている最新情報を使用します。
| 名称 | 値 | 説明 |
|---|---|---|
Content-Type (必須) | application/json | リクエストデータの種類(JSON) |
Authorization (必須) | "Basic apikey:{インスタンスのAPIキー}" | サービス認証に必要 BASE64でエンコードする |
X-Watson-Learning-Opt-Out (オプション) | true (デフォルトはfalseでオプトイン) | サービスに送信した情報を学習などに利用させない |
※ インスタンスのAPIキーの取得方法については、「資格情報の設定」で説明します。
色々なオプションを指定できますが、今回は必要最低限のオプションだけ抜粋します。
| フィールド名 | データ型 | 説明 |
|---|---|---|
| natural_language_query | テキスト | 自然言語での検索 2048文字以内 |
リクエストデータのサンプル
{
natural_language_query: "トイレに行きたいのですが"
}
レスポンスデータも多くの情報が返ってきますが、回答としてほしい情報だけ抜粋します。
| フィールド名 | データ型 | 説明 | |
|---|---|---|---|
| results | オブジェクト配列 | 検索結果として確からしい順番にドキュメント情報が格納される | |
| ドキュメント情報 | document_id | テキスト | ドキュメントID (CSVだと行単位) |
| question | テキスト | 質問の例文 | |
| text | テキスト配列 | 回答 (今回の例では要素は1つだけ) | |
レスポンスデータのサンプル
results: [
{
document_id: '87743fc8c79a4eb0d276f4dbb00e9c2c_0',
question: 'トイレはどこですか?',
text: [ '入口の左側にございます。' ],
},
...
]
上のサンプルの場合、カスタム関数の戻り値として「入口の左側にございます。」を返すためには、レスポンスデータの results[0].text[0] をセットすればよいことになります。
Google スプレッドシートのカスタム関数は、スプレッドシートとは別の画面のスクリプトエディタから登録します。
マクロを記録したことのある人は、スクリプトエディタを開いたことがあるかもしれません。
/** * Discovery APIを使用して、質問に対する回答を検索します。 * * @param {"トイレはどこですか"} TEXT テキスト {文字列} * 質問のテキストです。 * @return {string} * * @customfunction * copyright (c) 2023 SoftBank Corp. */ function DISCOVERY_QUERY(TEXT) { // 資格情報は外部に公開しないように注意してください const APIKEY = "あなたのAPIキー" const INSTANCE_URL = "あなたのインスタンスURL" const PROJECT_ID = "あなたのプロジェクトID" // 資格情報は外部に公開しないように注意してください const VERSION_DATE = "2020-08-30" // リクエストURL const url = `${INSTANCE_URL}/v2/projects/${PROJECT_ID}/query?version=${VERSION_DATE}` // リクエストデータ const payload = { natural_language_query: TEXT, } const params = { method: "post", headers: { Authorization: "Basic " + Utilities.base64EncodeWebSafe(`apikey:${APIKEY}`), "X-Watson-Learning-Opt-Out": true, }, payload: JSON.stringify(payload), contentType: "application/json", muteHttpExceptions: true, } // リクエストの実行 let res; try { res = UrlFetchApp.fetch(url, params) } catch (err) { throw Error(err.message) } // レスポンスデータ const res_json = JSON.parse(res.getContentText()) // ステータスコード const code = res.getResponseCode() if (code != 200) { console.error(res_json) throw Error(`ステータスコード ${code}`) } // 質問の回答 let answer; try { answer = res_json.results[0].text[0] } catch (err) { console.info(res_json) throw Error("回答が見つかりませんでした") } // 関数の戻り値 return answer }
ペーストしたカスタム関数のコードには、環境固有の以下の資格情報を設定する必要があります。
悪用防止のため、外部には公開しないように注意してください。
インスタンスのAPIキーとURLは、インスタンスの管理画面(ツールキットではありません)から取得できます。
※ IBM Cloud コンソールのダッシュボードから開く場合は以下の手順になります。
続いて、プロジェクトIDはツールキットから取得します。
これでカスタム関数の作成は完了です。
スクリプトエディタは閉じてしまっても大丈夫です。
では、実際にカスタム関数を使ってみましょう。
適当なセルに以下の式をタイプしていきます。
=DISCOVERY_QUERY(
そうすると、標準の関数と同じように使用方法が表示されます。
続きを以下のように入力して関数を実行します。
=DISCOVERY_QUERY("トイレに行きたいのですが")
セルに検索結果の回答が表示されました。
なお、カスタム関数に渡すテキストは、以下のようにセルの値の参照でも可能です。
セル「C2」をセル「C3」~「C6」にコピーすれば、全ての質問のテストが完了です。
データが多い場合でも、このように式をコピーすれば簡単ですね。
(式をコピーしなくても一括で処理できる方法については、「より活用するために」で紹介します)
もしも、エラーが表示される場合は資格情報を見直してみてください。
(全てのエラーの原因が資格情報の問題というわけではありません)
今回作成したDiscoveryのインスタンスですが、今後使う予定がなければ削除しておきましょう。
もちろん、インスタンスを削除するとカスタム関数も動かなくなります。
※ IBM Cloud コンソールのダッシュボードから開く場合は以下の手順になります。
インスタンスの削除後はリソースリストに戻ります。
今回は検索対象を固定のコレクションにしましたが、用途によって検索するプロジェクトやコレクションを切り替えたい場合には、引数から指定できるようにしたり、関数を別にしたりしてもいいかもしれません。
Discovery の検索結果にはドキュメントごとに確からしさの指標(1〜0の範囲の実数)も返ってくるので、結果として返すべきかどうかの判断材料になります。
想定した回答が返ってこない場合には、同義語の登録やクエリ拡張などの色々なチューニング方法があります。
カスタム関数は他の標準関数と同様に、引数と戻り値にセルの範囲(レンジ)を指定することも可能です。一度に複数の検索を実行したい場合には検討してみるのもいいかもしれません。ただし、大量に処理する場合(オペミスを含む)のリスクについて注意してください。
サンプルコードのエラー処理は必要最小限にしているので、もっとユーザにわかりやすくすることをおススメします。
社内などで多くの人に使ってもらう場合、関数を各自にコピーするとメンテナンスが大変になるので、ライブラリ化を検討してみてください。
Watson Discovery ができることは自然言語による検索だけではありません。
などなど、非常に多くの機能があります。
また、Watson Assistant と連携してチャットボットから検索することも、とても簡単にできます。(Watson Assistant 自体も自然言語を理解できます)
ぜひ試用期間中にいろいろ探索してみてください。
Google スプレッドシートを今まで使っていて、こんな事ができるなんて知らなかったという人もいるのではないでしょうか?
WebAPIとの連携方法がわかれば、データの取得・変換・分類・判定・予測など、カスタム関数の可能性は飛躍的に高まります。
もはや、単なる表計算ソフトにとどまらず、業務の効率化・自動化にとても強力なツールとなり得ることをおわかりいただけましたでしょうか?
Google スプレッドシート、Gmail、Google カレンダー、Google Chat、Google ドライブ、Google Meet などのさまざまなサービスがあらゆる働き方に対応する業務効率化を実現します。
IBM Cloudは、IBMが提供するビジネスのためのクラウドサービスです。AIプラットフォームのIBM Watsonをはじめとする幅広い製品・サービスを提供。ビジネス活用だけでなく、既存システムからのセキュアなクラウド移行や、クラウドネィティブ・アプリケーションの開発の両方に対応できるクラウドサービスです。
条件に該当するページがございません