Jupyter Notebook使用Python做依存句法分析实验

本Notebook背景介绍

此前介绍了一篇论文范例《基于依存句法分析的科技政策领域主题词表无监督构建》,该研究作者为了解决科技政策领域词表构建的问题,提出了一种基于依存句法分析的科技政策文本关键词抽取算法。在此基础上,提出文本主题词指数来构建文本主题词,利用同义词识别算法及百科知识发现和确定词与词的同义关系,采用字面匹配的方法判别上下位词,最终汇合四个部分形成科技政策领域主题词表。。

什么是依存句法分析? 能不能在python中做依存句法分析方面的实验呢? 本Notebook将回答这2个问题。

什么是依存句法分析?

笔者简单整理了句法分析的脑图: 句法分析脑图

依存文法存在一个共同的基本假设:文法结构本质上包含词和词之间的依存(修饰)关系。一个依存关系连接两个词,分别是核心词( head)和依存词( dependent)。依存关系可以细分为不同的类型,表示两个词之间的具体句法关系。

依存关系是一个核心词与它的依赖之间的二元对称关系。一个句子的核心词通常是动词,所有其他词要么依赖于核心词,要么依赖路径与它联通。

依存关系表示是一个加标签的有向图,其中节点是词汇项,加标签的弧表示依赖关系, 从中心词到依赖。

在20世纪70年代,Robinson提出依存语法中关于依存关系的四条公理:

  1. 一个句子中只有一个成分是独立的;
  2. 其它成分直接依存于某一成分;
  3. 任何一个成分都不能依存与两个或两个以上的成分;
  4. 如果A成分直接依存于B成分,而C成分在句中位于A和B之间,那么C或者直接依存于B,或者直接依存于A和B之间的某一成分;

下面是中文句子依存关系示意图:

中文依存关系例子

依存关系

依存结构是加标签的有向图,箭头从中心词指向从属,具体来说,箭头是从head指向child,从该解析树可以看出,每个Token只有一个Head。

关系标签

标签表示从属的语法功能,名词性的标签是:

  1. root:中心词,通常是动词
  2. nsubj:名词性主语(nominal subject)
  3. dobj:直接宾语(direct object)
  4. prep:介词
  5. pobj:介词宾语
  6. cc:连词

其他常用的标签:

  1. compound:复合词
  2. advmod:状语
  3. det:限定词
  4. amod:形容词修饰语

上面解释的参考文献:

  1. python自然语言处理学习笔记(八)—— 句法分析
  2. spaCy 第三篇:依存分析
  3. 成分句法分析 & 依存句法分析 Parsing 知识图谱

能不能在python中做依存句法分析方面的实验呢?

笔者查了一下,python的spacy库提供依存句法分析方面的模块。

spacy库简介:

spaCy是自然语言处理(NLP)任务的一个库。在众多的NLP库中,spaCy独树一帜。spaCy库具有强大的功能,同时它提供一系列优良的特性,库非常易用,以及库总是保持最新。

下面是来自spaCy官网的软件架构图:

spacy架构图

第三方库

运行本Notebook,需安装spacy库及中英文的算法包,如果没有安装的需要打开一个COMMAND窗口进行安装(注:内地环境安装可能会比较耗时):

$ pip install spacy -i https://pypi.tuna.tsinghua.edu.cn/simple/

$ conda install -c conda-forge spacy-model-en_core_web_sm

$ pip install https://github.com/explosion/spacy-models/releases/download/zh_core_web_sm-3.1.0/zh_core_web_sm-3.1.0.tar.gz

本notebook所做的测试

基于测试数据,在Jupyter Notebook中使用Python做依存句法分析方面的实验。

代码参考文献:

  1. spaCy官网
  2. spaCy 第三篇:依存分析
  3. Spacy的依存分析

引入spacy库

spaCy模块有4个非常重要的类:

Doc:Doc对象由Tokenizer构造,然后由管道的组件进行适当的修改。doc对象是token的序列

Span:Span对象是Doc对象的一个切片。

