LoginSignup
0
0

AI-102 HandsOn Azure AI Languageを勉強する

Last updated at Posted at 2024-04-04

AI-102の勉強のためにGitHubのHandsOnを実施します。

https://github.com/MicrosoftLearning/mslearn-ai-services
https://github.com/MicrosoftLearning/mslearn-ai-vision
https://github.com/MicrosoftLearning/mslearn-ai-language → 本記事はこれ
https://github.com/MicrosoftLearning/mslearn-ai-document-intelligence
https://github.com/MicrosoftLearning/mslearn-knowledge-mining
https://github.com/MicrosoftLearning/mslearn-openai

MSLearnのドキュメントはこちら。

Azure AI サービスを使用して自然言語処理のソリューションを開発する
 
できるのはこんなこと。

  • Azure AI Language
    • 概要作成
    • テキストから言語を検出する
    • テキストのセンチメントを分析する
    • キー フレーズ、エンティティ、リンクされたエンティティを抽出する
  • Azure AI Translator
    • 翻訳
  • Azure AI Speech
    • 音声対応

基本的にそれぞれのサービスでポータルがあり、そこでトレーニングやモデルのデプロイができる感じ。

リソース作成 (Language)

  • Question AnsweringにはAI Searchが必要。
  • Custom Text ClassificationやSummarizationにはStorage Accountが必要。

image.png

Question Answering、質問応答ソリューションの構築

OpenAIを使わないRAGのようなものととらえればよいか。
質問と応答のFAQ集を元に自然言語で回答してくれる。昔のQnAサービスの進化版。

その他にもLUIS(Language Understanding)というのがあるが、LUISはもっと会話寄り。

Question Answer Pairs

Language Studioからプロジェクトを作成し、例えば、データソースにMicrosoft Learnを設定したFAQボットを作ってみる。

Language studioのCustom question answeringから。
image.png

image.png

データソースはURL、ファイル、おしゃべり(ChitChat)の3種類を選べる。
image.png

HandsOnでは、Microsoft LearnのFAQ集をソースに設定してみる。
image.png

こんな風に構造化されていれば自動的に取り込んでくれるぽい。
image.png

おしゃべり、というのはMicrosoftがBotにキャラクターを与えるための事前定義済み質問集を指す。Witty、Enthsiastic、Caringとかを選べる。中身を見てみると、こんな感じ。年齢は?とか家族は?とかなんとなくBotに質問してしまいそうな内容がある。こちらも設定してみたところこんな感じになった。自分専用のキャラクターとかも作れそう。
image.png

質問は自分でも追加できる。
image.png

Alternate Questionというので、言い回しが違うけど同じ回答というケースを定義できる。
image.png

Follow-up promptで回答に補足をつけることができる。
image.png

Follow-upを作ったらEditorialというのが裏にできていて、そこに保存されていた。
image.png

image.png

Test

テストをしてみると、Wittyに設定したおしゃべりやFollow-up promptが出てくる。
image.png

Deploy

URLのエンドポイントができる。
image.png

このエンドポイントはカスタムアプリからも呼べるし、又はCreate a botボタンからクリック1つでAzure AI Bot Serviceと連携してWeb Botを簡単に作ることができる。
image.png

こんな感じで呼び出せる。

curl -X POST "https://{endpoint}.cognitiveservices.azure.com/language/:query-knowledgebases?projectName=LearnFAQ&api-version=2021-10-01&deploymentName=production" 
-H "Ocp-Apim-Subscription-Key: {KEY}" 
-H "Content-Type: application/json" 
-d "{\"top\":3,
\"question\":\"YOUR_QUESTION_HERE\",
\"includeUnstructuredSources\":true,
\"confidenceScoreThreshold\":\"YOUR_SCORE_THRESHOLD_HERE\",
\"answerSpanRequest\":{\"enable\":true,\"topAnswersWithSpan\":1,
\"confidenceScoreThreshold\":\"YOUR_SCORE_THRESHOLD_HERE\"},
\"filters\":{\"metadataFilter\":{\"logicalOperation\":\"YOUR_LOGICAL_OPERATION_HERE\",
\"metadata\":[{\"key\":\"YOUR_ADDITIONAL_PROP_KEY_HERE\",
\"value\":\"YOUR_ADDITIONAL_PROP_VALUE_HERE\"}]}}}"

