百度的“2020语言与智能技术竞赛”开赛了,今年有五个赛道,分别是机器阅读理解、推荐任务对话、语义解析、关系抽取、事件抽取。每个赛道中,主办方都给出了基于PaddlePaddle的baseline模型,这里笔者也基于bert4keras给出其中三个赛道的个人baseline。
地址:https://github.com/bojone/lic2020_baselines
这里简单分析一下这三个赛道的任务特点以及对应的baseline设计。
样本示例:
{
"context": "这位朋友你好,女性出现妊娠反应一般是从6-12周左右,也就是女性怀孕1个多月就会开始出现反应,第3个月的时候,妊辰反应基本结束。而大部分女性怀孕初期都会出现恶心、呕吐的感觉,这些症状都是因人而异的,除非恶心、呕吐的非常厉害,才需要就医,否则这些都是刚怀孕的的正常症状。1-3个月的时候可以观察一下自己的皮肤,一般女性怀孕初期可能会产生皮肤色素沉淀或是腹壁产生妊娠纹,特别是在怀孕的后期更加明显。还有很多女性怀孕初期会出现疲倦、嗜睡的情况。怀孕三个月的时候,膀胱会受到日益胀大的子宫的压迫,容量会变小,所以怀孕期间也会有尿频的现象出现。月经停止也是刚怀孕最容易出现的症状,只要是平时月> 经正常的女性,在性行为后超过正常经期两周,就有可能是怀孕了。如果你想判断自己是否怀孕,可以看看自己有没有这些反应。当然这也只是多数人的怀孕表现,也有部分女性怀孕表现并不完全是这样,如果你无法确定自己是否怀孕,最好去医院检查一下。",
"qas": [
{
"question": "怀孕多久会有反应",
"id": "f2843cffb845aad0100062841222023e",
"answers": [
{
"text": "6-12周左右",
"answer_start": -1
},
{
"text": "6-12周",
"answer_start": -1
},
{
"text": "1个多月",
"answer_start": -1
}
]
}
]
}
这个baseline其实没什么好说的,就是经过BERT之后,接两个全连接+Softmax分别预测答案的首和尾。有些训练样本标注了多个答案,但预测的时候只需要预测一个答案,所以训练阶段每次只随机选取一个答案进行训练。
样本示例:
{
"text": "谢霆锋扮演的花无缺2004年由大导演王晶执导的40集电视连续剧《绝代双骄》的改版《小鱼儿与花无缺》上映,小编不是针对导演和演员,这部电视连续剧确实可说是天雷滚滚的魔改版,得亏全部主演凭借颜值和演技把观众拴住了,故事情节改的一塌糊涂",
"spo_list": [
{
"predicate": "导演",
"object": {
"@value": "王晶"
},
"subject": "小鱼儿与花无缺"
},
{
"predicate": "主演",
"object": {
"@value": "谢霆锋"
},
"subject": "小鱼儿与花无缺"
},
{
"predicate": "主角",
"object": {
"@value": "花无缺"
},
"subject": "绝代双骄"
},
{
"predicate": "饰演",
"object": {
"inWork": "小鱼儿与花无缺",
"@value": "花无缺"
},
"subject": "谢霆锋"
}
]
}
关系抽取就是去年的三元组抽取,只不过今年做了一些升级。升级的地方在于考虑同一个predicate的多义性,比如“饰演”,有可能是指饰演了哪部电视剧,也有可能指饰演了电视剧中的哪个角色,如果同一个句子中含有多个不同的被饰演的对象(object),那么要全部抽取出来才算对。说是说升级,但其实没有本质变化,我们只需要把predicate和object对应的前缀拼接起来作为不同的predicate,就退化为常规的三元组抽取问题了,比如“饰演_@value”、“饰演_inWork”当成两个不同的predicate分别抽取。笔者baseline模型依然是基于去年的“半指针-半标注”设计,详情可参考《基于DGCNN和概率图的轻量级信息抽取模型》。
样本示例:
{
"text": "雀巢裁员4000人:时代抛弃你时,连招呼都不会打!",
"id": "409389c96efe78d6af1c86e0450fd2d7",
"event_list": [
{
"event_type": "组织关系-裁员",
"trigger": "裁员",
"trigger_start_index": 2,
"arguments": [
{
"argument_start_index": 0,
"role": "裁员方",
"argument": "雀巢",
"alias": [
]
},
{
"argument_start_index": 4,
"role": "裁员人数",
"argument": "4000人",
"alias": [
]
}
],
"class": "组织关系"
}
]
}
事件抽取是一个比较新的任务,要抽取出事件类型以及描述该事件的一些元素,同一个句子可能有多个事件,同一个实体可以同时描述多个事件(比如“XX月XX日”可能同时是多个事件发生时间)。本身事件抽取是比较复杂的任务,但是这次比赛主办方只评测(event_type, role, argument) 构成的三元组,也就是这样的三元组匹配上了,就加1分。而event_type、role都是离散的类别,argument则是原文中的一个实体,所以官方这样的评测指标就将这个任务退化为普通的实体标注问题了,因此可以用常规的序列标注模型来解决,笔者的baseline以及官方的baseline,都是转化为序列标注任务给出的。
上面三个比赛,本质上都是抽取问题,也就是说输出的实体都是原文中的片段。但是原始文本经过BERT的tokenizer后,不一定跟原始文本对得上了,存在小幅度的“增”、“删”、“改”的可能性(比如转小写、空格数目变化、部分字符转写),这些小幅度的改动对于工程上的评估是无关紧要的,但是对于这种比赛或学术的评测却是很重要的,因为如果不同的字符哪怕看起来一样,都会匹配错误。比如读者可以把下属代码复制到python运行一下:
u'à' == u'à'
为了将分词后的结果对应回原序列,笔者专门花了点时间,给bert4keras的Tokenizer
补充了rematch
方法,只要传入原始文本和分词后的结果,那么将会返回token到原始文本的映射关系,有了这个映射关系,就可以直接在原始文本中切片了。具体操作大家直接看baseline即可。
写了三个baseline,又水了一篇博客~
个人微信:加时请注明 (昵称+公司/学校+方向)