Press "Enter" to skip to content

Jupyter Notebook使用Python做中英文自然语言依存句法分析实验

1,本Notebook背景介绍

 

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

 

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

 

1.1,什幺是依存句法分析?

 

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

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

 

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

 

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

 

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

 

1. 一个句子中只有一个成分是独立的;

 

2. 其它成分直接依存于某一成分;

 

3. 任何一个成分都不能依存与两个或两个以上的成分;

 

4. 如果A成分直接依存于B成分,而C成分在句中位于A和B之间,那幺C或者直接依存于B,或者直接依存于A和B之间的某一成分;

 

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

1.1.1,依存关系

 

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

 

1.1.2,关系标签

 

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

 

root:中心词,通常是动词

 

nsubj:名词性主语(nominal subject)

 

dobj:直接宾语(direct object)

 

prep:介词

 

pobj:介词宾语

 

cc:连词

 

其他常用的标签:

 

compound:复合词

 

advmod:状语

 

det:限定词

 

amod:形容词修饰语

 

上面解释的参考文献:

 

1. python自然语言处理学习笔记(八)—— 句法分析

 

2. spaCy 第三篇:依存分析

 

3. 成分句法分析 & 依存句法分析 Parsing 知识图谱

 

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

 

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

 

spacy库简介:

 

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

 

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

2,第三方库

 

运行本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/sp acy-models/releases/download/zh_core_web_sm-3.1.0/zh_core_web_sm-3.1.0.tar.gz

 

2.1,可能安装不成功的诊断

 

通常是在开始菜单的Anaconda菜单下运行起来prompt窗口,在prompt窗口执行上面3个命令。有可能因为不是管理员身份执行第二个命令失败,看到这样的提示:

而第二步是要安装英文数据包,如果安装失败了,那幺执行实验一的时候,就会load失败,如下图:

解决方法就是用管理员身份打开Prompt命令行窗口,重新执行第二个命令

 

3,本notebook所做的测试

 

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

 

代码参考文献:

 

1.spaCy官网

 

2. spaCy 第三篇:依存分析

 

3.Spacy的依存分析

 

4,引入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的依存分析

 

# coding:utf-8    
import spacy

 

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

 

5.1,载入英文处理算法包

 

nlp1 = spacy.load('en_core_web_sm')

 

5.2,生成测试doc英文数据

 

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

 

doc = nlp1( "spaCy uses the terms head and child to describe the words" )

 

5.3,输出依存句法关系

 

for token in doc:
    print('{0}({1}) <-- {2} -- {3}({4})'.format(token.text, token.tag_, token.dep_, token.head.text, token.head.tag_))​

 

输出结果是:

 

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)

 

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

 

6.1,载入中文处理算法包

 

nlp2 = spacy.load('zh_core_web_sm')

 

6.2,生成测试doc中文文数据

 

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

 

doc = nlp2( "小猴子吃了5条香蕉" )

 

6.3,输出依存句法关系

 

for token in doc:
    print('{0}({1}) <-- {2} -- {3}({4})'.format(token.text, token.tag_, token.dep_, token.head.text, token.head.tag_))

 

输出结果是:

 

小(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)

 

7,实验三:分析一段话

 

找一篇科技新闻 苹果App Store大动作!允许开发者和用户使用第三方支付方式 ,取下面一段话:

 

苹果宣布将设立一项基金帮助美国小型开发者。所谓“小型开发者”资质要求是开发者须在2015年6月4日到2021年4月26日之间,在自然年内,美国商店发布的所有App全部收入累计不超过1百万美元,苹果称, 这包含99%的美国开发者,未来将披露关于此基金的细节信息。(该条款只针对美国地区)

 

doc3 = nlp2("苹果宣布将设立一项基金帮助美国小型开发者。所谓“小型开发者”资质要求是开发者须在2015年6月4日到2021年4月26日之间,在自然年内,美国商店发布的所有App全部收入累计不超过1百万美元,苹果称, 这包含99%的美国开发者,未来将披露关于此基金的细节信息。(该条款只针对美国地区)")
for token in doc3:
    print('{0}({1}) <-- {2} -- {3}({4})'.format(token.text, token.tag_, token.dep_, token.head.text, token.head.tag_))

 

输出结果是:

 

苹果(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)

 

8,展望

 

目前还没有引入可视化模块,看来要手工画一下依存图才能验证处理的是否正确,下一步我们将引入可视化再次做实验

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注