Token:在自然语言处理中,把一个单词,一个标点符号,一个空格等叫做一个token。

Vocab:存储词汇表和语言共享的数据。词汇表使用Lexeme对象和StringStore对象来表示。

Lexeme对象是词汇表Vocab中的一个词条(entry),可以通过similarity()函数计算两个词条的相似性;

StringStore类是一个string-to-int的对象,通过64位的哈希值来查找词汇,或者把词汇映射到64位的哈希值

当你在一个文本上调用nlp时,spaCy首先将文本分词,生成一个Doc对象。然后,Doc会经过几个不同的步骤进行处理。Pipeline通常包括一个标记器(tagger)、一个词法器(lemmatizer)、一个解析器(parser)和一个实体识别器(entity recognizer)。每个流水线组件都会返回经过处理的Doc,然后将其传递给下一个组件。

spacy_pipeline.png

参见Spacy的依存分析

In [1]:
In [2]:
Help on function render in module spacy.displacy:

render(docs: Union[Iterable[Union[spacy.tokens.doc.Doc, spacy.tokens.span.Span]], spacy.tokens.doc.Doc, spacy.tokens.span.Span], style: str = 'dep', page: bool = False, minify: bool = False, jupyter: Union[bool, NoneType] = None, options: Dict[str, Any] = {}, manual: bool = False) -> str
    Render displaCy visualisation.
    
    docs (Union[Iterable[Doc], Doc]): Document(s) to visualise.
    style (str): Visualisation style, 'dep' or 'ent'.
    page (bool): Render markup as full HTML page.
    minify (bool): Minify HTML markup.
    jupyter (bool): Override Jupyter auto-detection.
    options (dict): Visualiser-specific options, e.g. colors.
    manual (bool): Don't parse `Doc` and instead expect a dict/list of dicts.
    RETURNS (str): Rendered HTML markup.
    
    DOCS: https://spacy.io/api/top-level#displacy.render
    USAGE: https://spacy.io/usage/visualizers

实验一:针对英文文本做依存句法测试

载入英文处理算法包

In [3]:

生成测试doc英文数据

为简化测试,我们把一段英文字符串传给nlp生成doc

In [4]:

输出依存句法关系

In [5]:
spaCy(UH) <-- intj -- uses(VBZ)
uses(VBZ) <-- ROOT -- uses(VBZ)
the(DT) <-- det -- terms(NNS)
terms(NNS) <-- dobj -- uses(VBZ)
head(VB) <-- dobj -- uses(VBZ)
and(CC) <-- cc -- head(VB)
child(NN) <-- conj -- head(VB)
to(TO) <-- aux -- describe(VB)
describe(VB) <-- xcomp -- uses(VBZ)
the(DT) <-- det -- words(NNS)
words(NNS) <-- dobj -- describe(VB)

实验二:针对中文文本做依存句法测试

载入中文处理算法包

In [6]:

生成测试doc中文文数据

为简化测试,我们把一段中文字符串传给nlp生成doc

In [7]:

输出依存句法关系

