SpaCy 的 NLP 任務管線中最重要的是語法相依關係, 這在機器理解自然語言上有關鍵的作用 (例如訂票系統判斷客戶是否要訂票等), 這個語法相依關係是放在 Token 物件的 head 屬性與 dep_ 屬性中, 但光從這兩個欄位並不容易判讀句法關係, 因此 SpaCy 內建了displayCy 這個 visualizer (繪圖模組) 來展示文句中各 Token 物件之間的語法相依關係, 也可以標記命名實體 (NER, named entity recognition), 參考 :
本系列之前的文章參考 :
一. 在本機中使用 displayCy :
在本機使用 displayCy 做視覺化首先須匯入 displacy 模組, 然後呼叫其 serve() 函數, 並傳入語言物件與指定style 參數為 'dep', 格式如下 :
displaycy.serve(doc, [style='dep', port=5000, options=None])
這樣會在本機建立一個預設埠為 5000 的網頁伺服器, 並將所傳入之 Doc 物件的 POS 標註與語法相依關係圖繪製於此網頁中. 備選參數說明如下 :
- style : 指定欲繪製的對象, 預設 'dep' 為語法關係圖, 若設為 'ent' 為標記命名實體.
- port : 網頁伺服器埠號, 預設為 5000
- options : 型態為字典之選項設定, 可用之鍵如下 :
- 'bg' : 背景色, 值可為 16 進位色碼, 顏色名稱, (R, G, B) 元組
- 'compact' : 是否以緊湊方式繪圖 (方形線取代弧線), 預設 False
- 'color' : 線條色彩, 值可為 16 進位色碼, 顏色名稱, (R, G, B) 元組
- 'font' : 字型名稱, 例如 'Arial'
注意, options 字典中的鍵必須為字串, 且其設定僅在 style='dep' 時有作用.
例如 :
測試 1 : 呼叫 displacy.render() 建立網頁伺服器以呈現語法相依圖 [看原始碼]
import spacy
from spacy import displacy
nlp=spacy.load('en_core_web_sm')
doc=nlp('I live in Taiwan.')
displacy.serve(doc) # 預設繪製語法關係圖
此例於呼叫 displacy.serve() 時僅傳入 doc 物件, 預設是繪製語法關係圖 (style='dep'), 執行後會顯示如下結果 (在 Thonny 中執行) :
>>> %Run displacy_test_1.py
2022-03-20 14:58:12.357184: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cudart64_101.dll'; dlerror: cudart64_101.dll not found
2022-03-20 14:58:12.357541: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
Using the 'dep' visualizer
Serving on http://0.0.0.0:5000 ...
可見未傳入 style 參數時確實是預設啟動 dep 繪圖器, 底下會出現網頁伺服器位址為 0.0.0.0:5000 的提示, 但不要用 0.0.0.0 這網址去開啟 (因瀏覽器安全性限制無法開啟), 而是要改用 127.0.0.1 或 localhost, 結果如下 :
可見 displayCy 會以弧線箭頭來表示每個 Token 的語法相依關係 (由 parent 指向 child), Token 底下的是 POS 詞類標註 (即 pos_ 欄位值), 弧線上的是語法相依性標註 (即 dep_ 欄位值). 按 Ctrl+C 可以停止此網頁伺服器.
可以用迴圈走訪 doc 物件的各 Token, 顯示 tag_, pos_, 與 dep_ 等欄位來比對觀察 :
import spacy
nlp=spacy.load('en_core_web_sm')
doc=nlp('I live in Taiwan.')
print(f'text\tlemma_\ttag_\tpos_\tdep_\thead')
for token in doc:
fstr=(f'{token.text}\t{token.lemma_}\t{token.tag_}\t{token.pos_}\t'
f'{token.dep_}\t{token.head}')
print(fstr)
下面是添加 options 選項參數的範例 :
import spacy
from spacy import displacy
nlp=spacy.load('en_core_web_sm')
doc=nlp('I live in Taiwan.')
displacy.serve(doc, options={'color': '#0000ff',
'bg': 'cyan',
'compact': True,
'font': 'Arial'})
此例傳入 options 參數, 設定字型, 背景與前景色, 以及用緊湊方式繪圖, 結果如下 :
可見關係線從較占空間的弧線改為較緊緻的方形線, 顏色也照設定值改變了.
除了繪製語法相依圖外, 也可以傳入 style='ent' 來標記文句中的命名實體 (named entity), 例如 :
測試 4 : 標記文句中的命名實體 (NER) [看原始碼]
import spacy
from spacy import displacy
nlp=spacy.load('en_core_web_sm')
doc=nlp('I live in Taiwan.')
displacy.serve(doc, style='ent')
此例傳入 style='ent' 表示要繪製所標記的命名實體, 結果如下 :
可見 displayCy 將句中的命名實體 Taiwan 以高亮背景色標記出來了, 且打上 GPE 的標註, 表示這是一個地理上的名稱 (包含國家, 城市, 或省市州郡等).
Doc 物件中的每個 Token 都有一個 ent_type_ 屬性, 若該 Token 被辨識出來是一個命名實體, 則該屬性欄會被填入命名實體類型名稱, 將此類型名稱傳入 spacy.explain() 函式會傳回該類型之解釋, 若該 Token 不是命名實體則傳回 None, 例如 :
測試 4-1 : 走訪 Token 物件檢視 ent_type_ 屬性與其解釋 [看原始碼]
import spacy
from spacy import displacy
nlp=spacy.load('en_core_web_sm')
doc=nlp('I live in Taiwan.')
print('Token\tent_type_\texplain')
for token in doc:
print(f'{token.text}\t{token.ent_type_}\t{spacy.explain(token.ent_type_)}')
此例以迴圈走訪 Doc 物件, 並列印各 Token 的 ent_type_ 屬性與其解釋, 結果如下 :
二. 在 Jupyter Notebook 上使用 displayCy :
以上在本機命令列的操作也可以在 Jupyter Notebook 的網頁介面上執行, 但繪圖指令不是用 displacy.serve(), 而是要改用 displaycy.render(), 其介面與 displacy.serve() 類似 :
displaycy.render(doc, [style='dep', options=None])
首先在命令提示字元視窗輸入 jupyter lab, 這是新版的 Jupyter, 其安裝參考 :
D:\Python\test>jupyter lab
[I 23:20:18.791 LabApp] JupyterLab extension loaded from c:\python37\lib\site-packages\jupyterlab
[I 23:20:18.791 LabApp] JupyterLab application directory is c:\python37\share\jupyter\lab
[I 23:20:18.803 LabApp] Serving notebooks from local directory: D:\Python\test
[I 23:20:18.803 LabApp] The Jupyter Notebook is running at:
[I 23:20:18.804 LabApp] http://localhost:8888/?token=7db060eaec8fe94b1ef39f8377e47ca5bd048846441d00a7
[I 23:20:18.808 LabApp] or http://127.0.0.1:8888/?token=7db060eaec8fe94b1ef39f8377e47ca5bd048846441d00a7
[I 23:20:18.809 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 23:20:18.957 LabApp]
To access the notebook, open this file in a browser:
file:///C:/Users/User/AppData/Roaming/jupyter/runtime/nbserver-8756-open.html
Or copy and paste one of these URLs:
http://localhost:8888/?token=7db060eaec8fe94b1ef39f8377e47ca5bd048846441d00a7
or http://127.0.0.1:8888/?token=7db060eaec8fe94b1ef39f8377e47ca5bd048846441d00a7
[I 23:20:22.135 LabApp] Build is up to date
[I 23:20:23.208 LabApp] Kernel started: 2285a805-2962-4f9c-9f52-61cb9a37d7f4
2022-03-20 23:20:49.178605: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cudart64_101.dll'; dlerror: cudart64_101.dll not found
2022-03-20 23:20:49.178949: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
[I 23:22:22.899 LabApp] Saving file at /Untitled.ipynb
[I 23:24:07.160 LabApp] Creating new notebook in /
[I 23:24:07.435 LabApp] Kernel started: 82934c28-4c3a-48e2-b16b-5b4b95fd06c3
[I 23:26:07.470 LabApp] Saving file at /Untitled1.ipynb
這會自動開啟 Jupyter Notebook 網頁, 然後在方框中輸入如下的指令按上方的 Play 鍵執行 :
import spacy
nlp=spacy.load('en_core_web_sm')
doc=nlp('I live in Taiwan.')
spacy.displacy.render(doc)
結果如下 :
接著輸入下面兩個指令 :
spacy.displacy.render(doc, style='ent')
spacy.displacy.render(doc, options={'color': '#0000ff','bg': 'cyan', 'compact': True, 'font': 'Arial'})
結果如下 :
可見在 Jupyter Notebook 上執行 spacy visualization 也是非常方便的.
三. 使用 Spacy 的線上視覺化功能 :
除了在本機自行做視覺化外, 還可以利用 Spacy 官網上所提供的視覺化功能, 語法相依關係圖的網址如下 :
其中 Text to parse 欄位用來輸入要分析的文句, Model 欄位用來挑選語言的統計模型 (預設是英文的 en_core_web_sm), 下方預設已勾選的 Merge Punctuation 用來設定是否要將標點符號與其前一個 Token 合併 (這樣會使圖形更緊湊), 而 Merge Phrases 則用來設定是否要將形容詞與其後的名詞合併 (同樣會使圖形更緊湊).
預設情形下輸入 "I live in New York." 按 search 鈕結果如下 :
下方兩個選項都不勾選的結果是 :
可見語法圖變得比較詳細但卻較複雜了.
命名實體視覺化的網址如下 :
左上方的輸入框用來輸入句子, 左下方用來選擇語言統計模型, 右方則可勾選要辨認的實體標籤, 例如輸入 "I live in New York." 後按 search 鈕, 結果如下 :
線上視覺化的好處是不用自行安裝語言統計模型, 它已提供下列 13 種模型可用 :
例如選擇最後一項 Chinese 中文 zh_core_seb_sm 這個模型, 然後輸入如下句子 :
戴笠, 浙江省江山縣人, 中華民國陸軍中將, 生於清光緒 23 年, 國民政府軍統局少將副局長, 蔣介石愛將, 民國 35 年 3 月 17 日於南京上空飛機失事身亡.
實體標籤用預設, 按 search 結果如下 :
可見年份 (23 年, 35 年 3 月) 與地點 (浙江省, 南京) 都有辨認出來, 但是人名 (戴笠, 蔣介石), 機構名 (國民政府, 軍統局, 中華民國) 卻沒辨識出來, 應該是模型較小的緣故.
沒有留言:
張貼留言