Practical Applications of Chatbot
Knowledge Graph Part 2: Information Extraction
Last Updated: 2025/05/06
王柳鋐
文本分析
Basis of Knowledge Graph: Text Analysis
文本分析基本任務: 斷詞、詞性標記、實體辨識
"我和順仔早上5點登上「福建號」"
我和<person>順仔</person>早上5點登上「<ship>福建號</ship>」
斷詞(tagger)
(命名)實體辨識NER
name-entity-recognition
原文
我 和 順仔 早上 5點 登上 福建號
r c nr t t v nr
詞性標記PoS
part-of-speech
專業術語 + 分類
應用:索引、Hyperlink
中文文本分析開發工具

中文文本分析開發工具2018之後


BERT
Bidirectional Encoder Representations from Transformers
中文文本分析開發工具2018之後

文本分析的困難之處(1/3)
拜訪 我 普林斯 頓 神學院 的 老同 學麥克 切斯 尼 先生 和 幾位 宣教 師 。 晚上 介紹 加拿大 , 哈巴 安德 醫師 翻譯
斷詞
困難: 斷詞錯誤 雜訊
"拜訪我普林斯頓(Princeton)神學院的老同學麥克切斯尼(McChesney)先生和幾位宣教師。晚上介紹加拿大,哈巴安德醫師翻譯。"

自訂辭典

停用字列表
普林斯頓
老同學
麥克切斯尼先生
哈巴安德醫師
宣教師
我
的
和
晚上
幾位
拜訪 普林斯頓 神學院 老同學 麥克切斯尼先生 宣教師 。 介紹 加拿大 , 哈巴安德醫師 翻譯
困難: 錯別字、同義詞(不同稱呼/不同翻譯)

拜訪南勢番(南方的原住民),在包干、李流(Li-lau),薄薄、斗蘭(Tau-lan)和七腳川拍了一些照片。

台灣堡圖
1904
我們拜訪流流、薄薄、里腦,又回到大社
問題:究竟是里腦,李流還是流流?
不同翻譯
回到五股坑,蔥仔在前往領事館費里德(A.Frater)先生那裡後和我們一起。
和偕師母及閏虔益一起到五股坑,然後去洲裡,在晚上回來。
同義詞
專家
修正與建議
里漏社

自訂辭典

停用字列表
文本分析的困難之處(2/3)
訓練資料很難取得



文本分析的困難之處(3/3)
通用資訊擷取
Universal Information Extraction (UIE)
Universal IE
Universal Information Extraction(UIE,通用資訊擷取)
適用於多種任務、與多樣資料格式的統一模型或框架。
這些任務可能包括:
-
命名實體辨識(Named Entity Recognition, NER)
-
關係擷取(Relation Extraction, RE)
-
事件擷取(Event Extraction)
-
屬性擷取(Attribute Extraction)
-
情感/意圖識別(Sentiment/Intent Extraction)
-
半結構化資料的擷取(semi-structured sources like tables, forms)
「2024年,台積電在美國亞利桑那州設立了新晶圓廠。」
例句:
🟩 命名實體辨識(NER)
有意義的「實體」類別,例如人名、地名、組織名、時間等。
🔍 結果:
台積電 → ORG(組織)
美國亞利桑那州 → LOC(地點)
2024年 → DATE(時間)
NER 是基礎任務,通常其他任務都會依賴它的結果。
NER/關係擷取/事件擷取/屬性擷取
「2024年,台積電在美國亞利桑那州設立了新晶圓廠。」
例句:
🟦 關係擷取(Relation Extraction, RE)
在實體之間建立語意關係,如誰屬於誰、誰在何處、誰做了什麼
🔍 結果:
(台積電, 設廠地點, 美國亞利桑那州)
(事件時間, 設廠, 2024年)
系統需理解哪些實體之間存在特定語義上的「關聯」
NER/關係擷取/事件擷取/屬性擷取
🟨 事件擷取(Event Extraction, EE)
辨識事件的觸發詞(trigger)與其相關角色(arguments)
像是誰做了什麼、在什麼時間、在哪裡等。
🔍 結果:
- 事件類型:設廠(建設/擴張型事件)
- 觸發詞:設立
- 角色參數:
- 主體(Agent):台積電
- 地點(Place):美國亞利桑那州
- 時間(Time):2024年
- 設施(Facility):新晶圓廠
這類任務通常會搭配「事件結構模板」,較接近語意理解。
NER/關係擷取/事件擷取/屬性擷取
🟧 屬性擷取(Attribute Extraction)
擷取產品資訊、知識圖譜、評論分析中的特定屬性或描述
例句:
「這間晶圓廠的產能為每月4萬片,專門生產3奈米晶片。」
🔍 結果:
產能:每月4萬片
製程技術:3奈米
用途:生產晶片
對象(主體):這間晶圓廠
NER/關係擷取/事件擷取/屬性擷取
📌 總結比較
任務類型 問題定義 結果範例
NER | 實體是誰?在哪?是什麼? | 台積電:ORG、亞利桑那州:LOC |
RE | 實體之間有什麼關係? | 台積電 → 設廠地點 → 美國亞利桑那州 |
EE | 發生了什麼事件?誰參與? | 設立事件,主體:台積電,地點:亞利桑那 |
屬性擷取 | 對象有哪些屬性? | 晶圓廠 → 產能:4萬片/月,製程:3奈米 |
NER/關係擷取/事件擷取/屬性擷取
Ckip Transformers安裝與使用