In [8]:
小(JJ) <-- amod -- 猴子(NN)
猴子(NN) <-- nsubj -- 吃(VV)
吃(VV) <-- ROOT -- 吃(VV)
了(AS) <-- aux:asp -- 吃(VV)
5(CD) <-- nummod -- 香蕉(NN)
条(M) <-- mark:clf -- 5(CD)
香蕉(NN) <-- dobj -- 吃(VV)
In [15]:
小猴子吃了 5 CARDINAL 条香蕉
In [22]:
ADJ 猴子 NOUN VERB PART 5 NUM NUM 香蕉 NOUN amod nsubj aux:asp nummod mark:clf dobj
In [23]:
In [24]:
苹果(NN) <-- nsubj -- 宣布(VV)
宣布(VV) <-- ROOT -- 宣布(VV)
将(AD) <-- advmod -- 设立(VV)
设立(VV) <-- ccomp -- 宣布(VV)
一(CD) <-- nummod -- 基金(NN)
项(M) <-- mark:clf -- 一(CD)
基金(NN) <-- dobj -- 设立(VV)
帮助(VV) <-- conj -- 设立(VV)
美国(NR) <-- nmod -- 开发者(NN)
小型(JJ) <-- amod -- 开发者(NN)
开发者(NN) <-- dobj -- 帮助(VV)
。(PU) <-- punct -- 宣布(VV)
所谓(JJ) <-- amod -- 开发者(NN)
“(PU) <-- punct -- 开发者(NN)
小型(JJ) <-- amod -- 开发者(NN)
开发者(NN) <-- compound:nn -- 要求(NN)
”(PU) <-- punct -- 开发者(NN)
资质(NN) <-- compound:nn -- 要求(NN)
要求(NN) <-- nsubj -- 超过(VV)
是(VC) <-- cop -- 超过(VV)
开发者(NN) <-- nsubj -- 超过(VV)
须(VV) <-- xcomp -- 超过(VV)
在(P) <-- case -- 26日(NT)
2015年(NT) <-- compound:nn -- 26日(NT)
6月(NT) <-- conj -- 26日(NT)
4日(NT) <-- dep -- 6月(NT)
到(CC) <-- cc -- 26日(NT)
2021年(NT) <-- compound:nn -- 26日(NT)
4月(NT) <-- compound:nn -- 26日(NT)
26日(NT) <-- nmod:prep -- 超过(VV)
之间(LC) <-- case -- 26日(NT)
,(PU) <-- punct -- 超过(VV)
在(P) <-- case -- 自然(NN)
自然(NN) <-- nmod:prep -- 超过(VV)
年内(LC) <-- case -- 自然(NN)
,(PU) <-- punct -- 超过(VV)
美国(NR) <-- nmod:assmod -- 商店(NN)
商店(NN) <-- nsubj -- 发布(VV)
发布(VV) <-- acl -- 收入(NN)
的(DEC) <-- mark -- 发布(VV)
所有(DT) <-- det -- 收入(NN)
App全部(NR) <-- compound:nn -- 收入(NN)
收入(NN) <-- nsubj -- 超过(VV)
累计(AD) <-- advmod -- 超过(VV)
不(AD) <-- neg -- 超过(VV)
超过(VV) <-- ROOT -- 超过(VV)
1百万(CD) <-- nmod:range -- 超过(VV)
美元(M) <-- mark:clf -- 1百万(CD)
,(PU) <-- punct -- 超过(VV)
苹果(NN) <-- nsubj -- 称(VV)
称(VV) <-- conj -- 超过(VV)
,(PU) <-- punct -- 超过(VV)
这(PN) <-- nsubj -- 包含(VV)
包含(VV) <-- conj -- 超过(VV)
99%(NN) <-- nmod:assmod -- 开发者(NN)
的(DEC) <-- case -- 99%(NN)
美国(NR) <-- nmod:assmod -- 开发者(NN)
开发者(NN) <-- dobj -- 包含(VV)
,(PU) <-- punct -- 超过(VV)
未来(NT) <-- nmod:tmod -- 披露(VV)
将(AD) <-- advmod -- 披露(VV)
披露(VV) <-- conj -- 超过(VV)
关于(P) <-- case -- 基金(NN)
此(DT) <-- det -- 基金(NN)
基金(NN) <-- nmod -- 信息(NN)
的(DEG) <-- case -- 基金(NN)
细节(NN) <-- compound:nn -- 信息(NN)
信息(NN) <-- dobj -- 披露(VV)
。(PU) <-- punct -- 超过(VV)
((PU) <-- punct -- 针对(P)
该(DT) <-- det -- 条款(NN)
条款(NN) <-- nsubj -- 针对(P)
只(AD) <-- advmod -- 针对(P)
针对(P) <-- ROOT -- 针对(P)
美国(NR) <-- nmod:assmod -- 地区(NN)
地区(NN) <-- dobj -- 针对(P)
)(PU) <-- punct -- 针对(P)
In [25]:
苹果
宣布
将
设立
一
项
基金
帮助
美国
小型
开发者
。
所谓
“
小型
开发者
”
资质
要求
是
开发者
须
在
2015年
6月
4日
到
2021年
4月
26日
之间
,
在
自然
年内
,
美国
商店
发布
的
所有
App全部
收入
累计
不
超过
1百万
美元
,
苹果
称
,
这
包含
99%
的
美国
开发者
,
未来
将
披露
关于
此
基金
的
细节
信息
。
(
该
条款
只
针对
美国
地区
)
In [29]:
苹果 NOUN 宣布 VERB ADV 设立 VERB NUM NUM 基金 NOUN 帮助 VERB 美国 PROPN 小型 ADJ 开发者。 NOUN nsubj advmod ccomp nummod mark:clf dobj conj nmod amod dobj 所谓“ ADJ 小型 ADJ 开发者” NOUN 资质 NOUN 要求 NOUN VERB 开发者 NOUN VERB ADP 2015年 NOUN 6月 NOUN 4日 NOUN CCONJ 2021年 NOUN 4月 NOUN 26日 NOUN 之间, PART ADP 自然 NOUN 年内, PART 美国 PROPN 商店 NOUN 发布 VERB PART 所有 DET App全部 PROPN 收入 NOUN 累计 ADV ADV 超过 VERB 1百万 NUM 美元, NUM 苹果 NOUN 称, VERB PRON 包含 VERB 99% NOUN PART 美国 PROPN 开发者, NOUN 未来 NOUN ADV 披露 VERB 关于 ADP DET 基金 NOUN PART 细节 NOUN 信息。 NOUN amod amod compound:nn compound:nn nsubj cop nsubj xcomp case compound:nn conj dep cc compound:nn compound:nn nmod:prep case case nmod:prep case nmod:assmod nsubj acl mark det compound:nn nsubj advmod neg nmod:range mark:clf nsubj conj nsubj conj nmod:assmod case nmod:assmod dobj nmod:tmod advmod conj case det nmod case compound:nn dobj PUNCT DET 条款 NOUN ADV 针对 ADP 美国 PROPN 地区) NOUN punct det nsubj advmod nmod:assmod dobj
苹果 NOUN 宣布 VERB ADV 设立 VERB NUM NUM 基金 NOUN 帮助 VERB 美国 PROPN 小型 ADJ 开发者。 NOUN 所谓“ ADJ 小型 ADJ 开发者” NOUN 资质 NOUN 要求 NOUN VERB 开发者 NOUN VERB ADP 2015年 NOUN 6月 NOUN 4日 NOUN CCONJ 2021年 NOUN 4月 NOUN 26日 NOUN 之间, PART ADP 自然 NOUN 年内, PART 美国 PROPN 商店 NOUN 发布 VERB PART 所有 DET App全部 PROPN 收入 NOUN 累计 ADV ADV 超过 VERB 1百万 NUM 美元, NUM 苹果 NOUN 称, VERB PRON 包含 VERB 99% NOUN PART 美国 PROPN 开发者, NOUN 未来 NOUN ADV 披露 VERB 关于 ADP DET 基金 NOUN PART 细节 NOUN 信息。( NOUN DET 条款 NOUN ADV 针对 ADP 美国 PROPN 地区) NOUN nsubj advmod ccomp nummod mark:clf dobj conj nmod amod dobj amod amod compound:nn compound:nn nsubj cop nsubj xcomp case compound:nn conj dep cc compound:nn compound:nn nmod:prep case case nmod:prep case nmod:assmod nsubj acl mark det compound:nn nsubj advmod neg nmod:range mark:clf nsubj conj nsubj conj nmod:assmod case nmod:assmod dobj nmod:tmod advmod conj case det nmod case compound:nn dobj det nsubj advmod nmod:assmod dobj
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-29-a0601fa8e64b> in <module>
      2 displacy.render(sentence_spans, options=options,style="dep",jupyter=True)
      3 svg = displacy.render(doc3, style="dep")
----> 4 output_path = Path("/images/sentence.svg")
      5 output_path.open("w", encoding="utf-8").write(svg)

NameError: name 'Path' is not defined

In [ ]: