はじめに
この記事はMicrosoft Azure Advent Calendar 2017 の6日目の記事です。
注意点(17/12/25追記)
記事を書いた直後にいろいろとGAになり、すでに遺物になっている可能性があります。。
下記などに詳しく載っています!
MS Cogbot Advent Calendar 2017
この記事は
Azureの自然言語解釈系サービスの2つと、それを利用可能とするPaaS機能について簡単な説明と使ってみた所感を記します。
17/12/6時点の情報で記載します。
- 自然言語解釈系
- PaaS
正直日本語対応を謳ってますが、Preview的で、Unicode対応+分かち書きちょっとできるくらいの感触なので、今後に期待というところです。
昨日のAdvent Calendarの記事もQnaMakerとBotServiceから一歩進んだ記事ですので、ぜひ参考に。
LUIS
Language Understanding Intelligent Serviceの略ということで、イメージは公式を見るとわかります。
utterance(文章)を入力とし、intent(文意)とentity(要素)をパースしてJSON形式で返すAPIとなっています。
教師あり学習なので数十の例文が必要です。下記作業はちょっと手がかかりますので、チャットボットに必須のユーザの問いかけ実データを使って再訓練なども手間がかかりそうです。
必要な作業は下記。チュートリアルレベルはドキュメントに書いてあります。
- intent(文意)、entity(要素)を定義する
- intentは30個まで定義できますが、多いと精度が下がります。ボットの目的を絞って、必要最小限にしましょう。
- 事前定義済み要素(prebuilt entity)もありますが(時間など)日本語はあまり対応していないと思った方が良いでしょう
- intentごとに例文を入力し、その正解のentityを指定する
- 学習させ、テスト用インターフェースで試す
- LINEのようなインターフェースがあります
- APIを公開する
- キー取得など。指示に従っていけば特に迷わない認識です。
intentがある程度違うものであり、例文バリエーションを整えれば。。。
使用するデータをエンジンの改善に使うという規約と記憶してるので、日本語の精度を上げるためにどんどん使って欲しい、という印象を受けました。
しかし登録したentityのリストを取得する手法、entityを直接登録する手法がよくわからなくて辛い印象があリました(ご存知でしたらフォローください)
QnA Maker
問いかけの文章を投げると、それに近い答えをスコアとともに返却してくれるAPIです。
こちらも教師あり学習で、QとAのペアを学習させる必要があります。
TSVで投入するのがベタですが、QAサイトのURLやWORD形式でも読めるそうです。
ただしフォーマット制約が厳しいのであまり期待しない方が良いです。
QAボットはかける手間の割に使えるものができるので、手始めにはベストです
トレーニングするインターフェースは対話的で、間違ったQAがあったら左の3択から修正しよう、なければあとで正しいAnswerをて入力する、というところが使いやすいです。
同じAnswerを期待するQuestionを右側にどんどん追加していけるのもグッドかと。
Bot Service(ボットサービス)
App Serviceで「ボットサービス」と検索すると出てきます(Bot serviceだと当たらない?前は当たった気がするんだが)。
上記2つのサービスはテンプレートがあるので速攻です。
途中でQnAMakerのナレッジベース名をプルダウンで選択すれば連携終了。
デプロイされると、ブラウザ上で編集できる形でサンプルコードが出来上がります。
VisualStudioと連携してやるべきでしょうが、ちょっとの修正ならブラウザ上でも。
Slack、SkypeやFacebookMessengerなども連携先のAPI情報を貼り付ければ連携OK!という仕組みです。
少し修正
アクティブラーニング、すなわちスコアがあまり高くないAnswerがいくつか出てきたとき、候補を提示してユーザに選んでもらう、というのをやってみました。
しかし何度ドキュメントを読んでもうまくいかず。。。
結果BotServiceが指定するライブラリのバージョンをあげたら解決しました。
修正前
{
"frameworks": {
"net46": {
"dependencies": {
"Microsoft.Bot.Builder.Azure": "3.2.1",
"Microsoft.Bot.Builder.CognitiveServices": "1.0.3"
}
}
}
}
修正後
{
"frameworks": {
"net46": {
"dependencies": {
"Microsoft.Bot.Builder.Azure": "3.2.1",
"Microsoft.Bot.Builder.CognitiveServices": "1.1.0"
}
}
}
}
これでQnaMakerDialogのクラスを一つ作り、run.csxから呼べばOKです。
TODO込みのコードで残念なのは許してください。
using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Azure;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.CognitiveServices.QnAMaker;
// For more information about this template visit http://aka.ms/azurebots-csharp-qnamaker
[Serializable]
public class BasicQnAMakerDialog : QnAMakerDialog
{
// Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
public BasicQnAMakerDialog() : base(new QnAMakerService(new QnAMakerAttribute(Utils.GetAppSetting("QnASubscriptionKey"), Utils.GetAppSetting("QnAKnowledgebaseId"), "良い回答が見つかりませんでした。別の質問に変えてもらえますか?",0.5)))
// public BasicQnAMakerDialog() : base(new QnAMakerService(new QnAMakerAttribute(Utils.GetAppSetting("QnASubscriptionKey"), Utils.GetAppSetting("QnAKnowledgebaseId"))))
{
}
}
// ここから追加。TODO:APIキーとナレッジキーがべた書きになってしまったので良いやり方が知りたい。
[Serializable]
[QnAMaker("<QnAMakerのAPIキー>", "<ナレッジキー>", "わかりませんので別の質問にかえて", 0.10, 4)]
public class QnADialogWithActiveLearning : QnAMakerDialog
{
// TODO:こんな感じでかけそうなのにうまく動かなかった
// public QnADialogWithActiveLearning() : base(new QnAMakerService(new QnAMakerAttribute(Utils.GetAppSetting("QnASubscriptionKey"), Utils.GetAppSetting("QnAKnowledgebaseId"), "良い回答が見つかりませんでした。別の質問に変えてもらえますか?",0.3,3)))
protected override async Task QnAFeedbackStepAsync(IDialogContext context, QnAMakerResults qnaMakerResults)
{
// responding with the top answer when score is above some threshold
if (qnaMakerResults.Answers.Count > 0 && qnaMakerResults.Answers.FirstOrDefault().Score > 0.75)
{
await context.PostAsync(qnaMakerResults.Answers.FirstOrDefault().Answer);
}
else
{
await base.QnAFeedbackStepAsync(context, qnaMakerResults);
}
}
}
これで自信がある回答はシングルアンサー、自信がないとマルチアンサーを返すようになります。
まだ実際ユーザーが何を選択したかどうかがQnAMakerに返る訳ではなさそうなので、実際のアクティブラーニングにはもう一手間必要そうです。
どこかに吐いといて、バッチ学習でも良いと思います。
終わりに
簡単に紹介しました。今後に期待な部分も多いですし、英語のドキュメントもやや不親切ですが、
これくらいのアプリが1日あれば十分できてしまい、かつ料金もほぼ無料ということで
うまく付き合っていきたいところです。
wikiなどで情報共有しているサイトもあるかもしれませんが、意外とボット作っちゃった方がはやいかも?
以上です。