Ckip Transformers安裝與使用
使用方法ㄧ: 透過HuggingFace Transformers
圖片來源:Transformers, PyTorch, TensorFlow
pip install -U transformers
❶ 安裝transformers套件
❷ 安裝深度學習套件(擇一)
pip install -U torch
pip install -U tensorflow



* 後續以PyTorch為例
Ckip Transformers安裝與使用
使用方法二: CKIP_Transformers
圖片來源:Transformers, PyTorch, TensorFlow
pip install -U ckip-transformers
pip install -U torch

* 後續以PyTorch為例
from ckip_transformers.nlp import CkipWordSegmenter, CkipPosTagger, CkipNerChunker
## 將斷詞結果words與 part-of-speech結果pos打包在一起
def pack_ws_pos_sentece(words, pos):
assert len(words) == len(pos), f'words{len(words)}和pos{len(pos)}長度必須一樣'
result = [] # 最終結果串列
for word, p in zip(words, pos): # zip將words,pos對應位置鏈在一起
result.append(f"{word}({p})")
return "\u3000".join(result) #\u3000是全形空白字元
# Input text
text = [
"華氏80度,氣壓30-6,整天下雨。前進到奇武荖,聆聽朗誦。然後珍珠里簡和冬瓜山,晚間在珍珠里簡的禮拜有一百五十人,拔了七十六顆牙。",
"相當涼爽舒適,與阿華出去鄉間拜訪他的一位老朋友,是一位農人。我們被看見,認出來,且受排斥。遭到兩隻大黑狗攻擊,孩童吼叫,狂暴的辱罵。 我們回家,在吃過飯之後,我們比過去更勤奮的研讀各自的功課。",
"華氏84度,陰天,氣壓30-10。上午七點離開大里簡,大部分都用走的,上午時點三十分來到頭城,拔了一些牙。十一點到打馬煙,我們剛到雨就來了。禮德醫師在路上幫一個傢伙縫手指。新漆好的禮拜堂到處都是用藍色和紅色漆,全部由他們自費花了十二元。禮德醫師拍團體照。我們照顧了十四名病人,還拔了一些牙。主持聖餐禮,聆聽十七個人背誦。大家都做得很好,我們發禮物給他們。"
]
ws_driver = CkipWordSegmenter(model="bert-base") # 載入 斷詞模型
pos_driver = CkipPosTagger(model="bert-base") # 載入 POS模型
ner_driver = CkipNerChunker(model="bert-base") # 載入 實體辨識模型
print('all loaded...')
# 執行pipeline 產生結果
ws = ws_driver(text) # 斷詞
pos = pos_driver(ws) # 詞性: 注意斷詞-詞性是依序完成
ner = ner_driver(text) # 實體辨識
##列印結果
for sentence, word, p, n in zip(text, ws, pos, ner):
print(sentence)
print(pack_ws_pos_sentece(word, p))
for token in n:
print(f"({token.idx[0]}, {token.idx[1]}, '{token.ner}', '{token.word}')")
print()
華氏80度,氣壓30-6,整天下雨。前進到奇武荖,聆聽朗誦。然後珍珠里簡和冬瓜山,晚間在珍珠里簡的禮拜有一百五十人,拔了七十六顆牙。
華氏(Na) 80(Neu) 度(Nf) ,(COMMACATEGORY) 氣壓(Na) 30-6(Neu) ,(COMMACATEGORY) 整(Neqa) 天(Nf) 下雨(VA) 。(PERIODCATEGORY) 前進(VA) 到(P) 奇武荖(Nc) ,(COMMACATEGORY) 聆聽(VC) 朗誦(VC) 。(PERIODCATEGORY) 然後(D) 珍珠里簡(Na) 和(Caa) 冬瓜山(Nc) ,(COMMACATEGORY) 晚間(Nd) 在(P) 珍珠里簡(Nc) 的(DE) 禮拜(Na) 有(V_2) 一百五十(Neu) 人(Na) ,(COMMACATEGORY) 拔(VC) 了(Di) 七十六(Neu) 顆(Nf) 牙(Na) 。(PERIODCATEGORY)
(0, 5, 'QUANTITY', '華氏80度')
(8, 12, 'QUANTITY', '30-6')
(37, 40, 'LOC', '冬瓜山')
(41, 43, 'TIME', '晚間')
(52, 56, 'CARDINAL', '一百五十')
(60, 63, 'CARDINAL', '七十六')
實體辨識
11類專有名詞
7類數量詞
Part-of-Speech(POS)
61種詞性

