本文不深入机器学习算法和程序源码部分,可以作为认识关系抽取基本概念的短文放心食用。
在开始前,我们先初步了解一下什么是关系抽取
1 . 关系抽取
0x1定义 关系是什么?
举个简单的例子
实体 | 关系 | 实体
Beijing | is the capital of | China
他们构成SPO三元组:subject主语、predicate谓语、object宾语
spo三元组是实体识别、关系抽取中的基本概念,也是信息抽取的基本单元
0x2抽取方法
Word Embedding词向量:将某一个词语或短语映射为具体向量
{‘word’: ‘the’, ‘vec’: [0.418, 0.24968, …]},
{‘word’: ‘,’ , ‘vec’: [0.013441, 0.23682, …]},
不同单词的含义不同,实际操作中,我们把单词编码成向量,用”特征”来描述单词,特征值相近的单词有着相似的含义,反过来意思相近的单词可以通过这种方式更好地表达他们的语义与内在联系,即用一个词周围的词来表达这个词。
Dependency tree依赖树:这个依赖树是一个“有序”的树,即它反映了实际的词序

大多数现有的关系提取模型可以分为两类:基于序列和基于依赖关系。基于序列的模型只对词的序列进行操作,而基于依赖的模型则将依赖树纳入模型。
与基于序列的模型相比,基于依赖的模型能够捕捉到仅从表面形式上看不清楚的非局部句法关系。为了进一步提高性能,人们还提出了各种修剪策略来提炼依赖信息。
除了这种分类方法,因为数据集(dataset)标注的时间、人力成本高,近年来诞生了各种弱监督(weakly-supervised)和无监督(unsupervised)的模型包括
Semi-supervised learning半监督学习:包括少量标注数据和大量未标注数据
distantly-supervised远程监督:识别句子中实体,对齐三元组得到两者间的关系。
few-shot少样本学习、unsupervised无监督……等等
最经典的关系抽取考虑的是两个实体都包含在一个句子里的情形,也就是Sentence-Level Relation Extraction,并且这两个实体间的关系是可以确定的。
这次我准备尝试的OpenNRE中提供了
0x3评价测试结果
模型评估指标AUC:AUC(Area Under Curve)被定义为ROC曲线下与坐标轴围成的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。AUC越接近1.0,检测方法真实性越高;小于等于0.5时,则无应用价值。
精确率:Precision,针对预测结果而言的,它表示的是预测为正的样本中有多少是真正的正样本
召回率:Recall,针对原来的样本而言的,它表示的是样本中的正例有多少被预测正确了
F值:综合考虑精确率和召回率F1 = (2*P*R)/(P+R)
2 . 使用OpenNRE
0x1介绍
OpenNRE 是由清华NLP实验室开发的一个开源的、可扩展的工具包,它提供了一个统一的框架来实现关系抽取模型。
论文地址:https://www.aclweb.org/anthology/D19-3029
github:https://github.com/thunlp/OpenNRE
0x2安装
从github上clone到本地,按照指导一步步完成操作即可。
注意,原文件提供的setup.py不支持windows系统,可以自行去网上找支持的版本。
我使用的平台是Ubuntu20.04虚拟机、pytorch1.6.0、python3,使用python3运行安装脚本。
0x3模型选择
最经典的关系抽取考虑的是两个实体都包含在一个句子里的情形,也就是Sentence-Level Relation Extraction,并且这两个实体间的关系是可以确定的。
这次我准备尝试的OpenNRE中提供的数个模型处理的都是句级关系抽取。
- wiki80_cnn_softmax: 在 wiki80数据集上训练,带有 CNN 编码器。
- wiki80_bert_softmax: 使用带有 BERT 编码器的 wiki80数据集进行训练。
- wiki80_bertentity_softmax:使用带有 BERT 编码器的 wiki80数据集进行训练(使用实体表示连接)。
根据OpenNRE上的原文(We also provide a new dataset Wiki80, which is derived from FewRel.)来看Wiki80是由清华发布的数据集FewRel上提取的。
Wiki80数据集完全由人工标注,无噪声,其中包含80对常见的实体关系,每个关系个数都为700。
样本格式: 例子:{“token”: [“Vahitahi”, “has”, “a”, “territorial”, “airport”, “.”], “h”: {“name”: “territorial airport”, “id”: “Q16897548”, “pos”: [3, 5]}, “t”: {“name”: “vahitahi”, “id”: “Q1811472”, “pos”: [0, 1]}, “relation”: “place served by transport hub”}
“token”:标记处理后的句子 “h”:样本中的头实体的名字以及位置
“t”:样本中的尾实体的名字以及位置
0x4实践
加载软件包
>>> import opennre
>>> model = opennre.get_model(‘wiki80_cnn_softmax’)
查询格式为
>>>model.infer({‘text’: ‘He was the son of Máel Dúin mac Máele Fithrich, and grandson of the high king Áed Uaridnach (died 612).’, ‘h’: {‘pos’: (18, 46)}, ‘t’: {‘pos’: (78, 91)}})
这里我针对关系‘winner’进行测试,分别设置3句内容相似的话进行置信度比较,比较相同模型在不同情况下的表现和不同模型对同一语句的反馈结果。
Chinese Team EDG wins LoL Esports World Championship 2021.
Edward Gaming’s victory ended DWG KIA’s chance to win back-to-back world championships.
China’s Edward Gaming team, is dominating trending topic lists on Chinese social media this weekend for winning the League of Legends World Championship.
测试时注意不要把语句中的单引号和外层单引号闭合,或者也可以直接用中文单引号。
为了便于测试,我写了一个c程序来生成测试语句。

