Help us understand the problem. What is going on with this article?

LUISで文章分類器モデルを作成するまでの手順

More than 1 year has passed since last update.

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を呼び出すときのパラメータを確認しておきます。

publish_app.PNG
locationごとにEndpointが異なるので注意

  • 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の配列で返ってきます。hasErrorfalseならちゃんと登録できているようです。

[
    {
        "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の削除とかはまたの機会に。

m__k
数学専攻(確率解析)→SE→ITコンサル 自然言語処理をメインに勉強しています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした