基於依存句法分析的實體關係抽取
from:https://mp.weixin.qq.com/s/Q-WMYSTjGGxIMGNq-wfpRg
這一段時間一直在做知識圖譜,卡在實體關係抽取這裡幾個月了,在github上面看到有人使用卷積神經網路訓練模型進行抽取,自己也嘗試了一下,但是一直苦於沒有像樣資料去訓練,而標註訓練集又太費時間了,我不太願意幹體力活。所以採用了一個低檔次的方法,基於依存句法分析的實體關係抽取,記錄一下心得,方便日後忘記可以再找回來。
本方法參考了github上面的專案和一篇論文,在文章末尾給出,使用的分詞工具是HanLP,感謝相關作者。
論文給出了8種中文關係的表達方式,並且最後給出了一個採用正則表示式語法指出表達,核心就是謂語動詞表示關係,即關係表述中一定得有動詞。
狀語*動詞+補語?賓語?
我不太贊同把賓語也當作關係表述的一部分,論文指出“p4生於山西”應該抽出(p4,山西,生於山西),我認為關係不應該表述為“生於山西”,所以我把關係表述改為下面的樣子了。
狀語*動詞+補語?
這篇文章只是作為一個方法介紹,我自己先看了一遍,能夠保證我下次看到這篇文章,可以立馬回憶起自己的實現方法,希望你看了也能瞭解方法,看不懂的話,我表示抱歉,浪費您的時間了,我已經儘可能寫到簡單了。
先來看幾個簡單句子吧:
主謂賓關係:劉小緒 生於 四川 // 這個三元組很明顯:(劉小緒,生於,四川) 動補結構:劉小緒 洗 乾淨 了 衣服 // 如果套用主謂賓關係就是:(劉小緒,洗,衣服) // 但是這裡描述的是一個狀態,是劉小緒把衣服洗乾淨了 // “乾淨”是動詞“洗”的補語,所以還應該提取出一個如下三元組 // (劉小緒,洗乾淨了,衣服) 狀動結構:父親 非常 喜歡 跑步 // 這句和上面很像,主謂賓關係是:父親喜歡跑步 // “非常”用於修飾“喜歡” // (父親,非常喜歡,跑步) 介賓關係:劉小緒 就職 於 學校 // 如果直接把這個三元組抽取為(劉小緒,就職,學校),很彆扭 // “於”和“學校”是介賓關係,它們的關係應該是:就職於 // (劉小緒,就職於,學校) 賓語前置:海洋 由 水 組成 // “海洋”是“組成”的前置賓語 // “由”是“組成”的狀語 // “水”和“由”是介賓關係 // 所以上面的句子沒有明確的主謂關係,需要我們判斷 // 抽出的三元組應該為:(水,組成,海洋)
HanLP提供了兩種依存句法分析的器,預設採用的是基於神經網路的依存句法分析器。==依存句法分析就是將句子分析成一棵依存句法樹,描述各個詞語之間的依存關係,即指出詞語之間在句法上的搭配關係。==
有了上面所說的依存句法樹,其實我們只需要進行各種判斷就可以了。先做出下面的一點說明,就拿第一個例子來說。
原文:劉小緒生於四川
# 這是分詞結果
[劉小緒/nr, 生於/v, 四川/ns]
#這是句法分析結果
劉小緒 --(主謂關係)--> 生於
生於 --(核心關係)--> ##核心##
四川 --(動賓關係)--> 生於
為了方便理解,也為了方便程式的編寫,我把他們組織成了下面的形式,為每一個詞語都建一個依存句法字典。
劉小緒:{}
生於:{主謂關係=[劉小緒], 動賓關係=[四川]}
四川:{}
然後只需要寫出類似於下面的程式段就可以抽出關係了。
// 主謂賓關係:劉小緒生於四川// dic是這個詞語的依存句法字典if (dic.containsKey("主謂關係") && dic.containsKey("動賓關係")){ // 當前的詞語,用上面的例子來說,relation=“生於”
String relation = curWord.LEMMA; // 用迴圈遍歷,是因為關係列表裡面不一定只有一個詞語
for (CoNLLWord entity1:
dic.get("主謂關係")) { for (CoNLLWord entity2:
dic.get("動賓關係")) {
System.out.println(entity1.LEMMA + "," + relation + "," + entity2.LEMMA);
}
}
}
對於分詞後的每個詞語都進行上面程式段的操作。“劉小緒”和“四川”,關係字典都為空。而對於“生於”,關係列表裡面既有主謂也有動賓,而自己本身就是動詞,主謂賓就出來了。直接從主謂關係中拿出來詞語作為entity1,再拿上自己作為關係,最後拿出動賓關係中的詞語作為entity2。很明確的三元組(劉小緒,生於,四川)就出來了。
最後給出一個程式執行結果圖吧。
我個人覺得效果還行,在簡單句子上面表現的差強人意,在長句子上面表現的差勁。
參考:
HanLP自然語言處理
基於依存分析的開放式中文實體關係抽取方法,李明耀;
fact_triple_extraction:https://github.com/twjiang/fact_triple_extraction