SkillAgentSearch skills...

Monpa

MONPA 罔拍是一個提供正體中文斷詞、詞性標註以及命名實體辨識的多任務模型

Install / Use

/learn @monpa-team/Monpa

README

罔拍 MONPA: Multi-Objective NER POS Annotator

MONPA 罔拍是一個提供正體中文斷詞、詞性標註以及命名實體辨識的多任務模型,本計劃是將 monpa 包裝成可以 pip install 的 python package (最新版本 v0.3.1)。網站示範版本(https://nlptmu-monpaweb.hf.space/)。

最新版的 monpa model 是使用 pytorch 1.0 框架訓練出來的模型,所以在使用本版本前,請先安裝 torch 1.* 以上版本才能正常使用 monpa 套件。

公告

- 本次更新版本 v0.3.3:#16 升級 torch API 以解決警告訊息
- 更新版本 v0.3.2:解決 issue 10, 11 的建議,新增 short_sentence 斷句功能, cut_mp 及 cut_pseg 多執行程序功能等輔助程式。
- 更新版本 v0.3.1:新增運用 GPU 的批次斷詞功能 cut_batch 及 pseg_batch。
- 版本 v0.3.0:更小,更快,依然準確。完成 pip install 後不需要再另行下載模型檔。
- 公開釋出的 MONPA 僅供學術使用,請勿使用於商業用途。本團隊亦提供針對專業領域客製模型之服務,歡迎聯絡我們。

MONPA v0.2+ 版本是基於 BERT(雙向 Transformer)[1]模型來取得更強健的詞向量(word embeddings)並配合 CRF 同時進行斷詞、詞性標註、及 NER 等多個目標。已與 MONPA v0.1 版本有相當大差異,訓練語料亦與論文內容不同。

MONPA v0.3+ 版本基於 ALBERT [2] 重新訓練,大幅降低模型檔的大小,並加快執行效率。

<a id="1">[1]</a> BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. Jacob Devlin, Ming-Wei Chang, Kenton Lee, Kristina Toutanova, NAACL-HLT 2019.

<a id="2">[2]</a> ALBERT: A Lite BERT for Self-supervised Learning of Language Representations. Zhenzhong Lan, Mingda Chen, Sebastian Goodman, Kevin Gimpel, Piyush Sharma, Radu Soricut, ICLR 2020.

開發正體中文自然語言斷詞套件是一個基礎,接續的研究需要多方支持,歡迎您的捐款

monpa 各版本的斷詞效率比較圖

<img src="./monpa_2vs3.png" style="zoom:24%;" />

以上於 Google Colab 環境測試(monpa.cut 皆使用 CPU,monpa.cut_batch 使用 GPU)

注意

  1. 建議以原文輸入 monpa 完成斷詞後,再視需求濾掉停留字(stopword)及標點符號(punctuation)。
  2. 每次輸入到 monpa 做斷詞的原文超過 200 字元的部分將被截斷丟失,建議先完成合適長度分句後再應用 monpa 斷詞。可參考 wiki 如何將長文切成短句再用 monpa 斷詞?)自行開發或是使用 v0.3.2 (含)之後版本的功能程式 short_sentence 來協助分句。
  3. 支援 python >= 3.6,不支援 python 2.x。

安裝 monpa 套件

monpa 已經支援使用 pip 指令安裝,各作業系統的安裝步驟都相同。

pip install monpa

安裝時將自動檢查有無 torch >= 1.0 及 requests 等套件,若無則由 pip 直接安裝。Windows 作業系統需手動安裝,建議移駕 pytorch.org 取得最適合作業系統版本的安裝指令。

若已經安裝 monpa v0.2.x 版本,可以 pip install --upgrade monpa直接升級或是先以pip uninstall monpa 指令移除舊版本再行安裝新版本。

使用 monpa 的簡單範例

引入 monpa 的 python package。

import monpa

cut function

若只需要中文斷詞結果,請用 cut function,回傳值是 list 格式。簡單範例如下:

sentence = "蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。"
result_cut = monpa.cut(sentence)

for item in result_cut:
    print(item)

輸出

蔡英文
總統
今天
受
邀
參加
台北市政府
所
舉辦
的
陽明山
馬拉松
比賽
。

pseg function

若需要中文斷詞及其 POS 結果,請用 pseg function,回傳值是 list of tuples 格式,簡單範例如下:

sentence = "蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。"
result_pseg = monpa.pseg(sentence)

for item in result_pseg:
    print(item)

輸出

('蔡英文', 'PER')
('總統', 'Na')
('今天', 'Nd')
('受', 'P')
('邀', 'VF')
('參加', 'VC')
('台北市政府', 'ORG')
('所', 'D')
('舉辦', 'VC')
('的', 'DE')
('陽明山', 'LOC')
('馬拉松', 'Na')
('比賽', 'Na')
('。', 'PERIODCATEGORY')

load_userdict function

如果需要自訂詞典,請依下列格式製作詞典文字檔,再使用此功能載入。簡單範例如下:

假設製作一個 userdict.txt 檔,每行含三部分,必須用「空格 (space)」隔開,依次是:詞語、詞頻(數值型態)、詞性(未能確定,請填 NER)。排序是以詞頻數值大者優先,若詞頻數值相同則排列前面者優先。

注意:最後不要留空行或任何空白空間。*

台北市政府 100 NER
受邀 100 V

當要使用自訂詞時,請於執行斷詞前先做 load_userdict,將自訂詞典載入到 monpa 模組。

請將本範例的 ./userdict.txt 改成實際放置自訂詞文字檔路徑及檔名。

monpa.load_userdict("./userdict.txt")

延用前例,用 pseg function,可發現回傳值已依自訂詞典斷詞,譬如「受邀」為一個詞而非先前的兩字分列輸出,「台北市政府」也依自訂詞輸出。

sentence = "蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。"
result_pseg_userdict = monpa.pseg(sentence)

for item in result_pseg_userdict:
    print(item)

輸出

('蔡英文', 'PER')
('總統', 'Na')
('今天', 'Nd')
('受邀', 'V')
('參加', 'VC')
('台北市政府', 'NER')
('所', 'D')
('舉辦', 'VC')
('的', 'DE')
('陽明山', 'LOC')
('馬拉松', 'Na')
('比賽', 'Na')
('。', 'PERIODCATEGORY')

cut_batch function

開始批次斷句前,請先啟動使用 GPU 之設定。

monpa.use_gpu(True)

從 monpa v0.3.1 開始提供應用 GPU 運算能力的 cut_batch function,輸入須為 list 格式,單批次的輸入量需考量 GPU 的記憶體容量,回傳值亦是 list 格式。初次啟動需耗費較多時間,建議若非大量斷詞,可使用 cut function 即可。簡單範例如下:

sentence_list = ["蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。", "蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。"]
result_cut_batch = monpa.cut_batch(sentence_list)

for item in result_cut_batch:
    print(item)

輸出

['蔡英文', '總統', '今天', '受', '邀', '參加', '台北市政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。']
['蔡英文', '總統', '今天', '受', '邀', '參加', '台北市政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。']

pseg_batch function

開始批次斷句前,請先啟動使用 GPU 之設定。

monpa.use_gpu(True)

從 monpa v0.3.1 開始提供應用 GPU 運算能力的 pseg_batch function,輸入須為 list 格式,單批次的輸入量需考量 GPU 的記憶體容量,回傳值亦是 list of turples 格式。初次啟動需耗費較多時間,建議若非大量斷詞,可使用 pseg function 即可。簡單範例如下:

sentence_list = ["蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。", "蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。"]
result_pseg_batch = monpa.pseg_batch(sentence_list)

for item in result_pseg_batch:
    print(item)

輸出

[('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受', 'P'), ('邀', 'VF'), ('參加', 'VC'), ('台北市政府', 'ORG'), ('所', 'D'), ('舉辦', 'VC'), ('的', 'DE'), ('陽明山', 'LOC'), ('馬拉松', 'Na'), ('比賽', 'Na'), ('。', 'PERIODCATEGORY')]
[('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受', 'P'), ('邀', 'VF'), ('參加', 'VC'), ('台北市政府', 'ORG'), ('所', 'D'), ('舉辦', 'VC'), ('的', 'DE'), ('陽明山', 'LOC'), ('馬拉松', 'Na'), ('比賽', 'Na'), ('。', 'PERIODCATEGORY')]

輔助功能程式( v0.3.2 開始提供)

utils.short_sentence function

開始使用輔助功能程式前,請先載入 monpa 附屬之 utils 功能。

from monpa import utils

基於 monpa 斷詞只處理 200 字元內的短句,所以建議先將長句分成多個短句再做斷詞才不會因過長語句而丟失斷詞。從 monpa v0.3.2 開始提供以 "。","!","?","," 依序為參考斷點的 short_sentence function,輸入須為 string 格式,回傳值是 list 格式。該功能程式將先尋找 200 字元內最後一個 "。" 為斷點,若無,則改以 "!" 為斷點,以此類推。若 200 字元內皆無法找到預設 4 個標點符號為斷點來分句,就直接從 200 字元處分句。簡單範例如下:

long_sentence = '''
蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。
'''
sentence_list = utils.short_sentence(long_sentence)
for item in sentence_list:
    print(item)

