Microsoft AzureのCognitive Service LUISで文章分類器を作成するまでの手順メモです。
ただAPIのコマンドを確認しただけですので、内容は薄いです。(精度とかチューニングとかは一切触れません。)
LUISのIntentを分類先とみなします。(Entityとか他の機能はとりあえず一切使用しません。)
IBM WatsonのNatural Language Classifier(NLC)的な感じで使うことを想定しています。
LUISにはポータル画面が用意されており、そこからIntentやそれに紐付くUtteranceを画面でペコペコ追加できるけど、いっきにIntentやUtteranceの追加ができなさそうなので、コマンドでAPIを呼んで構築します。
(WatsonのNLCであればポータル画面上でcsvファイルをuploadできますが...)
API Referenceに書いてあることをただするだけです。↓
https://westus.dev.cognitive.microsoft.com/docs/services/5890b47c39e2bb17b84a55ff/operations/5890b47c39e2bb052c5b9c2f
Documentはこちら↓
https://docs.microsoft.com/ja-jp/azure/cognitive-services/luis/home
LUISのアカウントを作成
以下の方の手順で作成します。スクショを細かく載せられており非常にわかりやすいです。
https://qiita.com/Yuwji/items/dda88c0c19f2b02e8c26
パラメータの確認
ポータル画面から「My apps」を開いて、画面右上の「PUBLISH」を選択。
以下のような画面が表示されます。
APIを呼び出すときのパラメータを確認しておきます。
- West US - westus.api.cognitive.microsoft.com
- West Europe - westeurope.api.cognitive.microsoft.com
- Australia East - australiaeast.api.cognitive.microsoft.com
API
Intentの確認
curl -X GET https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/[appID]/versions/[versionID]/intents -H 'ocp-apim-subscription-key: [subscription-key]'
以下のようなjsonが返ってくる。最初はデフォルトで登録されているNoneだけ。
[
{
"id": "[Intent ID]",
"name": "None",
"typeId": 0,
"readableType": "Intent Classifier"
}
]
Intentの追加
分類先を追加します。とりあえず今回はデモということで、気象庁のQ&Aのカテゴリを分類先として使ってみます。
以下をIntentとしてみる
- 気象
- 地震・津波・火山
- 地球環境・海洋
- 全般・その他
たとえば「気象」Intentを追加するなら、以下のようにPOSTします。
curl -X POST https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/[appID]/versions/[versionID]/intents -H 'content-type: application/json' -H 'ocp-apim-subscription-key: [subscription-key]' -d '{"name": "気象"}'
うまくいけばIntentIDが帰ってきます。
"d9c04sg5-gq35-987q-c290-e6a123456789" # ダミーです。
残りのIntentも同様に追加して、Intentの確認をすると、
[
{
"id": "[Intent ID]",
"name": "None",
"typeId": 0,
"readableType": "Intent Classifier"
},
{
"id": "[Intent ID]",
"name": "全般・その他",
"typeId": 0,
"readableType": "Intent Classifier"
},
{
"id": "[Intent ID]",
"name": "地球環境・海洋",
"typeId": 0,
"readableType": "Intent Classifier"
},
{
"id": "[Intent ID]",
"name": "地震・津波・火山",
"typeId": 0,
"readableType": "Intent Classifier"
},
{
"id": "[Intent ID]",
"name": "気象",
"typeId": 0,
"readableType": "Intent Classifier"
}
]
Intentが追加されたことがわかります。
Utteranceの追加
LUISでは各Intentに対して最低5つのUtteranceの追加を推奨してそうな感じなので、先ほど追加した各Intentに5つのUtteranceを追加してみます。
まずはとりあえず、「気象」と「地震・津波・火山」に1つずつUtteranceを追加してみます。
curl -X POST https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/[appID]/versions/[versionID]/examples -H 'content-type: application/json' -H 'ocp-apim-subscription-key: [subscription-key]' -d '[
{
"text": "気象等の特別警報の指標は、今後、変更されることはありますか?",
"intentName": "気象",
"entityLabels":[]
},
{
"text": "津波の特別警報の基準を予想される津波の高さが3m超から5m超に変更すべきではないですか?",
"intentName": "地震・津波・火山",
"entityLabels":[]
}
]'
結果は以下のようなjsonの配列で返ってきます。hasError
がfalse
ならちゃんと登録できているようです。
[
{
"value": {
"ExampleId": [exID],
"UtteranceText": "気象等の特別警報の指標は、今後、変更されることはありますか?"
},
"hasError": false
},
{
"value": {
"ExampleId": [exID],
"UtteranceText": "津波の特別警報の基準を予想される津波の高さが3m超から5m超に変更すべきではないですか?"
},
"hasError": false
}
]
こんな感じで全てのIntentに最低5つのUtteranceを追加します。
Utteranceの確認
curl -X GET https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/[appID]/versions/[versionID]/examples -H 'content-type: application/json' -H 'ocp-apim-subscription-key: [subscription-key]'
結果は以下のように各Utteranceが何のIntentに紐付いてるか、tokenizeされたUtterance、そのUtteranceに対するIntentの予想が確認できます。まだ学習をしていないので、(None以外の)各Intentに対するscoreが-1になっているということでしょう。
[
{
"id": [exID],
"text": "気象等の特別警報の指標は、今後、変更されることはありますか?",
"intentLabel": "気象",
"tokenizedText": [
"気象",
"等",
"の",
"特別",
"警報",
"の",
"指標",
"は",
"、",
"今後",
"、",
"変更",
"さ",
"れる",
"こと",
"は",
"あり",
"ます",
"か",
"?"
],
"entityLabels": [],
"intentPredictions": [
{
"name": "None",
"score": 0.7736272
},
{
"name": "全般・その他",
"score": -1
},
{
"name": "地球環境・海洋",
"score": -1
},
{
"name": "地震・津波・火山",
"score": -1
},
{
"name": "気象",
"score": -1
}
],
"entityPredictions": []
},
~以下略~
学習
以下のコマンドでOK。body
はないけどPOST
する。
curl -X POST https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/[appID]/versions/[versionID]/train -H 'content-type: application/json' -H 'ocp-apim-subscription-key: [subscription-key]'
結果は以下のような簡単なjsonで返ってきます。これは学習中を意味するっぽいです。
{
"statusId": 9,
"status": "Queued"
}
学習が完了していれば、以下のように返ってきます。
{
"statusId": 2,
"status": "UpToDate"
}
学習が完了すれば先ほどのUtteranceの確認でscoreが-1でなく確信度的な値が入っていると思います。
ApplicationをPublishする
ここまでの手順後にquery
を投げてもまだ各Intentに分類してくれないようで、Publishする必要があります。以下でApplicationをPublishします。versionは必要に応じて変更するのがよいでしょう。
curl -X POST https://[location].api.cognitive.microsoft.com/luis/api/v2.0/apps/[appID]/publish -H 'content-type: application/json' -H 'ocp-apim-subscription-key: [subscription-key]' -d '{
"versionId": "0.1",
"isStaging": false,
"region": "westus"
}'
以下のようなjsonが返ってきます。
{
"versionId": "0.1",
"isStaging": false,
"endpointUrl": "https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/[appID]",
"region": "westus",
"assignedEndpointKey": null,
"endpointRegion": "westus",
"publishedDateTime": "20xx-xx-xxTxx:xx:xxZ"
}
ここまでくれば、LUISを分類器として使えるようになると思います。
問い合わせてみる
以下のGET文で問い合わせます。ちょっと注意が必要なのですが、上記でいろいろAPIをつっついていたときと若干URLが違います。
(~/luis/api/~ではない。)
curl -X GET 'https://[location].api.cognitive.microsoft.com/luis/v2.0/apps/[appID]?verbose=true&q=[query]' -H 'content-type: application/json' -H 'ocp-apim-subscription-key: [subscription-key]'
とりあえず、「大地震が発生したらどうしたらいいですか?」と問い合わせてたら、以下のようなjsonが返ってきました。
{
"query": "大地震が発生したらどうしたらいいですか?",
"topScoringIntent": {
"intent": "地震・津波・火山",
"score": 0.14173308
},
"intents": [
{
"intent": "地震・津波・火山",
"score": 0.14173308
},
{
"intent": "地球環境・海洋",
"score": 0.1367866
},
{
"intent": "全般・その他",
"score": 0.0536470264
},
{
"intent": "None",
"score": 0.023606617
},
{
"intent": "気象",
"score": 0.006278038
}
],
"entities": []
}
精度があれですが、各Intentに追加したUtteranceもテキトーにサンプリングしただけだし、5つしか追加してないので、精度はここでは触れないこととします。
queryのパラメーター
Documentによると、query
には以下のパラメーターがあるようです。(今回はverbose
だけ使用)
クエリ文字列 | Type | 値の例 | 目的 |
---|---|---|---|
verbose | ブール値 | true | 発話のすべての意図スコアを含めます |
timezoneOffset | 数 (単位は分) | 60 | datetimeV2 作成済みエンティティのタイム ゾーン オフセットを設定します |
spellCheck | ブール値 | true | 発話のスペル訂正 -- bing-spell-check-subscription-key クエリ文字列パラメーターと組み合わせて使用します |
bing-spell-check-subscription-key | サブスクリプション ID | spellCheck クエリ文字列パラメーターと組み合わせて使用します | |
staging | ブール値 | false | ステージング エンドポイントまたは本番環境エンドポイントを選択します |
log | ブール値 | true | クエリと結果をログに追加します |
追加の学習とかIntentやUtteranceの削除とかはまたの機会に。