Botanic

  • 3

    获得赞
  • 4

    发布的文章
  • 0

    答辩的项目

关系抽取任务的模型与实现细节

自然语言处理

最后更新 2022-05-06 20:05 阅读 4020

最后更新 2022-05-06 20:05

阅读 4020

自然语言处理

由于需要构建知识图谱,所以在实体识别的基础上,我们需要构建一个模型来识别同一个句子中实体间的关系。关系抽取本身是一个分类问题。给定两个实体和两个实体共同出现的句子文本,判别两个实体之间的关系。

在具体实现的过程中,主要参考了 crownpku_github 的模型结构。他的实践中使用了双向 GRU,字与句子的双重Attention模型,以天然适配中文特性的字向量(charactor embedding)作为输入。以下主要介绍了本次实践的一些细节,具体模型及代码请参考 github

下面主要从如下几个方面进行叙述:

  1. 为什么要选择这个模型?
  2. 特征工程是如何做到?
  3. 有哪些参数,参数量有多大
  4. 现在使用的方法有什么缺点,如何进行改进?

模型构建

BiGRU加字级别Attention的模型想法来自文章 Attention-Based Bidirectional Long Short-Term Memory Networks for Relation Classification。在这篇文章中使用的模型是BiLSTM+Attention相比于单向一层的RNN,使用BiLSTM能够更好捕捉双向的语义关系,并且能够在一定程度上减小梯度消失带来的问题。而注意力机制可以聚焦到影响分类结果的核心词语,在不使用额外知识的条件下捕捉到句子间重要的语义信息。这里将原文的模型结构中的LSTM改为GRU,且对句子中的每一个中文字符输入为character embedding。这样的模型对每一个句子输入做训练,并加入字级别的attention

BiGRU+Attention1

句子级别Attention的想法来自文章 Neural Relation Extraction with Selective Attention over Instances针对远程监督场景下的关系抽取中存在的,由于误标签传播引起的训练数据噪声过大的问题,论文作者在关系语句层面上引入Attention机制,通过赋予包含某三元组的句子的不同的权重,从而减少噪声,进而提升学习效果。这里将其中对每个句子进行encoding的CNN模块换成上面的双向GRU模型。这样的模型对每一种类别的句子输入做共同训练,加入句子级别的attention

BIGRU+Attention2

假设

  1. 一个训练样本中,即一个句子中只包含两个实体,且这两个实体之间一定是有关系的;
  2. 两个实体之间只存在一种关系,也就是说一个句子中只隐式的包含一种关系

特征构建:

输入数据由字向量与位置向量组成。对于每个字,首先确定这个字在词表中的id(用于在训练时获取其id对应的词向量),然后获得这个词与句子中两个实体的距离,这个距离的最大范围规定在-60到60之间,小于的部分设置为0,大于的部分设置为123。

在模型构建中,使用已经训练好的字向量作为字的初始化向量(向量维度为100),使用随机初始化的方式初始化位置向量(向量为5),在模型训练的过程中对位置向量的参数矩阵继续训练。对于模型输入来说,其向量维度为110,即同一字向量与两个位置向量拼接而成。最大文本长度设置为70。

模型细节:

  • BiLSTM + 字级别Attention(向量计算过程基本按采用原论文中的方法)

准备正序和逆序的文本序列及位置序列,通过向量矩阵分别获取文本向量和位置向量,然后将二者进行拼接;拼接完毕后将正序和逆序的向量分别通过BiLSTM层和dropout层,得到向量结果按位相加;

BiLSTM输出的结果首先通过一个tanh激活函数,$M = tanh(H)$;然后与一个维度为文本序列长度的参数矩阵相乘,并通过softmax得到权值(即Attention的结果)$\alpha = softmax(\omega^T M)$;将这个权值加到BiLSTM的输出结果上,得到句子最终的向量表示,$r = H \alpha^T$。公式表示为:

  • 句子级别 Attention

从一个batch中每次取出一个向量,首先计算它的tanh函数结果,然后计算当前这个句子的权值,这个权值的计算过程使用了$softmax$ ($\alpha_i = \frac {exp(e_i)}{\sum_k exp(e_k)}$),输入的数据 $e_i$ 为当前句子与对应关系的打分结果,这个结果为 $e_i = x_iAr$,其中 $x_i$ 为句向量,$A$ 为权重的对角矩阵,$r$ 为具体关系r的向量表示,这两个都是可训练的参数。得到的Attention参数 $\alpha_i$ 要乘以对应句子向量得到整个集合上的结果,公式表示为 $s = \sum_i \alpha_ix_i$

模型最终的输出结果为 $o = Ms+d$ ,其中 $M$ 为关系矩阵的表示,$d$ 为一个偏置向量,这两个都是可训练的参数。这里相当于将整个集合的 $s$ 作为输入,为其配置参数和偏置,$o$ 为这一层的输出,后面接softmax输出每个类别下的概率。

模型参数说明:

  1. BiLSTM模型中的参数,2倍的LSTM中的参数
  2. 字级别attention中的参数有1个,大小为神经元个数*1
  3. 句级别attention中的参数有4个,分别是上文的A,r,M,d,参数量见re_model.py文件

训练情况:

当前关系类别只有3个,分别是:【正向关系,反向关系,没有关系】,训练数据3000条,测试数据1000条;

其中没有关系的训练数据个数为300,通过处理数据进行构造的。

评价方法:

  • correct_by_relation表示:预测结果显示有关系,实际标签也是有关系,并且两个的结果是吻合的,进行计数(TP);
  • guessed_by_relation表示:预测显示有关系则全部进行计数(TP+FP);
  • gold_by_relation:实际标签显示有关系则全部进行计数(TP+FN)。
  1. def score(key, prediction, verbose=False):
  2. correct_by_relation = Counter()
  3. guessed_by_relation = Counter()
  4. gold_by_relation = Counter()
  5. # Loop over the data to compute a score
  6. for row in range(len(key)):
  7. gold = key[row] # 存放真实关系
  8. guess = prediction[row] # 存放预测关系
  9. if gold == NO_RELATION and guess == NO_RELATION:
  10. pass
  11. elif gold == NO_RELATION and guess != NO_RELATION:
  12. guessed_by_relation[guess] += 1
  13. elif gold != NO_RELATION and guess == NO_RELATION:
  14. gold_by_relation[gold] += 1
  15. elif gold != NO_RELATION and guess != NO_RELATION:
  16. guessed_by_relation[guess] += 1
  17. gold_by_relation[gold] += 1
  18. if gold == guess:
  19. correct_by_relation[guess] += 1
  20. # 计算presicion和recall,f1的值
  21. prec_micro = 1.0
  22. if sum(guessed_by_relation.values()) > 0:
  23. prec_micro = float(sum(correct_by_relation.values())) / float(sum(guessed_by_relation.values()))
  24. recall_micro = 0.0
  25. if sum(gold_by_relation.values()) > 0:
  26. recall_micro = float(sum(correct_by_relation.values())) / float(sum(gold_by_relation.values()))
  27. f1_micro = 0.0
  28. if prec_micro + recall_micro > 0.0:
  29. f1_micro = 2.0 * prec_micro * recall_micro / (prec_micro + recall_micro)

优化方法:

  1. 当前的位置向量计算方式是,句子中的每一个字分别到两个实体间的距离。但这个距离是每个字到实体第一个字的距离,可以尝试为每个字到实体最后一个字的距离也做位置向量,进行向量的拼接或是按位相加;

  2. batch_size的值会影响预测的准确率,因为attention的计算指定了batch_size=50,所以在预测阶段,如果batch_size的维持在50左右(甚至大于50),则预测准确率也会维持在80%以上;而如果batch_size比较小,准确率也会伴随有一定程度的降低;

  3. 比较理想的数据是,每一个完成句子中应该只包含了一种实体关系。但如果这个句子包含多个实体,且这多个实体之间又存在多个关系,这就很难对预测结果进行评价了。因为预测结果只能有1个。例如一个句子中存在3个实体1,2,3,两个关系A(1,2),B(1,3),预测结果为A,但是实际标注为【1,3,B,句子】,但是如果不看实体本身的话,B关系确实也是这个句子中的一种关系。结论:单纯针对一个句子进行预测,可能会遗漏掉很多重要信息(可以参考细粒度情感分析的相关项目;或者使用多分类的方法,一个句子中包含多种关系);
  4. 会存在一些数据不平衡的情况,主要优化方式采用了欠采样的策略进行优化的,准确率提升并不明显。由于采用随机抽样的方式进行构建数据集,欠采样有可能漏掉一些包含关键信息的句子样本。解决数据不平衡的问题,还需要进一步实践。

模型总结:

(1)关系抽取本身与分类模型并没有什么区别。首先我们需要知道每一条文本数据中包含了哪两个实体,并且他们之间存在哪种关系,这里的关系就是标签;

(2)输入数据,是采用字向量(对句子中的每个字做embedding)和位置向量(对句子中每个字与两个实体之间的距离进行编码)拼接的方式,共同组成模型的输入;

(3)在最终输出层加入了attention层,对每个句子中每个字做attention,得到的结果再接全连接层和softmax,得到的结果就是softmax后的logits结果,对这个结果进行评价

(4)可优化的方面见3.

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,转载请附上原文出处链接和本声明。
本文链接地址:https://flyai.com/article/992
讨论(0)
500字
表情
发送
删除确认
是否删除该条评论?
取消 删除