得到三个语句
model.infer({‘text’: ‘Chinese Team EDG wins LoL Esports World Championship 2021.’, ‘h’: {‘pos’: (13, 16)}, ‘t’: {‘pos’: (22,57)}})
model.infer({‘text’: ‘Edward Gaming\’s victory ended DWG KIA\’s chance to win back-to-back world championships.’, ‘h’: {‘pos’: (0, 13)}, ‘t’: {‘pos’: (31,38)}})
model.infer({‘text’: ‘China’s Edward Gaming team, is dominating trending topic lists on Chinese social media this weekend for winning the League of Legends World Championship.’, ‘h’: {‘pos’: (10, 28)}, ‘t’: {‘pos’: (114,154)}})
- wiki80_cnn_softmax
结果分别是
(‘occupant’, 0.3708553910255432)
(‘member of’, 0.35048750042915344)
(‘league’, 0.877382755279541)
- wiki80_bert_softmax
结果分别是
(‘winner’, 0.995232880115509)
(‘winner’, 0.9677496552467346)
(‘winner’, 0.9625738859176636)
- wiki80_bertentity_softmax
结果分别是
(‘participant of’, 0.9236127138137817)
(‘member of’, 0.1834011673927307)
(‘participant of’, 0.4932926893234253)
对比这三个使用同一训练集得到的模型,可以发现使用bert对模型进行预训练后,其结果的准确度明显高于直接训练的模型。
而采用entity representation concatenation的模型会在关系抽取中出现一定的偏差,语义分析能力在一定程度上减弱。
看到bert模型带来的巨大变化很有意思,关于bert在其他类型数据集和模型上的效果也是值得去尝试的。
参考资料
- Zhijiang Guo , Yan Zhang and Wei Lu. 2019. Attention Guided Graph Convolutional Networks for Relation Extraction. In Proc. of ACL
- Han, Xu and Gao, Tianyu and Yao, Yuan and Ye, Deming and Liu, Zhiyuan and Sun, Maosonghttps://github.com/thunlp/OpenNRE
- 风霖https://www.zhihu.com/people/wu-rui-dong-72)https://www.zhihu.com/column/c_1047871657112346624
- devil_son1234https://blog.csdn.net/devil_son1234/article/details/107082647