会話言語理解モデル (Conversational language understanding model)

最初に

AlexaやGoogleHomeのBotみたいに、会話からキーフレーズを抽出するための技術。GPTみたいに汎用的ではないから、会話理解というと言い過ぎな印象を受ける。

こういう流れらしい。GPTでもプロンプトでできそうではあるが、ちゃんとトレーニングできるのがいいところ。

1. アプリが、ユーザーから自然言語入力を受け入れます。
2. 言語モデルを使用してセマンティックの意味 (ユーザーの "意図") を特定します。
3. アプリが、適切なアクションを実行します。

Conversational language understandingを選択。
image.png

プロジェクト作成

※なんかこの辺でうまくプロジェクトが作成できないときがあったが、Storage AccountありでLanguageリソースを作り直すとうまくいった。
image.png

会話理解には以下の要素がある。

  • 入力される会話内容である発話、Utterance

  • 実際にやってほしい意図、Intent

  • その意図を理解して何を処理してほしいかを定義する、Entity Component

  • 実際にトレーニングされたモデル

作業の順番
①Intentを作る
②IntentにEntityを紐づける
③ModelをDeployする
④IntentにUtteranceの例文を紐づける

Intent

まずはIntentを作成する。
image.png

Utterance

Data LabelingからIntentを要求する発話の例を定義してやる。(さっきのQnAに似ている)
GetTimeには"what time is it?"のように。
image.png

Model

Modelをトレーニングする。
image.png

ModelをDeployする。
image.png

Testする。意図を理解してくれるから、Utteranceが少し違ってもちゃんと返ってくる。

{
    "query": "What time?\n",
    "prediction": {
        "topIntent": "GetTime",
        "projectKind": "Conversation",
        "intents": [
            {
                "category": "GetTime",
                "confidenceScore": 0.96072626
            },
            {
                "category": "GetDate",
                "confidenceScore": 0.87814885
            },
            {
                "category": "GetDay",
                "confidenceScore": 0.79664844
            },
            {
                "category": "None",
                "confidenceScore": 0
            }
        ],
        "entities": []
    }
}

Entity

上記でちゃんと正しいIntentが選択されることがわかった。それでは実際にEntityを紐づけて、データ抽出的なことができるようにしてみる。
Entityの種類は4種類。

  • Learned
  • List
  • Prebuilt
  • Regex

image.png

image.png

image.png

image.png

Learnedを作ってみる

image.png

Data LabelingからGetTimeのIntentに"What time is it in London?" のLondonを選択し、LocationのEntityを追加する。
image.png

Listを定義する

image.png

さっきと同じ感じで選択。
image.png

Prebuiltを選ぶ

Boolean, DateTime, Email, IPAddress等色々ある。
今回はDateTimeを選択。
image.png

image.png

※Microsoft Outlookとかで時間が本文に入っているときに会議を自動的に作る機能とかこういう処理が裏でされているのかなと思ったり。

動作確認

Entityを変更した後は、再度トレーニング、再デプロイする。
先ほどのEntityで定義した部分が抽出されている。

{
    "query": "what time is it in Tokyo?\n",
    "prediction": {
        "topIntent": "GetTime",
        "projectKind": "Conversation",
        "intents": [
            {
                "category": "GetTime",
                "confidenceScore": 0.87871605
            },
            {
                "category": "GetDay",
                "confidenceScore": 0.71863574
            },
            {
                "category": "GetDate",
                "confidenceScore": 0.7082026
            },
            {
                "category": "None",
                "confidenceScore": 0
            }
        ],
        "entities": [
            {
                "category": "Location ",
                "text": "Tokyo",
                "offset": 19,
                "length": 5,
                "confidenceScore": 1
            }
        ]
    }
}

