编译并使用ltp语义依存(图)分析模块

语义依存分析模块是LTP新功能,用于生成中文句子的语义依存图(存在语义关系的两个词之间用带标签的有向弧连接,允许一个词有多个父节点,因此是图结构)。这里记录一下该模块的编译及使用流程,方便使用。

语义依存分析

本节对语义依存图进行一个简介,如果只是要使用sdp模块可以直接跳过。

引言

要让机器能够理解自然语言,需要对原始文本自底向上进行分词、词性标注、命名实体识别和句法分析,若想要机器更智能,像人一样理解和运用语言,还需要对句子进行更深一层的分析,即句子级语义分析。

语义依存分析是通往语义深层理解的一条蹊径,它通过在句子结构中分析实词间的语义关系(这种关系是一种事实上或逻辑上的关系,且只有当词语进入到句子时才会存在)来回答句子中“Who did what to whom when and where”等问题。

语义分析可以跨越句子的表层结构直接获取深层语义表达的本质,这种性质在信息检索、机器翻译等诸多领域有重要作用。

语义依存树

在对中文语义依存分析的探索中,我们首先尝试了用树结构融合依存结构和语义关系。下图是一个语义依存树的示例。

语义依存树

哈工大社会计算与信息检索研究中心与北京语言大学邵艳秋教授合作于2011年推出了BH-SDP-v1(BLCU and HIT SDP)语义依存表示体系,并对中文宾州句法树库中的10,068个句子进行了标注。该标注语料经过整理后在SemEval-2012上组织了国际公开评测。这是世界上最早的语义依存分析技术评测。2014年,其他学者才开始组织英文语义依存分析评测。

该语料库存在如下几个问题:有些语义关系彼此易混淆;语义关系数量太大,有些关系在标注语料中出现次数很少;句子全部来自新闻,涵盖的语言现象有限;依存树结构,刻画语义不全面。

语义依存图

对于语义依存树表示体系存在的问题,我们采用的解决方案是用语义依存图分析代替语义依存树分析。形式上类似于依存语法,但必要时突破树形结构(BH-SDP-v2)。这样的突破使得对连动、兼语、概念转位等汉语中常见的现象的分析更全面深入,当然这也给依存分析器的构建带来了很大的难度,因为任何词都可能有多个父节点。下图直观地展示了语义依存树与依存图的区别。

语义依存树与语义依存图对比示例

语义依存树与语义依存图的主要区别在于,在依存树中,任何一个成分都不能依存于两个或两个以上的成分,而在依存图中则允许句中成分依存于两个或两个以上的成分。且在依存图中允许依存弧之间存在交叉,而依存树中不允许。

BH-SDP-v2压缩了语义关系类型的数量,重新组织并缩减了语义关系,将关系分为主要语义角色、事件关系、关系标记,从而减少不必要的类间关系混淆。语义关系在保留了一般语义关系、反关系基础上,我们还定义了嵌套关系,用来标记一个事件降级充当了另一个事件的成分。

我们标注了语义依存图语料库,包含10068句新闻语料和15000句课文句子。新闻句子平均长度是31个词,课本句子平均长度是14个词。我们又基于该标注语料在SemEval-2016上组织了一次国际公开评测。

LTP的语义依存分析模块

编译

语义依存分析(sdp)模块是LTP的一部分,所以只需获得包括sdp模块的LTP源代码,然后按照LTP标准安装步骤进行安装即可,具体可以参考官方在线文档

这里简要记录一下Linux下的编译步骤。直接在根目录下用如下命令进行编译:

./configure
make

编译完成后我们要使用到的几个二进制程序包括bin目录下的ltp_test(用于从生文本到sdp模块的预测)和bin/examples目录下的lstm_par_cmdline(用于对已完成词性标注的语料获取其语义依存图)。

使用

ltp_test

本程序用于从生文本到sdp模块的预测(当然也可以用于一直到srl等模块的预测,这里主要介绍sdp)。

输入格式为每句一行。

调用范例如下:

./ltp_test --last-stage sdp --segmentor-model /data/ltp/ltp-models/3.3.1/ltp_data/cws.model --postagger-model /data/ltp/ltp-models/3.3.1/ltp_data/pos.model --sdp-model /users2/yxwang/work/LTP/new_model/sem16.sdp.model --input infile

本程序命令行参数的具体介绍见官方文档,由于这里只用到了分词、词性标注和sdp模块,因此只给出了3个模型位置。

目前版本的sdp模型位置可以直接在hpc上我的目录下找到:

/users2/yxwang/work/LTP/new_model/sem16.sdp.model

其他模型为3.3.1的模型。

返回格式为xml4nlp格式,其他各项解释见官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="utf-8" ?>
<xml4nlp>
<note sent="y" word="y" pos="y" ne="n" parser="n" semparser="n" lstmsemparser="y" wsd="n" srl="n" />
<doc>
<para id="0">
<sent id="0" cont="早起使人健康。">
<word id="0" cont="早起" pos="v">
<sem id="0" parent="1" relate="Exp" />
</word>
<word id="1" cont="使" pos="v">
<sem id="0" parent="-1" relate="Root" />
</word>
<word id="2" cont="人" pos="n">
<sem id="0" parent="1" relate="Datv" />
<sem id="1" parent="3" relate="Aft" />
</word>
<word id="3" cont="健康" pos="a">
<sem id="0" parent="1" relate="eResu" />
</word>
<word id="4" cont="。" pos="wp">
<sem id="0" parent="3" relate="mPunc" />
</word>
</sent>
</para>
</doc>
</xml4nlp>

包括sdp信息的节点标签是sem,每个sem表示当前词的一个父节点,其中id属性表示是第几个父节点,parent属性表示当前父节点的在句中的id(也就是wordid),relate属性表示该词与当前父节点之间弧上的标签。

lstm_par_cmdline

运行lstm_par_cmdline后显示说明如下:

usage: ./lstm_par_cmdline <options>

options:
  --model-directory arg The directory of model folder 
                    [default=ltp_data/sdp.model].
  --input arg           The path to the input file. Input data should contain 
                    one sentence each line. Words should be separated by 
                    space with POS tag appended by '_' (e.g. "w1_p1 w2_p2 
                    w3_p3 w4_p4").
  -h [ --help ]         Show help information

其中,

  • model-directory:sdp模型路径(与ltp_test中的sdp-model相同)
  • input:输入文档路径

输入格式如下,每句一行,每个词的位置用 “_” 隔开,前面是词,后面是词性,词之间用tab隔开。(与pos_cmdline输出格式相同)。

我_n    是_v    中国_a  人_n
早起_n  使_v    人_n    健康_v

调用范例如下:

./lstm_par_cmdline --model-directory /users2/yxwang/work/LTP/new_model/sem16.sdp.model --input infile

输出格式为CoNLL格式,如下所示:

1       我      我      n       n       _       2       Exp     _       _
2       是      是      v       v       _       5       Root    _       _
3       中国    中国    a       a       _       4       Desc    _       _
4       人    人    n       n       _       2       Clas    _       _

1       早起    早起    n       n       _       2       Exp     _       _
2       使      使      v       v       _       5       Root    _       _
3       人      人      n       n       _       2       Datv    _       _
3       人      人      n       n       _       4       Agt     _       _
4       健康    健康    v       v       _       2       eResu   _       _

每句话中的一条弧用一行表示,第一列表示词在句中的位置,第二列表示,第四列表示词性,第七列表示父节点位置,第八列表示该词与当前父节点之间弧上的标签。注意有些词有多个父节点(例如第二句中的“人”),这时这个词就会有多行,每行表示其与一个父节点之间的弧信息。