華氏80度,氣壓30-6,整天下雨。前進到奇武荖,聆聽朗誦。然後珍珠里簡和冬瓜山,晚間在珍珠里簡的禮拜有一百五十人,拔了七十六顆牙。
華氏(Na) 80(Neu) 度(Nf) ,(COMMACATEGORY) 氣壓(Na) 30-6(Neu) ,(COMMACATEGORY) 整(Neqa) 天(Nf) 下雨(VA) 。(PERIODCATEGORY) 前進(VA) 到(P) 奇武荖(Nc) ,(COMMACATEGORY) 聆聽(VC) 朗誦(VC) 。(PERIODCATEGORY) 然後(D) 珍珠里簡(Na) 和(Caa) 冬瓜山(Nc) ,(COMMACATEGORY) 晚間(Nd) 在(P) 珍珠里簡(Nc) 的(DE) 禮拜(Na) 有(V_2) 一百五十(Neu) 人(Na) ,(COMMACATEGORY) 拔(VC) 了(Di) 七十六(Neu) 顆(Nf) 牙(Na) 。(PERIODCATEGORY)
(0, 5, 'QUANTITY', '華氏80度')
(8, 12, 'QUANTITY', '30-6')
(37, 40, 'LOC', '冬瓜山')
(41, 43, 'TIME', '晚間')
(52, 56, 'CARDINAL', '一百五十')
(60, 63, 'CARDINAL', '七十六')
只辨識出1個實體
且分類錯誤
應為GPE
3個地名,共出現四次
珍珠里簡: 不同詞性?
Na:普通名詞,Nc: 地方詞
from ckip_transformers.nlp import CkipWordSegmenter, CkipPosTagger, CkipNerChunker
ws_driver = CkipWordSegmenter() # 初始化 CKIP 模型
pos_driver = CkipPosTagger()
ner_driver = CkipNerChunker()
text = ["2024年,台積電在美國亞利桑那州設立了新晶圓廠。"]
ws = ws_driver(text)
pos = pos_driver(ws)
ner = ner_driver(text)
print("🔎 命名實體:")
for sentence in ner:
for entity in sentence:
print(f"{entity.word} → {entity.ner}")
print("💥 事件擷取(簡易)")
trigger_words = ["設立", "成立", "開幕", "建設"]
for tokens, tags in zip(ws, pos):
for i, word in enumerate(tokens):
if word in trigger_words:
subject = tokens[i-2] if i >= 2 else ""
location = tokens[i-1] if i >= 1 else ""
obj = tokens[i+1] if i+1 < len(tokens) else ""
print(f"事件:{word}")
print(f" 主體:{subject}")
print(f" 地點:{location}")
print(f" 對象:{obj}")
print("🔗 關係擷取(主詞-動詞-受詞邏輯)")
for tokens, tags in zip(ws, pos):
for i in range(1, len(tokens)-1):
if tags[i].startswith("V"):
subj = tokens[i-1]
obj = tokens[i+1]
print(f"[主詞] {subj} —[動詞] {tokens[i]}→ [受詞] {obj}")
NER/關係擷取/事件擷取 CKIP_Transformers
Universal IE continue
🧠 核心概念
UIE 的目標是建構一個不同任務和領域的通用模型
UIE 強調:
-
任務無關性:不需為不同任務設計不同模型
-
資料格式通用性:能處理文本、表格、HTML 等格式。
-
少樣本學習能力(few-shot / zero-shot learning)
-
即使在新任務或新資料上也能快速適應。
-
Universal IE methodology
🔧 方法與技術
-
序列到序列(Seq2Seq)框架
-
轉換成文字生成任務。例如,把「從句子中取出人名」變成「輸入:句子 + 指令,輸出:人名」。
-
代表模型:T5, BART 等。
-
-
Prompt-based Learning(提示學習)
-
使用自然語言提示引導模型完成不同的抽取任務,常結合大型語言模型(如 GPT 系列、ChatGPT、T5、FLAN-T5)。
-
-
Unified Schema/Framework
-
如 OneIE、UIE、SpERT(Span-based Entity and Relation Transformer)等,把所有任務轉化為統一的「標註問題」。
-
-
多任務學習(Multi-task Learning)
-
訓練一個模型解決多種任務,有助於學到更一般化的表示。
-
Universal IE methodology
🔬 代表性研究與模型
名稱 發表單位 年份 特點
Alibaba |
2022 |
提出 prompt-based 的 unified schema,支援多種任務(NER、RE、Event)。 |
|
OneIE |
Columbia University |
2020 |
將多任務建模視為 span-based sequence labeling 任務。 |
SpERT |
IBM Research |
2020 |
使用 transformer 擷取實體與關係,統一架構下進行 span prediction。 |
Text2Event |
THU(清華) |
2021 |
將事件擷取建模為序列生成任務。 |
TIE (Text-in-Text) |
Facebook AI |
2021 |
將所有任務統一成「子文字擷取」的問題。 |
Universal IE methodology

Universal IE Implementation

pip install paddlepaddle==2.6.1
非GPU版本
pip install -U paddlenlp
from paddlenlp.transformers import AutoTokenizer, AutoModelForTokenClassification
import paddle
# 使用 ERNIE 3.0 模型進行中文NER, 以7類為例(num_classes)
model_name = "ernie-3.0-base-zh"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForTokenClassification.from_pretrained(model_name, num_classes=7)
# 自定義一段中文文本
text = "華氏80度,氣壓30-6,整天下雨。前進到奇武荖,聆聽朗誦。然後珍珠里簡和冬瓜山,晚間在珍珠里簡的禮拜有一百五十人,拔了七十六顆牙。"
# 將文本轉換為模型輸入格式
inputs = tokenizer(text, return_tensors="pd", padding=True, truncation=True, max_length=128)
# 模型預測
with paddle.no_grad():
logits = model(**inputs)
preds = paddle.argmax(logits, axis=-1).numpy()[0]
# 取出詞元與標籤
tokens = tokenizer.convert_ids_to_tokens(inputs['input_ids'][0].numpy())
label_map = {
0: "O", # 非實體
1: "B-PER", # 人名開頭
2: "I-PER", # 人名內部
3: "B-ORG", # 組織開頭
4: "I-ORG", # 組織內部
5: "B-LOC", # 地名開頭
6: "I-LOC", # 地名內部
}
# 顯示結果(只顯示非 'O' 的實體)
print("命名實體識別結果:")
for token, pred in zip(tokens, preds):
label = label_map.get(pred, "O")
if label != "O":
print(f"{token}: {label}")
NER
from paddlenlp import Taskflow
# 醫療實體識別:診斷、症狀、藥物
schema = ['疾病', '症狀', '藥物']
ie_medical = Taskflow('information_extraction', model='uie-medical-base', schema=schema)
text = "患者出現高燒、咳嗽等症狀,診斷為流感,建議服用達菲。"
result = ie_medical(text)
print(result)
NER-醫療類
from paddlenlp import Taskflow
# 自訂實體類別
schema = ['學校名稱', '創辦人', '總部城市']
ie_custom = Taskflow('information_extraction', model='uie-base', schema=schema)
text = "真理大學是由牛津學堂發展而來,創辦人是馬偕,位於淡水。"
result = ie_custom(text)
print(result)
NER-自訂
from paddlenlp import Taskflow
# 自訂 schema(可根據任務調整)
schema = ['人物', '組織', '地點']
ie = Taskflow('information_extraction', model='uie-base', schema=schema)
# 多筆資料(List of strings)
texts = [
"馬雲是阿里巴巴的創始人,總部位於杭州。",
"劉德華出生於香港,是華語影壇的重要人物。",
"鴻海總部在新北市,創辦人是郭台銘。"
]
# 批次預測
results = ie(texts)
# 顯示結果
for idx, res in enumerate(results):
print(f"\n【第 {idx + 1} 筆輸入】")
print(res)
NER-批次處理
PaddleNLP finetune
pip install paddlepaddle==2.6.1
非GPU版本
pip install -U paddlenlp
git clone https://github.com/PaddlePaddle/PaddleNLP.git
cd PaddleNLP/slm/model_zoo_uie
下載微調專案,前往微調樣板資料夾