{
    "query": "what's the date on Weds?",
    "prediction": {
        "topIntent": "GetDate",
        "projectKind": "Conversation",
        "intents": [
            {
                "category": "GetDate",
                "confidenceScore": 0.9679488
            },
            {
                "category": "GetDay",
                "confidenceScore": 0.95016205
            },
            {
                "category": "GetTime",
                "confidenceScore": 0.8293059
            },
            {
                "category": "None",
                "confidenceScore": 0
            }
        ],
        "entities": [
            {
                "category": "Weekday",
                "text": "Weds",
                "offset": 19,
                "length": 4,
                "confidenceScore": 1
            },
            {
                "category": "Date",
                "text": "Weds",
                "offset": 19,
                "length": 4,
                "confidenceScore": 1,
                "resolutions": [
                    {
                        "resolutionKind": "DateTimeResolution",
                        "dateTimeSubKind": "Date",
                        "timex": "XXXX-WXX-3",
                        "value": "2024-04-03"
                    },
                    {
                        "resolutionKind": "DateTimeResolution",
                        "dateTimeSubKind": "Date",
                        "timex": "XXXX-WXX-3",
                        "value": "2024-04-10"
                    }
                ],
                "extraInformation": [
                    {
                        "extraInformationKind": "EntitySubtype",
                        "value": "datetime.date"
                    }
                ]
            }
        ]
    }
}

ちょっと面白かったのが、わざとUttenranceやSynonymで定義していない誤字を入れてみてもちゃんと抽出してくれた。ただし、当たり前だけど正しいものに訂正とかはしてくれないみたいだ。

{
    "query": "what's the date on Wenedsday?",
    "prediction": {
        "topIntent": "GetDate",
        "projectKind": "Conversation",
        "intents": [
            {
                "category": "GetDate",
                "confidenceScore": 0.9753281
            },
            {
                "category": "GetDay",
                "confidenceScore": 0.96795267
            },
            {
                "category": "GetTime",
                "confidenceScore": 0.8847069
            },
            {
                "category": "None",
                "confidenceScore": 0
            }
        ],
        "entities": [
            {
                "category": "Date",
                "text": "Wenedsday",
                "offset": 19,
                "length": 9,
                "confidenceScore": 1,
                "extraInformation": [
                    {
                        "extraInformationKind": "EntitySubtype",
                        "value": "datetime.date"
                    }
                ]
            }
        ]
    }
}

アプリから呼び出し

HomeBotとかの開発だと、通信にはSDKを使うため詳細は省略。

curl -X POST "https://{endpoint}.cognitiveservices.azure.com/language/:analyze-conversations?api-version=2022-10-01-preview" 
-H "Ocp-Apim-Subscription-Key: {Key}"  
-H "Apim-Request-Id: {id}" 
-H "Content-Type: application/json" 
-d "{\"kind\":\"Conversation\",
\"analysisInput\":{
\"conversationItem\":{
\"id\":\"PARTICIPANT_ID_HERE\",
\"text\":\"YOUR_QUERY_HERE\",
\"modality\":\"text\",
\"language\":\"QUERY_LANGUAGE_HERE\",
\"participantId\":\"PARTICIPANT_ID_HERE\"}},
\"parameters\":{\"projectName\":\"Clock\",
\"verbose\":true,
\"deploymentName\":\"production\",
\"stringIndexType\":\"TextElement_V8\"}}"

流れ的にはIntentsからConfidenceScoreが一番高いものを選択し、それからEntitiesを抽出し、独自のカスタム処理を実施させていく感じになる。

テキストを分類する (Text Classification)

プロジェクト作成

Storage Accountに配置したファイルを分類するため、Storage Accountが必須。

image.png

分類先をSingle CategoryとMulti Categoryで選べる。
image.png

手動ラベリング

Storage Accountに配置したファイルが表示されるので自分でラベルをつける。この際に、データをテストデータにするかか、トレーニングデータにするかを選べる。
image.png

こちらはまだPreviewのようだが、OpenAIで自動的に分類させることもできるみたい。
image.png

