一些中文NLP领域,构建语料的经验和技巧

2020-05-12 11:03 来源:电子说

记得写毕业论文那会儿,经常为语料发愁。由于大多数 NLP 问题都是有监督问题,很多时候我们往往缺的不是算法,而是标注好的语料。这在中文语料上更是明显。今天就和大家分享一些中文 NLP 领域,构建语料的经验和技巧,虽然未必看了此文就能彻底解决语料的问题,但是或多或少会有些启发。

首先分享几个常见的语料获取渠道

国内外NLP领域的会议评测数据

相关研究机构、实验室、论文公开的数据集

国内外数据科学竞赛平台,kaggle,天池,科赛,CCF等

互联网企业自己举办的比赛,如百度,搜狐,知乎,腾讯这些企业都是土豪,通常会花费巨额的资金标注语料

Github 很多模型里面会自带部分语料

虽然通过这些途径,能够搜集到不少的NLP语料,但这些“现成”的语料往往与我们需要解决的 NLP 问题不太一致,因此我们还得想办法去变一些语料出来。

通过API或开源模型标注语料

比如我们需要训练一个命名实体识别模型,就可以借助 bosonnlp 或者 hanlp、foolnltk 上去标注一些语料。这些API和模型有的时候只提供了模型的预测结果,没有提供训练的语料,但是我们可以拿这些别人训练好的模型去构造语料。

知识蒸馏

我们可以将别人训练的模型看做是Teacher, 然后用API标注的语料自己训练的模型看做是Student, 虽然结果不能达到和原来模型一致的效果,但是也不至于差太多,这种方式在初期能够帮助我们快速的推进项目,看到项目的效果后,后期再想办法优化迭代

通过搜索引擎收集标注数据

假设我们需要做一个NER模型,其中一类实体是人名,可能我们想到的是从网上下载一批新闻,然后标出其中的人名,但是,这样做有一个问题,一篇几千字的新闻往往只有几个人名,而我们只需要出现了人名的那部分句子,并不需要其他部分。如果直接在整篇文本上标注效率十分低。其实,我们可以转换一下思路,找一份中文人名词库,然后放到百度中搜索,百度摘要返回的大部分结果基本是我们想要的语料,通过爬虫把摘要爬下来,自己再过滤下就好啦。这样的做法相当于,借助于一些过滤和排序算法,帮助我们快速找到待标注的语料。

二次加工已有语料

有的时候,一些语料和我们的需要解决的任务相似,但又完全不一样,这时候我们可以尝试利用其他任务的语料来构建出想要的语料。就拿百度2019信息抽取比赛来说吧,该比赛的任务是从

"text": "《逐风行》是百度文学旗下纵横中文网签约作家清水秋风创作的一部东方玄幻小说,小说已于2014-04-28正式发布"

这样的句子中抽出实体和关系三元组

"spo_list": [{"predicate": "连载网站", "object_type": "网站", "subject_type": "网络小说", "object": "纵横中文网", "subject": "逐风行"}, {"predicate": "作者", "object_type": "人物", "subject_type": "图书作品", "object": "清水秋风", "subject": "逐风行"}]screenshot-lic2019-ccf-org-cn-kg-1574584084691

百度总共提供了大概17万的标注数据,而且数据标注质量颇高。训练数据被标注为以下格式:

{"text": "《逐风行》是百度文学旗下纵横中文网签约作家清水秋风创作的一部东方玄幻小说,小说已于2014-04-28正式发布", "spo_list": [{"predicate": "连载网站", "object_type": "网站", "subject_type": "网络小说", "object": "纵横中文网", "subject": "逐风行"}, {"predicate": "作者", "object_type": "人物", "subject_type": "图书作品", "object": "清水秋风", "subject": "逐风行"}]

由该数据我们可以构造什么数据呢?

命名实体识别语料

由于语料中的每个实体都标注了实体类别,所以可以通过实体类别,构造出命名实体识别任务的语料,这17万数据集,提供了国家、城市、影视作品、人物、地点、企业、图书等10几个类别的实体,这些语料加上人名日报、msra、bosonnlp 公开的NER语料,我们就可以扩充一个更大的NER语料集;

开放关系抽取语料

虽然该数据集是面向封闭域关系抽取的数据集,其实改造一下,也能用于句子级别的开放域关系抽取任务中,比如我们可以构建一个基于序列标注的关系和实体联合抽取模型,简单的说就是给定(S,P,O)三元组和text,从中抽取一个代表关系的动宾短语或名词性短语来。比如从《逐风行》是百度文学旗下纵横中文网签约作家清水秋风创作的一部东方玄幻小说,小说已于2014-04-28正式发这句话抽取(清水秋风,创作,《逐风行》)这样的关系三元组。当然,要改造成适合开放关系抽取的语料,还有一些工作需要做。比如原来语料中的S和O是我们要抽取的内容,而P却不是,因此,我们可能需要进行二次标注或者再构建一个模型去预测出P。

很多公开的语料都可以采用类似的做法,这里就抛砖引玉一下,不一一介绍了。

标注工具

工欲善其事,必先利其器 ,标注工具能够大大提高标注效率,标注工具通过提供方便的快捷键和交互方式,让我们在相同时间,标注更多的数据。同时,还可以在标注工具中嵌入一些AI辅助标注的能力,实现机器自动标注,而我们只需要修改和删除小部分的错误标注样本,进一步提高效率。

主动学习标注

在机器学习任务中,由于数据标注代价高昂,如果能够从任务出发,通过对任务的理解来制定标准,挑选最重要的样本,使其最有助于模型的学习过程,将大大减少标注的成本, 主动学习就是解决这个问题的。关于主动学习背后的理论细节,感兴趣可以自行谷歌,这里举一个通俗易懂的例子简要解释一下。

可以

还记得支持向量机中的“支持向量”吗?当我们在分类的时候,并不是所有的点对于分割线的位置都是起决定性作用的。在离超平面特别远的区域,哪怕你增加10000个样本点,对于分割线的位置,也是没有作用的,因为分割线是由几个关键点决定的(图上三个),这几个关键点支撑起了一个分割超平面,所以这些关键点,就是支持向量。借鉴大数据标注任务上,如果能够准确的标出那些“重要”的样本,就有可能实现“事半功倍”的效果。

随机标注的结果可能是上图中的b, 准确率大约为70%。而右图就是主动学习方法找到的标注点,因为这些点几乎构成了完美分界线的边界,所以使用与中图同样的样本数,但它能够取得90%左右的准确率!

弱监督的数据标注

监督学习就是我们有一批高置信的标注数据,通过model来拟合效果。弱监督学习,就是我们很难获取足够量的高置信的标注数据,所以弱监督学习就是来解决这个问题。

这里为大家介绍一个斯坦福的研究者开源的弱监督学习通用框架 Snorkel ,由这种方法生成的标签可用于训练任意模型。已经有人将Snorkel用于处理图像数据、自然语言监督、处理半结构化数据、自动生成训练集等具体用途。

Snorkel 集成了多种知识来源作为弱监督,我们只需要在基于MapReduce模板的pipeline中编写标记函数,每个标记函数都接受一个数据点生成的概率标签,并选择返回None(无标签)或输出标签。在编写标记函数的时候,我们可以利用一切可以利用知识来标记我们的数据,这些知识可能包括,人工规则、知识图谱、已有的模型、统计信息、网页等。

如上图所示,假设我们在做NER任务,需要标注人名,可以用来构建标记函数的知识有:

文本是否在人名词库中

jieba、hanlp等NLP工具包给出的pos tag

文本是否是知识图谱中的人物实体

基于以上知识,我们就可以写出多个标记函数了。当然,通过 Snorkel 标注的数据是有噪声的,甚至很多标记函数给出的结果互相冲突。这些我们完全不用担心,因为Snorkel已经提供了解决这些问题的方法。

拿出项目的效果,向公司申请资源

最后的最后,我们可以想好算法的落地场景和价值,讲好故事,向公司和老板的争取资源!

延伸 · 阅读