PaddleNLP finetune
建議資料夾結構
uie/
訓練檔
驗證檔
{"content": "蔡英文是台灣的總統,住在台北。", "prompt": "人物", "result_list": [{"start": 0, "end": 3, "text": "蔡英文"}]}
{"content": "蔡英文是台灣的總統,住在台北。", "prompt": "地點", "result_list": [{"start": 9, "end": 11, "text": "台灣"}]}
{"content": "蔡英文是台灣的總統,住在台北。", "prompt": "地點", "result_list": [{"start": 16, "end": 18, "text": "台北"}]}
train.jsonl
{"content": "侯友宜是新北市市長,住在新北。", "prompt": "人物", "result_list": [{"start": 0, "end": 3, "text": "侯友宜"}]}
{"content": "侯友宜是新北市市長,住在新北。", "prompt": "地點", "result_list": [{"start": 6, "end": 9, "text": "新北市"}]}
{"content": "侯友宜是新北市市長,住在新北。", "prompt": "地點", "result_list": [{"start": 14, "end": 16, "text": "新北"}]}
{"content": "台灣大學是台灣最著名的高等教育機構之一,位於台北。", "prompt": "組織", "result_list": [{"start": 0, "end": 4, "text": "台灣大學"}]}
{"content": "台灣大學是台灣最著名的高等教育機構之一,位於台北。", "prompt": "地點", "result_list": [{"start": 21, "end": 23, "text": "台灣"}]}
{"content": "台灣大學是台灣最著名的高等教育機構之一,位於台北。", "prompt": "地點", "result_list": [{"start": 31, "end": 33, "text": "台北"}]}
dev.jsonl
PaddleNLP finetune
python finetune.py \
--train_path train.jsonl \
--dev_path dev.jsonl \
--output_dir ./checkpoint/uie-taiwan-custom \
--model_name_or_path uie-base \
--max_seq_length 512 \
--per_device_train_batch_size 16 \
--per_device_eval_batch_size 16 \
--learning_rate 1e-5 \
--num_train_epochs 10 \
--logging_steps 10 \
--eval_steps 50 \
--save_steps 50 \
--do_train \
--do_eval \
--overwrite_output_dir \
--device gpu
Preparation: Information Extraction
By Leuo-Hong Wang
Preparation: Information Extraction
- 34