Training

image.png

モデルの精度が表示される。テストデータを使っていて、100%ではない場合、手動でラベリングしたものとモデルの結果が異なるということ。
image.png

 正しい分類とは、実際のラベルが x のときに、モデルでラベルが x と予測される場合です。 実際には、分類が正しくない場合のドキュメントのエラーにはさまざまな種類があります。

- 擬陽性 - モデルによる予測は x ですが、ファイルには x というラベルが付けられていません。
- 擬陰性 - モデルによる予測はラベル x ではありませんが、ファイルには実際には x というラベルが付けられています。
これらのメトリックは、Azure AI Language によって提供される 3 つのメジャーに変換されます。

-リコール - すべての実際のラベルのうち、識別された数。ラベル付けされたすべてのものに対する真陽性の割合。
-精度 - 予測されたラベルのうち正しいものの数。識別されたすべての陽性に対する真陽性の割合。
-F1 スコア - 各コンポーネントのバランスを最大化するために 1 つのスコアを提供することを目的とした、"リコール" と "精度" の関数

要はリコールは検出率、精度は検出して正確にラベル付けできた割合。

この辺をもとにテストデータを追加して精度を改善していく。

ちなみにTraining後にはStorage Accountにキャッシュ?が作成されていた。
image.png

Deploy

image.png

curl -X POST "https://{endpoint}.cognitiveservices.azure.com/language/analyze-text/jobs?api-version=2022-10-01-preview" 
-H "Ocp-Apim-Subscription-Key: {key}" 
-H "Content-Type: application/json" 
-d "{\"tasks\":[{\"kind\":\"CustomSingleLabelClassification\",
\"parameters\":{\"projectName\":\"ClassifyLab\",
\"deploymentName\":\"articles\"}}],
\"displayName\":\"CustomTextPortal_CustomSingleLabelClassification\",
\"analysisInput\":{\"documents\":[{\"id\":\"document_CustomSingleLabelClassification\",
\"text\":\"YOUR_DOCUMENT_HERE\",
\"language\":\"YOUR_DOCUMENT_LANGUAGE_HERE\"}]}}"

Test

他のに比べて大分レスポンスがシンプル。

{
    "classes": [
        {
            "category": "News",
            "confidenceScore": 0.36
        }
    ]
}

カスタム固有表現認識 (Custom named entity recognition)

テキスト ドキュメントからあらかじめ定義されたエンティティを抽出する。エンティティは、人、場所、物、イベント、スキル、または値。上でやった会話理解とかなり似ている気がする。。。

最初に

プロジェクトを作成。
image.png

image.png

Data Labeling

ラベルを作成し、手動で文章の該当部分をピックアップ。
ここではItemForSale、Price、Locationの3つをラベリングしていく。
image.png

ちなみに1個だけ手動でやって、それ以外はGPTによるAuto-labelingを使ってみたところちゃんとラベリングされた。ただ結局手動でOKを確定しなくてはいけないらしく、ここをちゃんとしないとTrainingができない。

image.png

Training

image.png

たまたまかもしれないけどやたらと時間がかかった。。。

Model Performance

image.png

- Precision	すべての試行された認識に対する成功した表現認識の比率。 高いスコアは、エンティティが認識されている限り、正しくラベル付けされることを意味します。
- Recall	ドキュメントの実際のエンティティの数に対する成功した表現認識の比率。 高いスコアは、適切なラベルが割り当てられているかどうかに関係なく、エンティティを適切に検出できたことを意味します
- F1 スコア	単一のスコアリング メトリックを提供する精度とリコールの組み合わせ

要するに、Recallは検出できるかの指標、Precisionは検出できたものが正しくラベル付けされているかということらしい。

image.png

これはFalse Positiveとなっていて、普通に回答ミス。70 lbの重さとPriceを勘違いしてしまっている。
image.png

こういうデータを元に、必要なトレーニングデータを追加していく。

Deploy

image.png

