Azure の Cognitive Service のうち、テキスト分析を学びます。
Microsoft Learn では、次のコンテンツです。
Azure のテキスト分析では、次のようなことが可能です。
- 文章の言語 (フランス語や英語など) の検出
- 文章の感情分析を行い、肯定的または否定的かを検出
- 主な要点を示す可能性のあるキーフレーズを抽出
- 文章内のエンティティを識別して分類。 エンティティとは、人物、場所、組織、または日常的な項目 (日付、時刻、数量など)を指します
Microsoft アカウントと Azure のサブスクリプションを用意しておきます。
準備
Azure Portal で Cognitive Services のページを開きます。
Cognitive Services には、画像系だけでなく、音声や言語など、様々な認識サービスが用意されています。
今回は、言語サービスを使用します。「+作成」を押して、言語サービスを作成します。
作成できたら、左ペインの「キーとエンドポイント」をクリック、キーとエンドポイントページ内のキー1とエンドポイントのURLを控えておきます。
Learn の演習を試す
Microsoft Learn を読み進めると、演習が用意されていますので、これをやってみます。
PowerShell のターミナルを起動し、git コマンドで用意されたプログラムをダウンロードします。
PS git clone https://github.com/MicrosoftLearning/AI-900-AIFundamentals ai-900
ちなみにこのフォルダには、テキスト分析用のサンプルだけでなく、AI-900 で扱うサンプル一式が含まれています。
今回は、「analyze-text.ps1」という Powershell スクリプトを使用します。
エンドポイントとキーを埋め込む
先頭2行にある $key と $endopoint 変数の定義を書き換えます。
$key="YOUR_KEY" # ← ここに言語サービスのキー1を入力します
$endpoint="YOUR_ENDPOINT" # ← ここに言語サービスのエンドポイントを入力します
# Code to call Text Analytics service to analyze sentiment in text
$txt_file = "review1.txt"
保存したら、さっそく実行してみます。
PS c:\ai-900> .\analyze-text.ps1
***Detecting Language***
- Language: English
- Code: en
- Score: 0.99
***Finding Key Phrases***
- Key Phrases:
The Royal Hotel
Good Hotel
good service
great location
Buckingham Palace
Westminster Abbey
same group
West coast
Michelin Star
taster menu
enormous bathroom
Clean rooms
staff
London
UK
stay
courtyard
restaurant
part
plenty
fish
kitchen
lounge
bedroom
***Analyzing Sentiment***
- A positive sentiment based on these scores:
- Positive: 0.97
- Neutral: 0.03
- Negative: 0
***Identifying known entities***
- GOOD Music : https://en.wikipedia.org/wiki/GOOD_Music
- Hotel : https://en.wikipedia.org/wiki/Hotel
- The Royal Hotel : https://en.wikipedia.org/wiki/The_Royal_Hotel
- London : https://en.wikipedia.org/wiki/London
- Buckingham Palace : https://en.wikipedia.org/wiki/Buckingham_Palace
- Westminster Abbey : https://en.wikipedia.org/wiki/Westminster_Abbey
- India : https://en.wikipedia.org/wiki/India
- West Coast Main Line : https://en.wikipedia.org/wiki/West_Coast_Main_Line
- Michelin Guide : https://en.wikipedia.org/wiki/Michelin_Guide
この analyze-text.ps1 では、1回の実行で言語の特定、フェーズの抽出、感情分析、エンティティの抽出を行います。
ちなみに分析の原文(review1.txt)はこちらです。
Clean rooms, good service, great location near Buckingham Palace and Westminster Abbey, and so on. We thoroughly enjoyed our stay. The courtyard is very peaceful and we went to a restaurant which is part of the same group and is Indian ( West coast so plenty of fish) with a Michelin Star. We had the taster menu which was fabulous. The rooms were very well appointed with a kitchen, lounge, bedroom and enormous bathroom. Thoroughly recommended.
結果を順番に見ていきます。
Detecting Language
- Language: English
- Code: en
- Score: 0.99
言語検出では、英語(Code:en)で、Score は 0.99(=99%)となっていて正しく検出できています。
キーフレーズも、単語の検出がうまくできているようです。
感情分析では、ポジティブが 97% でした。原文は素晴らしい旅行の記録ですので適切といえます。
Analyzing Sentiment
- A positive sentiment based on these scores:
- Positive: 0.97
- Neutral: 0.03
- Negative: 0
エンティティとキーフレーズの違いがよく分かりませんが、エンティティの方が主に名詞がピックアップされているような気がします。
日本語文章でテキスト分析を試す
英語の実力は確認できましたので、日本語文章を試してみたいと思います。
言語検出
スクリプトを見てみると、10行目で URL を組み立てて、12行目で https://raw.githubusercontent.com に公開されているテキストをダウンロードし、変数 txt に格納しているのが分かります。
05 $txt_file = "review1.txt"
06 if ($args.count -gt 0 -And $args[0] -in ("review1.txt", "review2.txt", "review3.txt", "review4.txt"))
07 {
08 $txt_file = $args[0]
09 }
10 $url = "https://raw.githubusercontent.com/MicrosoftLearning/AI-900-AIFundamentals/main/data/text/reviews/$txt_file"
11
12 $txt = (Invoke-webrequest -URI $url).Content
この txt 変数の中身が分析対象となっていますので、次のように書き換えます。
05 #$txt_file = "review1.txt"
06 #if ($args.count -gt 0 -And $args[0] -in ("review1.txt", "review2.txt", "review3.txt", "review4.txt"))
07 #{
08 # $txt_file = $args[0]
09 #}
10 #$url = "https://raw.githubusercontent.com/MicrosoftLearning/AI-900-AIFundamentals/main/data/text/reviews/$txt_file"
11
12 #$txt = (Invoke-webrequest -URI $url).Content
13 $txt = "これは日本語文章のテストです。"
注意点
忘れてはならないのが、UTF-8 でのエンコードです。
Powershell では文字列を内部で UTF-16 で管理しています。変数 txt に代入した日本語も、格納されたタイミングで UTF-16 に変換されて管理されます。
txt を JSON にして変数 data に代入し、30 - 33 行目で Invoke-RestMethod を使って API をコールするのですが、API が受け付けてくれるのは UTF-8 ですので、UTF-16 では正しく受け取ってくれません。
20 $data = @{
21 'documents' = @(
22 @{
23 "id" = "1"
24 "text" = "$txt"
25 }
26 )
27 } | ConvertTo-Json
28
29 Write-Host("***Detecting Language***")
30 $result = Invoke-RestMethod -Method Post `
31 -Uri "$endpoint/text/analytics/v3.1/languages" `
32 -Headers $headers `
33 -Body $data | ConvertTo-Json -Depth 6
このため、下の 29行目のように送信データを UTF-8 でエンコードします。
あと、Language の説明ページにもありますが、現行のバージョンの推測エンジン(2022-10-01)では日本語がうまく検出できないそうです。なので、推測モデルのバージョンを2021-11-20 に指定して実行します。
20 $data = @{
21 'documents' = @(
22 @{
23 "id" = "1"
24 "text" = "$txt"
25 }
26 )
27 } | ConvertTo-Json
28
29 $data= [System.Text.Encoding]::UTF8.GetBytes($data) # UTF-8 にコンバートする
30
31 # Uri の文字列にモデルバージョンを指示するコマンドを追加する
32 Write-Host("***Detecting Language***")
33 $result = Invoke-RestMethod -Method Post `
34 -Uri "$endpoint/text/analytics/v3.1/languages?model-version=2021-11-20" `
35 -Headers $headers `
36 -Body $data | ConvertTo-Json -Depth 6
変更ができたら保存して実行してみます。
PS C:\ai-900> .\analyze-text.ps1
***Detecting Language***
- Language: Japanese
- Code: ja
- Score: 1
ちゃんと日本語であると検出できました。
キーフレーズ検出
キーフレーズ検出でも、先ほどの要領で UTF-8 に変換して API をコールします。
あと、日本語であることを伝えるために、下のコードの 52 行目のように language コードを指定します。
45 # Key Phrases
46
47 $data = @{
48 'documents' = @(
49 @{
50 "id" = "1"
51 "text" = "$txt"
52 "language" = "ja" # 言語を指定する
53 }
54 )
55 } | ConvertTo-Json
56
57 $data= [System.Text.Encoding]::UTF8.GetBytes($data) # UTF-8 にコンバートする
58
59 write-host "`n`n***Finding Key Phrases***"
60 $result = Invoke-RestMethod -Method Post `
61 -Uri "$endpoint/text/analytics/v3.1/keyPhrases" `
62 -Headers $headers `
63 -Body $data | ConvertTo-Json -Depth 6
64
65 $analysis = ($result | ConvertFrom-Json)
66
67 $keyPhrases = $analysis.documents.keyPhrases
編集して保存したら実行します。
PS C:\ai-900> .\analyze-text.ps1
***Detecting Language***
- Language: Japanese
- Code: ja
- Score: 1
***Finding Key Phrases***
- Key Phrases:
日本語文章
テスト
「日本語文章」と「テスト」が検出できました。
感情分析
キーフレーズと全く同じように、UTF-8 へのコンバート、language の指定を行います。
***Analyzing Sentiment***
- A neutral sentiment based on these scores:
- Positive: 0.01
- Neutral: 0.99
- Negative: 0
ナチュラルが 99% となってます。
ポジティブさもネガティブさも検出されず、機能の確認ができません。
感情分析としてはサンプルがよくなかったかもしれません。
そこで変数 txt の値を「メロスは激怒した。」に変えて実行してみます。
10 #$url = "https://raw.githubusercontent.com/MicrosoftLearning/AI-900-AIFundamentals/main/data/text/reviews/$txt_file"
11
12 #$txt = (Invoke-webrequest -URI $url).Content
13 $txt = "メロスは激怒した。"
14
15 $headers = @{}
16 $headers.Add( "Ocp-Apim-Subscription-Key", $key )
17 $headers.Add( "Content-Type","application/json" )
「激怒」は強いネガティブワードです。予想通りの結果になるでしょうか。
***Analyzing Sentiment***
- A negative sentiment based on these scores:
- Positive: 0
- Neutral: 0.01
- Negative: 0.99
ネガティブが 99% になりました。
エンティティ検出
エンティティ検出ですが、英文ならちゃんと検出できますが、日本語ではなにをやっても出力されませんでした。
***Identifying known entities***
エンティティ検出は日本語には対応していないのかもしれません。
言語スタジオ
ここでは Powershell のサンプルから API を利用する方法を試しましたが、Azure ではテキスト分析用に言語スタジオというサイトが用意されています。
言語検出やキーフレーズなどを、Web 上から試すことができます。
まずはどんなものか体験したい!という方は、こちらを最初に使用する方がいいかもしれません。
参考(テキスト分析)
- Language API の仕様
- 検出できる言語について