从头开始训练一个依存分析器
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                从头开始训练一个依存分析器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                文章目錄
- 從頭開始訓練一個依存分析器
 - 重要概念
 - 關系標簽
 - 標注關系
 - 應用場景
 
- 一、自定義模型
 - 1、導入所需要的包與模塊
 - 2、導入訓練樣本
 
- 二、訓練模型
 - 1、模型參數的注解(語種、輸出目錄以及訓練迭代次數)
 - 2、對現有的模型進行優化
 - 3、創建內置管道組件
 - 4、添加train data的標簽
 - 5、構建模型
 - 6、模型保存
 
- 三、模型測試
 - 不足的地方
 - 參考
 
從頭開始訓練一個依存分析器
依存句法通過分析語言單位內成分之前的依存關系解釋其句法結構,主張句子中核心動詞是支配其他成分的中心成分。而它本身卻不受其他任何成分的支配,所有受支配成分都以某種關系從屬于支配者。
 
重要概念
- 依存句法認為“謂語”中的動詞是一個句子的中心,其他成分與動詞直接或間接地產生聯系。
 - 依存句法理論中,“依存”指詞與詞之間支配與被支配的關系,這種關系不是對等的,這種關系具有方向。確切的說,處于支配地位的成分稱之為支配者,而處于被支配地位的成分稱之為從屬者。
 - 依存語法本身沒有規定要對依存關系進行分類,但為了豐富依存結構傳達的句法信息,在實際應用中,一般會給依存樹的邊加上不同的標記。
 - 依存語法存在一個共同的基本假設:句法結構本質上包含詞和詞之間的依存(修飾)關系。一個依存關系連接兩個詞,分別是核心詞和依存詞。依存關系可以細分為不同的類型,表示兩個詞之間的具體句法關系。
 
關系標簽
標簽表示從屬的語法功能,名詞性的標簽是:
- root:中心詞,通常是動詞
 - nsubj:名詞性主語(nominal subject)
 - dobj:直接賓語(direct object)
 - prep:介詞
 - pobj:介詞賓語
 - cc:連詞
 
其他常用的標簽:
- compound:復合詞
 - advmod:狀語
 - det:限定詞
 - amod:形容詞修飾語-
 
標注關系
中文依存分析關系如下:
 
應用場景
- 幫助進行NER標注:名詞短語通常被標記為一個完整的實體,這些短語經過語法解析后就可以被準確識別。
 - 機器翻譯:通過構建完整的語法樹,可以正確的建立詞語之間的關系避免翻譯歧義。
 - 通過重新定義詞語之間的聯系,識別詞語之間的關系,例如:人物親戚關系。
 
接下來開始 spaCy 訓練依存分析器。
 注:本文使用 spaCy 3.0 代碼實現。
 
 
一、自定義模型
1、導入所需要的包與模塊
from __future__ import unicode_literals, print_function import plac import random import spacy from pathlib import Path from spacy.training import Example2、導入訓練樣本
TRAIN_DATA = [("房祖名 是 成龍 的 兒子", {'heads': [2, 4, 2, 2, 0],'deps': ['SON', '-', 'ROOT', '-', 'ATT']}),("張若昀 的 妻子 是 唐藝昕", {'heads': [0, 0, 4, 2, 0],'deps': ['ROOT', '-', 'ATT', '-', 'HUS']}),("陳凱歌 是 陳赫 的 舅舅", {'heads': [2, 4, 2, 2, 0],'deps': ['UNCLE', '-', 'ROOT', '-', 'ATT']}),("焦曼婷 是 焦恩俊 的 女兒", {'heads': [2, 4, 2, 2, 0],'deps': ['DAU', '-', 'ROOT', '-', 'ATT']}) ]數據可以自己再添加,越多越好,其中heads為根據下標的依存匹配(即從屬詞與支配詞的劃分)。
 
 
二、訓練模型
1、模型參數的注解(語種、輸出目錄以及訓練迭代次數)
@plac.annotations(lang=("ISO Code of language to use", "option", "l", str),output_dir=("Optional output directory", "option", "o", Path),n_iter=("Number of training iterations", "option", "n", int))2、對現有的模型進行優化
if model is not None:nlp = spacy.load(model) # 加載存在的模型 print("Loaded model '%s'" % model)else:nlp = spacy.blank('en') # 創建空白模型print("Created blank 'en' model")3、創建內置管道組件
使用 add_pipeline函數創建流水線
if 'parser' in nlp.pipe_names:nlp.remove_pipe('parser') parser = nlp.add_pipe('parser', first=True)4、添加train data的標簽
for text, annotations in TRAIN_DATA:for dep in annotations.get('deps', []):parser.add_label(dep)5、構建模型
訓練過程本身很簡單,nlp.update()方法為我們抽象了所有內容,由 spaCy 處理實際的機器學習和訓練過程。
# 禁用流水線中所有其他組件,以便只訓練/更新NER標注器 other_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'parser']with nlp.disable_pipes(*other_pipes): # 僅訓練我們標注的標簽,假如沒有則會對所有的標簽訓練,for itn in range(n_iter):random.shuffle(TRAIN_DATA) # 訓練數據每次迭代打亂順序losses = {} # 定義損失函數for batch in spacy.util.minibatch(TRAIN_DATA, size=2):for text, annotations in batch:#建立一個案例doc = nlp.make_doc(text)example = Example.from_dict(doc, annotations)nlp.update([example], losses=losses, drop=0.3)print(losses)6、模型保存
test_model(nlp)if output_dir is not None:output_dir = Path(output_dir)if not output_dir.exists():output_dir.mkdir()nlp.to_disk(output_dir)print("Saved model to", output_dir)print("Loading from", output_dir)nlp2 = spacy.load(output_dir)test_model(nlp2)三、模型測試
def test_model(nlp):texts = ["小紅 是 小綠 的 妻子","房祖名 和 成龍 的 關系 是 父子","張曉龍 和 張佳寧 的 舅舅"]docs = nlp.pipe(texts)for doc in docs:print(doc.text)print([(t.text, t.dep_, t.head.text) for t in doc if t.dep_ != '-'])if __name__ == '__main__':plac.call(main)模型的效果如下
小紅 是 小綠 的 妻子 [('小紅', 'FAT', '小綠'), ('是', 'dep', '小紅'), ('小綠', 'ROOT', '小綠'), ('妻子', 'dep', '小綠')] 房祖名 和 成龍 的 關系 是 父子 [('房祖名', 'SON', '成龍'), ('和', 'dep', '房祖名'), ('成龍', 'ROOT', '成龍'), ('關系', 'ATT', '父子'), ('父子', 'dep', '成龍')] 張曉龍 和 張佳寧 的 舅舅 [('張曉龍', 'UNCLE', '張佳寧'), ('和', 'dep', '張曉龍'), ('張佳寧', 'ROOT', '張佳寧'), ('舅舅', 'dep', '張佳寧')]可以看到效果還是可以的,只有第一條沒有匹配成功。
 
 
不足的地方
本文模型用的是英文模型,可以看到本文將中文句子事先用空格隔開,以到達成功訓練,后續待改進。
 
 
參考
1、【法】巴格夫·斯里尼瓦薩-德西坎.《自然語言處理與計算語言學》.人民郵電出版社
2、https://zhuanlan.zhihu.com/p/51186364
3、https://blog.csdn.net/sinat_33741547/article/details/79258045
總結
以上是生活随笔為你收集整理的从头开始训练一个依存分析器的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: C++Primer 第9章 顺序容器
 - 下一篇: JRUL数字交流三相电流继电器