句法分析是自然语言处理中的关键技术之一,其基本任务是确定句子的句法结构或者句子中词汇之间的依存关系。主要包括两方面的内容,一是确定语言的语法体系,即对语言中合法句子的语法结构给予形式化的定义;另一方面是句法分析技术,即根据给定的语法体系,自动推导出句子的句法结构,分析句子所包含的句法单位和这些句法单位之间的关系。
依存关系本身是一个树结构,每一个词看成一个节点,依存关系就是一条有向边。本文主要通过清华大学的句法标注语料库,来实现基于 CRF 的中文句法依存分析模型。
清华大学句法标注语料库
清华大学的句法标注语料,包括训练集(train.conll)和开发集合文件(dev.conll)。训练集大小 5.41M,共185541条数据。测试集大小为 578kb,共19302条数据。
语料本身格式如下图所示:
通过上图,我们可以看出,每行语料包括有8个标签,分别是 ID、FROM、lEMMA、CPOSTAG、POSTAG、FEATS、HEAD、DEPREL。详细介绍如下图:
模型的实现
通过上面对句法依存关键技术的定义,我们明白了,句法依存的基本任务是确定句子的句法结构或者句子中词汇之间的依存关系。同时,我们也对此次模型实现的语料有了基本了解。
有了这些基础内容,我们便可以开始着手开发了。
本模型的实现过程,我们将主要分为训练集和测试集数据预处理、语料特征生成、模型训练及预测三大部分来实现,最终将通过模型预测得到正确的预测结果。
本次实战演练,我们选择以下模型和软件:
- Sklearn_crfsuite
- Python3.6
- Jupyter Notebook
训练集和测试集数据预处理
由于上述给定的语料,在模型中,我们不能直接使用,必须先经过预处理,把上述语料格式重新组织成具有词性、方向和距离的格式。
首先,我们通过一个 Python 脚本 get_parser_train_test_input.py
,生成所需要的训练集和测试集,执行如下命令即可:
cat train.conll | python get_parser_train_test_input.py > train.data
cat dev.conll | python get_parser_train_test_input.py > dev.data
上面的脚本通过 cat 命令和管道符把内容传递给脚本进行处理。这里需要注意的是,脚本需要在 Linux 环境下执行,且语料和脚本应放在同一目录下。
get_parser_train_test_input.py 这一脚本的目的,就是重新组织语料,组织成可以使用 CRF 算法的格式,具有词性、方向和距离的格式。我们认为,如果词 A 依赖词 B,A 就是孩子,B 就是父亲。按照这种假设得到父亲节点的粗词性和详细词性,以及和依赖次之间的距离。
我们打开该脚本,看看它的代码,如下所示,重要的代码给出了注释。
#coding=utf-8
'''词A依赖词B,A就是孩子,B就是父亲'''
import sys
sentence = ["Root"]
def do_parse(sentence):
if len(sentence) == 1:return
for line in sentence[1:]:
line_arr = line.strip().split("\t")
c_id = int(line_arr[0])
f_id = int(line_arr[6])
if f_id == 0:
print("\t".join(line_arr[2:5])+"\t" + "0_Root")
continue
f_post,f_detail_post = sentence[f_id].strip().split("\t")[3:5] #得到父亲节点的粗词性和详细词性
c_edge_post = f_post #默