curl -X POST "https://{endpoint}.cognitiveservices.azure.com/language/analyze-text/jobs?api-version=2022-10-01-preview" 
-H "Ocp-Apim-Subscription-Key: {key}" 
-H "Content-Type: application/json" 
-d "{\"tasks\":[{
\"kind\":\"CustomEntityRecognition\",
\"parameters\":{
\"projectName\":\"CustomEntityLab\",
\"deploymentName\":\"AdEntities\",
\"stringIndexType\":\"TextElement_v8\"}}],
\"displayName\":\"CustomTextPortal_CustomEntityRecognition\",
\"analysisInput\":{\"documents\":[{\"id\":\"document_CustomEntityRecognition\",
\"text\":\"YOUR_DOCUMENT_HERE\",
\"language\":\"YOUR_DOCUMENT_LANGUAGE_HERE\"}]}}"

Test

文章を与えると、ItemForSale、Price、Locationを抽出してくれる。

{
    "entities": [
        {
            "text": "Glass L Shaped desk",
            "category": "ItemForSale",
            "offset": 0,
            "length": 19,
            "confidenceScore": 0.99
        },
        {
            "text": "$100",
            "category": "Price",
            "offset": 22,
            "length": 4,
            "confidenceScore": 1
        },
        {
            "text": "downtown Detroit MI",
            "category": "Location",
            "offset": 177,
            "length": 19,
            "confidenceScore": 0.99
        }
    ]
}

Azure AI 翻訳 (Azure AI Translator)

機能は3つ。音訳というのは中々面白い。

  • 言語検出
[
  {
    "language": "ja",
    "score": 1.0,
    "isTranslationSupported": true,
    "isTransliterationSupported": true
    
    
   }
]
  • 翻訳
[
  {"translations": 
    [
      {"text": "Hello", "to": "en"},   
      {"text": "Bonjour", "to": "fr"}
    ]
  }
]
  • 表記変換(音訳)
curl -X POST "https://api.cognitive.microsofttranslator.com/transliterate?api-version=3.0&fromScript=Jpan&toScript=Latn" 
-H "Ocp-Apim-Subscription-Key: <your-key>" 
-H "Ocp-Apim-Subscription-Region: <your-service-region>" 
-H "Content-Type: application/json" 
-d "[{ 'Text' : 'こんにちは' }]"

[
    {
        "script": "Latn",
        "text": "Kon'nichiwa"
    }
]

カスタム翻訳モデル

カスタム翻訳ツールポータルがあるので、こちらでWorkspace, Projectを作成。Domainというのを選べて、業界用語的なところに対応してくれるのかな?
image.png

image.png

HandsOnがAPIメインでつまらなかったので、こちらにQuickStartをやってみる。

トレーニング

人が翻訳した望ましい翻訳文を英語とドイツ語でアップロードする。その他辞書ファイルとかもアップできるらしい。

image.png

image.png

取り込まれた。
image.png

Trainingしてみる。
10,000 unique training sentences required.とあり、Trainingだけで60ドル近くかかってしまう、かつ数時間かかるらしい。。
image.png

ので、ここはドキュメントからスクショを拝借。BLEUスコアという翻訳の品質を測るスコアがあるらしい。
image.png

Deploy

あとはデプロイして、API経由で発行するだけ。

普通にただ翻訳したいだけならこうだが、

https://api.cognitive.microsofttranslator.com/translate?api-version=3.0

[
    {"Text":"Where can I find my employee details?"}
]

カスタムモデルを利用して翻訳する場合はCategory IDを付与する必要がある。

Category ID は、WorkspaceID、プロジェクト ラベル、およびカテゴリ コードを連結して作成されます。

https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=de&category=a2eb72f9-43a8-46bd-82fa-4693c8b64c3c-TECH

音声

  • 音声テキスト変換
  • テキスト読み上げ(音声合成)
  • Speech Translation
  • Speaker Recognition(音声に基づいて個々の話者を認識)
  • 意図認識(音声入力の意味論的意味を判断する API)

ちょっと色々機能が多すぎるので、今は記載しない。後で別にまとめるかも。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0