依存句法分析的效果雖然沒有像分詞、NER的效果來的好,但也有其使用價值,在平常的工做中,咱們免不了要和其打交道。筆者這幾天一直在想如何分析依存句法分析的結果,一個重要的方面即是其可視化和它的圖分析。
咱們使用的NLP工具爲jieba和LTP,其中jieba用於分詞,LTP用於詞性標註和句法分析,須要事件下載pos.model
和parser.model
文件。
本文使用的示例句子爲:node
2018年7月26日,華爲創始人任正非向5G極化碼(Polar碼)之父埃爾達爾教授舉行頒獎儀式,表彰其對於通訊領域作出的貢獻。
首先,讓咱們來看一下沒有可視化效果以前的句法分析結果。Python代碼以下:python
# -*- coding: utf-8 -*- import os import jieba from pyltp import Postagger, Parser sent = '2018年7月26日,華爲創始人任正非向5G極化碼(Polar碼)之父埃爾達爾教授舉行頒獎儀式,表彰其對於通訊領域作出的貢獻。' jieba.add_word('Polar碼') jieba.add_word('5G極化碼') jieba.add_word('埃爾達爾') jieba.add_word('之父') words = list(jieba.cut(sent)) print(words) # 詞性標註 pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') postagger = Postagger() postagger.load(pos_model_path) postags = postagger.postag(words) # 依存句法分析 par_model_path = os.path.join(os.path.dirname(__file__), 'data/parser.model') parser = Parser() parser.load(par_model_path) arcs = parser.parse(words, postags) rely_id = [arc.head for arc in arcs] # 提取依存父節點id relation = [arc.relation for arc in arcs] # 提取依存關係 heads = ['Root' if id == 0 else words[id-1] for id in rely_id] # 匹配依存父節點詞語 for i in range(len(words)): print(relation[i] + '(' + words[i] + ', ' + heads[i] + ')')
輸出結果以下:web
['2018', '年', '7', '月', '26', '日', ',', '華爲', '創始人', '任正非', '向', '5G極化碼', '(', 'Polar碼', ')', '之父', '埃爾達爾', '教授', '舉行', '頒獎儀式', ',', '表彰', '其', '對於', '通訊', '領域', '作出', '的', '貢獻', '。'] ATT(2018, 年) ATT(年, 日) ATT(7, 月) ATT(月, 日) ATT(26, 日) ADV(日, 舉行) WP(,, 日) ATT(華爲, 創始人) ATT(創始人, 任正非) SBV(任正非, 舉行) ADV(向, 舉行) ATT(5G極化碼, 之父) WP((, Polar碼) COO(Polar碼, 5G極化碼) WP(), Polar碼) ATT(之父, 埃爾達爾) ATT(埃爾達爾, 教授) POB(教授, 向) HED(舉行, Root) VOB(頒獎儀式, 舉行) WP(,, 舉行) COO(表彰, 舉行) ATT(其, 貢獻) ADV(對於, 作出) ATT(通訊, 領域) POB(領域, 對於) ATT(作出, 貢獻) RAD(的, 作出) VOB(貢獻, 表彰) WP(。, 舉行)
咱們獲得了該句子的依存句法分析的結果,可是其可視化效果卻很差。
咱們使用Graphviz工具來獲得上述依存句法分析的可視化結果,代碼(接上述代碼)以下:算法
from graphviz import Digraph g = Digraph('測試圖片') g.node(name='Root') for word in words: g.node(name=word) for i in range(len(words)): if relation[i] not in ['HED']: g.edge(words[i], heads[i], label=relation[i]) else: if heads[i] == 'Root': g.edge(words[i], 'Root', label=relation[i]) else: g.edge(heads[i], 'Root', label=relation[i]) g.view()
獲得的依存句法分析的可視化圖片以下:微信
在這張圖片中,咱們有了對依存句法分析結果的直觀感受,效果也很是好,可是遺憾的是,咱們並不能對上述可視化結果造成的圖(Graph)進行圖分析,由於Graphviz僅僅只是一個可視化工具。那麼,咱們該用什麼樣的工具來進行圖分析呢?
答案就是NetworkX。如下是筆者對於NetworkX應用於依存句法分析的可視化和圖分析的展現,其中圖分析展現了兩個節點之間的最短路徑。示例的Python代碼以下:工具
# 利用networkx繪製句法分析結果 import networkx as nx import matplotlib.pyplot as plt from pylab import mpl mpl.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 指定默認字體 G = nx.Graph() # 創建無向圖G # 添加節點 for word in words: G.add_node(word) G.add_node('Root') # 添加邊 for i in range(len(words)): G.add_edge(words[i], heads[i]) source = '5G極化碼' target1 = '任正非' distance1 = nx.shortest_path_length(G, source=source, target=target1) print("'%s'與'%s'在依存句法分析圖中的最短距離爲: %s" % (source, target1, distance1)) target2 = '埃爾達爾' distance2 = nx.shortest_path_length(G, source=source, target=target2) print("'%s'與'%s'在依存句法分析圖中的最短距離爲: %s" % (source, target2, distance2)) nx.draw(G, with_labels=True) plt.savefig("undirected_graph.png")
獲得的可視化圖片以下:post
輸出的結果以下:測試
'5G極化碼'與'任正非'在依存句法分析圖中的最短距離爲: 6 '5G極化碼'與'埃爾達爾'在依存句法分析圖中的最短距離爲: 2
本次到此結束,但願這篇簡短的文章可以給讀者帶來一些啓發~字體
注意:不妨瞭解下筆者的微信公衆號: Python爬蟲與算法(微信號爲:easy_web_scrape), 歡迎你們關注~