- OpenAI : 透過 API 呼叫 OpenAI 的 LLM 模型
- Decision : 異常偵測, 個人化工具, 內容仲裁等
- Language : 文字分析, 語言理解, 翻譯工具, QnA 等
- Speech : 文轉音, 音轉文, 語者辨識, 語音翻譯等
- Vision : 電腦視覺, 臉孔辨識等
認知服務是微軟以 IBM 認知計算概念為基礎所提出的一種雲端服務, 讓服務開發者不需要具備豐富的機器學習與資料科學技能, 只要熟悉 REST API 用法即可輕鬆將 AI 認知智慧導入應用程式中.
參考 :
本篇是我閱讀 "Python 人工智慧程式設計入門-使用 Microsoft Azure 雲端服務" 這本書的第 9 章 "文字分析" 的語言偵測 (language detection) 後所進行的實測紀錄.
文字分析 (text analysis) 屬於 Azure AI 服務中 Language 功能, 它內建自然語言處理 (NLP) 功能可用來進行語言偵測, 情感分析, 關鍵字擷取, 與具名實體 (NER) 辨識等分析, 參考 :
認知服務的文字分析 API 教學文件參考 :
應用程式範例放在 GitHub, 可參考不同程式語言之範例 :
舊版 (v3.0) 的文字分析 API 範例參考 :
書裡面的範例就是採用 v3.0 API.
在前一篇測試中, 我們已經在 Azure 雲端建立了一個資源群組與一個執行個體, 藉此取得了資源的端點 (即服務網址) 與存取該資源所需之金鑰. 本篇則要在應用程式中用它們來存取已建立的 Azure 資源以便進行文字分析任務.
一. 語言偵測 (Language detection) :
此功能可以辨識出輸入文本是屬於哪一種人類語言, 此功能利用 Azure AI 的機器學習與 NLP 演算法辨識輸入的文本是屬於哪一種人類語言 (包含變體與方言), 這在設計支援多國語言的 AI 應用服務時很有用, 參考 :
按 "快速入門" 超連結 :
底下有一個 "必要條件", 這些我們在前一篇中已完成, 透過建立資源群組與執行個體, 取得了資源的端點 (即網址) 與存取它所需之金鑰 :
開發者可使用 C#, JAVA, JavaScript, 或 Python 等程式語言以 REST API 方式向 Azure AI 資源提出要求來取得回應. 點選 Python, 底下會出現使用 Python 存取文字分析資源的範例, 但必須先安裝 Azure AI 文字分析的用戶端套件 azure-ai-textanalytics :
pip install azure-ai-textanalytics==5.2.0
D:\python\test>pip install azure-ai-textanalytics==5.2.0
Collecting azure-ai-textanalytics==5.2.0
Downloading azure_ai_textanalytics-5.2.0-py3-none-any.whl (239 kB)
239.3/239.3 kB 1.0 MB/s eta 0:00:00
Collecting azure-core<2.0.0,>=1.24.0 (from azure-ai-textanalytics==5.2.0)
Downloading azure_core-1.29.6-py3-none-any.whl.metadata (36 kB)
Collecting msrest>=0.7.0 (from azure-ai-textanalytics==5.2.0)
Downloading msrest-0.7.1-py3-none-any.whl (85 kB)
85.4/85.4 kB 2.4 MB/s eta 0:00:00
Collecting azure-common~=1.1 (from azure-ai-textanalytics==5.2.0)
Downloading azure_common-1.1.28-py2.py3-none-any.whl (14 kB)
Requirement already satisfied: typing-extensions>=4.0.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from azure-ai-textanalytics==5.2.0) (4.9.0)
Requirement already satisfied: anyio<5.0,>=3.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (3.7.1)
Requirement already satisfied: requests>=2.21.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (2.31.0)
Requirement already satisfied: six>=1.11.0 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (1.16.0)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from msrest>=0.7.0->azure-ai-textanalytics==5.2.0) (2023.7.22)
Collecting isodate>=0.6.0 (from msrest>=0.7.0->azure-ai-textanalytics==5.2.0)
Downloading isodate-0.6.1-py2.py3-none-any.whl (41 kB)
41.7/41.7 kB 2.1 MB/s eta 0:00:00
Requirement already satisfied: requests-oauthlib>=0.5.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from msrest>=0.7.0->azure-ai-textanalytics==5.2.0) (1.3.1)
Requirement already satisfied: idna>=2.8 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from anyio<5.0,>=3.0->azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (3.4)
Requirement already satisfied: sniffio>=1.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from anyio<5.0,>=3.0->azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (1.3.0)
Requirement already satisfied: exceptiongroup in c:\users\tony1\appdata\roaming\python\python310\site-packages (from anyio<5.0,>=3.0->azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (1.1.3)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests>=2.21.0->azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (3.2.0)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests>=2.21.0->azure-core<2.0.0,>=1.24.0->azure-ai-textanalytics==5.2.0) (1.26.16)
Requirement already satisfied: oauthlib>=3.0.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests-oauthlib>=0.5.0->msrest>=0.7.0->azure-ai-textanalytics==5.2.0) (3.2.2)
Downloading azure_core-1.29.6-py3-none-any.whl (192 kB)
192.5/192.5 kB 2.9 MB/s eta 0:00:00
Installing collected packages: azure-common, isodate, azure-core, msrest, azure-ai-textanalytics
Successfully installed azure-ai-textanalytics-5.2.0 azure-common-1.1.28 azure-core-1.29.6 isodate-0.6.1 msrest-0.7.1
然後複製 "快速入門" 中的範例程式碼到編輯器 (我使用 Thonny), 將最前面兩列的 key 與 endpoint 變數換成自己的金鑰與端點網址, 然後存檔 (例如 azure_language_detect_1.py) :
# azure_language_detect_1.py
key = "06f8a834tony4bdbbe264504b196606f" # 此為範例金鑰
endpoint = "https://tony-test1.cognitiveservices.azure.com/"
from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential
# Authenticate the client using your key and endpoint
def authenticate_client():
ta_credential = AzureKeyCredential(key)
text_analytics_client = TextAnalyticsClient(
endpoint=endpoint,
credential=ta_credential)
return text_analytics_client
client = authenticate_client() # 傳回 TextAnalyticsClient 物件
# Example method for detecting the language of text
def language_detection_example(client):
try:
documents = ["Ce document est rédigé en Français."]
response = client.detect_language(documents = documents, country_hint = 'us')[0]
print("Language: ", response.primary_language.name)
except Exception as err:
print("Encountered exception. {}".format(err))
language_detection_example(client)
然後直接執行 :
>>> %Run azure_language_detect.py
Language: French
可見得到正確輸出 (偵測到法語).
這個範例與書本上的舊版程式碼差很多, 上面的程式定義了兩個函式 :
- authenticate_client() :
利用所匯入的 AzureKeyCredential() 與 TextAnalyticsClient() 來驗證用戶端應用程式的存取權, 不管驗證是否成功, 它都會傳回一個 TextAnalyticsClient 物件. - language_detection_example() :
呼叫傳回的 TextAnalyticsClient 物件之 detect_language() 方法偵測文本是哪種語言, 傳入參數 documents 為待測文本組成之串列 (可同時偵測多個不同語言之句子), 傳回一個 DetectLanguageResult 物件 (內容為一個兩層的字典), 偵測結果可用其primary_language.name 或 ['primary_language']['name'] 屬性取得.
以下是在互動環境中拆解執行步驟 :
首先匯入函式 :
>>> from azure.ai.textanalytics import TextAnalyticsClient
>>> from azure.core.credentials import AzureKeyCredential
接著定義認證用的金鑰與端點變數 :
>>> key='06f8a834tony4bdbbe264504b196606f' # 此為範例金鑰
>>> endpoint='https://tony-test1.cognitiveservices.azure.com/'
然後呼叫 AzureKeyCredential() 並傳入 key 進行驗證, 它會傳回一個 AzureKeyCredential 物件 (驗證用) :
>>> ta_credential=AzureKeyCredential(key)
>>> type(ta_credential)
<class 'azure.core.credentials.AzureKeyCredential'>
接下來就可以呼叫 TextAnalyticsClient() 並傳入端點位址與 AzureKeyCredential 驗證物件, 它會傳回一個 TextAnalyticsClient 物件 (分析用) :
>>> client=TextAnalyticsClient(endpoint=endpoint, credential=ta_credential)
>>> type(client)
<class 'azure.ai.textanalytics._text_analytics_client.TextAnalyticsClient'>
注意, 不管金鑰與端點正確與否, 都會傳回一個 TextAnalyticsClient 物件, 但錯誤的金鑰或端點在後續做分析時會拋出例外.
然後就可以建立一個待測句子串列 (可以一次偵測多個文本), 將它傳給 TextAnalyticsClient 物件的 detect_language() 測試, 傳回值是一個 DetectLanguageResult 物件 (類似字典) 組成的串列, 待測句子有幾個, 傳回串列裡就有幾個相對應的 DetectLanguageResult 物件, 先以上面的法文句子為例 :
>>> docs=['Ce document est rédigé en Français.'] # 待偵測之文本串列
>>> response=client.detect_language(documents=docs)
>>> type(response)
<class 'list'>
>>> len(response)
1
>>> type(response[0])
<class 'azure.ai.textanalytics._models.DetectLanguageResult'>
可見傳入串列, 傳回值也是陣列, 裡面只有一個元素, 是一個類似字典的 DetectLanguageResult 物件, 查看 response 內容 :
>>> response
[DetectLanguageResult(id=0, primary_language=DetectedLanguage(name=French, iso6391_name=fr, confidence_score=1.0), warnings=[], statistics=None, is_error=False)]
可見偵測的結果放在 primary_language 這個 key 的值 (是一個 DetectedLanguage 物件) 裡面, 只要用 name 這個 key 即可取得偵測結果, 可以使用點運算子, 也可以使用 [] 運算子 :
>>> response[0].primary_language.name
'French'
>>> response[0]['primary_language']['name']
'French'
可以一次傳入多個句子去偵測, 例如下面中, 日, 韓, 英, 法五種語言六種文本的 '我愛你' :
>>> docs=['我爱你', "Je t'aime", 'I love you', '我愛你', '愛してます', '사랑해요']
>>> response=client.detect_language(documents=docs, country_hint = 'us')
>>> response
[DetectLanguageResult(id=0, primary_language=DetectedLanguage(name=Chinese_Simplified, iso6391_name=zh_chs, confidence_score=1.0), warnings=[], statistics=None, is_error=False), DetectLanguageResult(id=1, primary_language=DetectedLanguage(name=English, iso6391_name=en, confidence_score=1.0), warnings=[], statistics=None, is_error=False), DetectLanguageResult(id=2, primary_language=DetectedLanguage(name=English, iso6391_name=en, confidence_score=1.0), warnings=[], statistics=None, is_error=False), DetectLanguageResult(id=3, primary_language=DetectedLanguage(name=Chinese_Traditional, iso6391_name=zh_cht, confidence_score=1.0), warnings=[], statistics=None, is_error=False), DetectLanguageResult(id=4, primary_language=DetectedLanguage(name=Japanese, iso6391_name=ja, confidence_score=1.0), warnings=[], statistics=None, is_error=False), DetectLanguageResult(id=5, primary_language=DetectedLanguage(name=Korean, iso6391_name=ko, confidence_score=1.0), warnings=[], statistics=None, is_error=False)]
輸入幾個句子就會傳回幾個偵測結果, 我們可以用迴圈來列出偵測結果 :
>>> for r in response:
print(f'句子 {int(r.id) + 1} 語言: {r.primary_language.name}')
句子 1 語言: Chinese_Simplified
句子 2 語言: English (錯誤)
句子 3 語言: English
句子 4 語言: Chinese_Traditional
句子 5 語言: Japanese
句子 6 語言: Korean
除了句子 2 偵測錯誤 (應該是 French) 外, 其餘都正確. 錯誤原因可能是句子太短, 偵測模型把它誤認為是英語.
我們可以用內建函式 enumerate() 來改善上面的輸出結果 :
>>> for id, r in enumerate(response):
print(f'"{docs[id]}" : {r.primary_language.name}')
"我爱你" : Chinese_Simplified
"Je t'aime" : English
"I love you" : English
"我愛你" : Chinese_Traditional
"愛してます" : Japanese
"사랑해요" : Korean
函式 enumerate() 會傳回 response 串列元素 id 與元素值組成之 tuple 串列, 這樣便能取得元素之 id, 它的順序是與傳入參數 docs 內的文本是對應的, 因此可用來取得對應之輸入文本. 關於 enumerate() 用法參考 :
在上面測試中我們將金鑰直接以明碼寫在 key 變數中, 這在用 Colab 做教學或分享到 GitHub 時很容易不慎將金鑰洩漏出去, 比較好的做法是將金鑰儲存在系統變數中, 用到時再取出來, 作法參考下面這篇 :
先用記事本將金鑰記在常數名稱 AZURE_AI_API 內, 例如 :
AZURE_AI_API=06f8a834tony4bdbbe264504b196606f
然後以 utf-8 格式儲存為 .env 檔. 接著用 pip install 安裝 python-dotenv 套件, 就可以從 dotenv 匯入 load_dotenv() 函式來載入系統變數, 利用 os.load_environ.get('AZURE_AI_API') 來載入金鑰.
茲將上面測試程式碼寫成如下單一程式檔 :
# azure_ai_detect_language.py
import os
from dotenv import load_dotenv
from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential
def authenticate_client(endpoint, key):
credential=AzureKeyCredential(key)
client=TextAnalyticsClient(endpoint=endpoint,
credential=credential)
return client
if __name__ == '__main__':
load_dotenv()
key=os.environ.get('AZURE_AI_API')
endpoint='https://tony-test1.cognitiveservices.azure.com/'
client=authenticate_client(endpoint, key)
docs=['我爱你',
"Je t'aime",
'I love you', '我愛你',
'愛してます',
'사랑해요']
response=client.detect_language(documents=docs)
for id, r in enumerate(response):
print(f'"{docs[id]}" : {r.primary_language.name}')
執行結果如下 :
>>> %Run azure_ai_detect_language.py
"我爱你" : Chinese_Simplified
"Je t'aime" : English (錯誤)
"I love you" : English
"我愛你" : Chinese_Traditional
"愛してます" : Japanese
"사랑해요" : Korean
原始碼存放於 GitHub :
沒有留言:
張貼留言