輸出

可以發現有 292 字元的 long_sentence 長句,經 utils.short_sentence 以 "。" 為斷點分成兩個短句。

蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。
蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。

utils.cut_mp function

從 monpa v0.3.1 開始提供應用 GPU 運算能力的 cut_batch function,但考量不是每台機器皆有 GPU,所以從 v0.3.2 開始提供多執行程序的功能程式來降低多量句子的斷詞耗時。輸入為 list 或是 list of list 格式,再依機器的 CPU 內核配備指定同時啟動的 worker 數量,回傳值是 list 或是 list of list 格式。初次啟動需耗費較多時間,建議若非大量斷詞,可使用 cut function 即可。簡單範例如下:

sentence_list = ['蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。', '蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。']

result_cut_mp = utils.cut_mp(sentence_list, 4) #本例是指定啟動 4 個 workers
print(result_cut_mp)

輸出

[['蔡英文', '總統', '今天', '受', '邀', '參加', '台北市政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受', '邀', '參加', '台北市', '政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受', '邀', '參加', '台北市', '政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受', '邀', '參加', '台北市', '政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受邀', '參加', '台北市', '政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受', '邀', '參加', '台北市', '政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。'], ['蔡英文', '總統', '今天', '受', '邀', '參加', '台北市政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受', '邀', '參加', '台北市政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受', '邀', '參加', '台北市', '政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。', '蔡英文', '總統', '今天', '受', '邀', '參加', '台北市', '政府', '所', '舉辦', '的', '陽明山', '馬拉松', '比賽', '。']]

utils.pseg_mp function

從 monpa v0.3.1 開始提供應用 GPU 運算能力的 cut_batch function,但考量不是每台機器皆有 GPU,所以從 v0.3.2 開始提供多執行程序的功能程式來降低多量句子的斷詞耗時。輸入為 list 或是 list of list 格式,再依機器的 CPU 內核配備指定同時啟動的 worker 數量,回傳值是 list 或是 list of list 格式。初次啟動需耗費較多時間,建議若非大量斷詞,可使用 pseg function 即可。簡單範例如下:

sentence_list = ['蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。', '蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。蔡英文總統今天受邀參加台北市政府所舉辦的陽明山馬拉松比賽。']

result_pseg_mp = utils.pseg_mp(sentence_list, 4) #本例是指定啟動 4 個 workers
print(result_pseg_mp)

輸出

[[('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受', 'P'), ('邀', 'VF'), ('參加', 'VC'), ('台北市政府', 'ORG'), ('所', 'D'), ('舉辦', 'VC'), ('的', 'DE'), ('陽明山', 'LOC'), ('馬拉松', 'Na'), ('比賽', 'Na'), ('。', 'PERIODCATEGORY'), ('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受', 'VJ'), ('邀', 'VF'), ('參加', 'VC'), ('台北市', 'LOC'), ('政府', 'Na'), ('所', 'D'), ('舉辦', 'VC'), ('的', 'DE'), ('陽明山', 'LOC'), ('馬拉松', 'Na'), ('比賽', 'Na'), ('。', 'PERIODCATEGORY'), ('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受', 'VJ'), ('邀', 'VF'), ('參加', 'VC'), ('台北市', 'LOC'), ('政府', 'Na'), ('所', 'D'), ('舉辦', 'VC'), ('的', 'DE'), ('陽明山', 'LOC'), ('馬拉松', 'Na'), ('比賽', 'Na'), ('。', 'PERIODCATEGORY'), ('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受', 'VJ'), ('邀', 'VF'), ('參加', 'VC'), ('台北市', 'LOC'), ('政府', 'Nc'), ('所', 'D'), ('舉辦', 'VC'), ('的', 'DE'), ('陽明山', 'LOC'), ('馬拉松', 'Na'), ('比賽', 'Na'), ('。', 'PERIODCATEGORY'), ('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受邀', 'VJ'), ('參加', 'VC'), ('台北市', 'LOC'), ('政府', 'Nc'), ('所', 'D'), ('舉辦', 'VC'), ('的', 'DE'), ('陽明山', 'LOC'), ('馬拉松', 'Na'), ('比賽', 'Na'), ('。', 'PERIODCATEGORY'), ('蔡英文', 'PER'), ('總統', 'Na'), ('今天', 'Nd'), ('受', 'VJ'), ('邀', 'VF'), ('參加', 'VC'), ('台北市', 'LOC'), ('政府', 'Na'), ('所', 'D')

Related Skills

View on GitHub
GitHub Stars247
CategoryDevelopment
Updated7mo ago
Forks25

Languages

Python

Security Score

77/100

Audited on Aug 14, 2025

No findings