• 主页
  • 算法
  • 小桥流水人家
  • python
  • linux
  • mysql
所有文章 友链 关于我

  • 主页
  • 算法
  • 小桥流水人家
  • python
  • linux
  • mysql

coreference resolution

2021-12-17

介绍

共指解析,按照百度的定义如下:

1
众所周知,人们为了避免重复,习惯用代词、称谓和缩略语来指代前面提到的实体全称。例如,在文章开始处会写“哈尔滨工业大学”,后面可能会说“哈工大”、“工大”等,还会提到“这所大学”、“她”等。这种现象称为共指现象。

简而言之,其目的在于自动识别表示同一实体的名词短语或代词等。

举个例子:

哈尔滨工业大学,一般学生或者大众喜欢简称为哈工大,工大等,她是一所美丽的大学。

实体(entity): 应是唯一定义的,并且具有共知的。哈尔滨工业大学即为这句话的实体。
指称(mention): 实体在自然语言文本中的另外一种表达形式,哈工大,工大,她都是指称。
共指(coreference): 如果文本或句子中的两个或多个mention指向同一个entity,那么则称为共指。

到这里可以看出,一个复杂的句子中可能会有多个实体以及对应的多个指称共指于不同的实体,这可以是一个分类任务也可以是一个聚类任务。

根据认知,中文里面能做实体的一般是专有名词,比如清华大学,《海蒂》,各行各业有不同的专有名词。另外就是名词或者名词短语以及代词,比如这人,他,它,她等。

下面介绍一种算法。

Word-Level Coreference Resolution

论文地址: Word-Level Coreference Resolution
代码地址:wl-coref

先说个人感受,这个咋感觉更像是提升速度,topK操作,而没有那么多骚操作来提升效果。代码质量杠杠的,但是不是batch训练,又有点怪怪的~

代码对于训练部分看完了,如果有说的不对的,或者没有涵盖到重点的,非常欢迎指教!

1. 获得word level embedding

  • 获取subtoken输入bert后得到的向量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def _bertify(self, doc: Doc) -> torch.Tensor:
subwords_batches = bert.get_subwords_batches(doc, self.config,
self.tokenizer)

special_tokens = np.array([self.tokenizer.cls_token_id,
self.tokenizer.sep_token_id,
self.tokenizer.pad_token_id])
subword_mask = ~(np.isin(subwords_batches, special_tokens))

subwords_batches_tensor = torch.tensor(subwords_batches,
device=self.config.device,
dtype=torch.long)
subword_mask_tensor = torch.tensor(subword_mask,
device=self.config.device)

# Obtain bert output for selected batches only
attention_mask = (subwords_batches != self.tokenizer.pad_token_id)
out, _ = self.bert(
subwords_batches_tensor,
attention_mask=torch.tensor(
attention_mask, device=self.config.device))
del _

# [n_subwords, bert_emb]
return out[subword_mask_tensor]

  • 获取word level embedding
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from typing import Tuple

import torch

from coref.config import Config
from coref.const import Doc


class WordEncoder(torch.nn.Module): # pylint: disable=too-many-instance-attributes
def __init__(self, features: int, config: Config):

super().__init__()
self.attn = torch.nn.Linear(in_features=features, out_features=1)
self.dropout = torch.nn.Dropout(config.dropout_rate)


def forward(self, # type: ignore # pylint: disable=arguments-differ #35566 in pytorch
doc: Doc,
x: torch.Tensor,
) -> Tuple[torch.Tensor, ...]:

word_boundaries = torch.tensor(doc["word2subword"], device=self.device)
# 每个token被tokenizer为subtokens后,starts记录每个token的起始位置
starts = word_boundaries[:, 0]
# ends记录每个token的结束位置
ends = word_boundaries[:, 1]

# [n_mentions, features]
words = self._attn_scores(x, starts, ends).mm(x)

words = self.dropout(words)

return (words, self._cluster_ids(doc))

def _attn_scores(self,
bert_out: torch.Tensor,
word_starts: torch.Tensor,
word_ends: torch.Tensor) -> torch.Tensor:

n_subtokens = len(bert_out)
n_words = len(word_starts)

# [n_mentions, n_subtokens]
# with 0 at positions belonging to the words and -inf elsewhere
# 只有start到end之间的为0,否则为-inf
attn_mask = torch.arange(0, n_subtokens, device=self.device).expand((n_words, n_subtokens))
attn_mask = ((attn_mask >= word_starts.unsqueeze(1))
* (attn_mask < word_ends.unsqueeze(1)))
attn_mask = torch.log(attn_mask.to(torch.float))
# 每一个subtoken被降维为1,比如一个句子有477个subtokens,bert_out为(477, 768),attn_scores就变成了(1,477)
attn_scores = self.attn(bert_out).T # [1, n_subtokens]
attn_scores = attn_scores.expand((n_words, n_subtokens))
attn_scores = attn_mask + attn_scores
del attn_mask
# 做归一化
return torch.softmax(attn_scores, dim=1) # [n_words, n_subtokens]

  • 这部分可以看我最后简单示例,说明实现方式。

假设tokens长度为455, 这里输出就变成了word level embedding。

粗排(rough score)

还是觉得,不考虑batch_size那一维,整个代码都方便理解许多😂😂😂😂😂😂😂😂😂😂。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class RoughScorer(torch.nn.Module):
def __init__(self, features: int, config: Config):
super().__init__()
self.dropout = torch.nn.Dropout(config.dropout_rate)
self.bilinear = torch.nn.Linear(features, features)

self.k = config.rough_k

def forward(self, # type: ignore # pylint: disable=arguments-differ #35566 in pytorch
mentions: torch.Tensor,
) -> Tuple[torch.Tensor, torch.Tensor]:

# 这里一共做了两件事情
# 1. 获取token和token之间的关联矩阵,可用于表示之间的关联程度。
# [n_mentions, n_mentions]
pair_mask = torch.arange(mentions.shape[0])
pair_mask = pair_mask.unsqueeze(1) - pair_mask.unsqueeze(0)
pair_mask = torch.log((pair_mask > 0).to(torch.float))
pair_mask = pair_mask.to(mentions.device) # -- 首先构建掩码矩阵,该矩阵为一个下三角矩阵,含义为每个词只能取该词之前的词作为候选词。

# 但是有啥说啥,我就搞不明白为啥这里还要加一个bilinear,这不有点多此一举么,维度没发生改变,谁能知道给我解答下~
# 不过没人看😂😂😂😂😂😂
bilinear_scores = self.dropout(self.bilinear(mentions)).mm(mentions.T)

rough_scores = pair_mask + bilinear_scores
# 2. 获取每个token的topK tokens。
return self._prune(rough_scores)

def _prune(self,
rough_scores: torch.Tensor
) -> Tuple[torch.Tensor, torch.Tensor]:
# 骚气吧,是不是又get到新操作。不过这个sorted,不管true还是false结果都不变😂😂😂😂😂😂
top_scores, indices = torch.topk(rough_scores,
k=min(self.k, len(rough_scores)),
dim=1, sorted=False)
return top_scores, indices

获取词对特征

看到么看到么,人家到这里才开始干活~

top_indices的维度为(405,50),表示这个句子一共有405个tokens,然后获取每个token最相关联的50个tokens的索引。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def forward(self,  # type: ignore  # pylint: disable=arguments-differ  #35566 in pytorch
top_indices: torch.Tensor,
doc: Doc) -> torch.Tensor:
word_ids = torch.arange(0, len(doc["cased_words"]), device=self.device)
# 一、same speaker特征
speaker_map = torch.tensor(self._speaker_map(doc), device=self.device)
# 获取speaker_map对应位置的值,最终输出维度和top_indices一样
# 看这一步操作,妥妥让我难理解半个小时~
# 1. speaker_map[top_indices]这里,第一次见这种map操作,学习了
# 2. 这种广播写法让我觉得,emmmmm,还不如expand下来的更直接
same_speaker = (speaker_map[top_indices] == speaker_map.unsqueeze(1)) # 广播
same_speaker = self.speaker_emb(same_speaker.to(torch.long))

# 二、距离特征
# 这个特征我觉得还是挺有用的,1、加速了训练和推理速度 2、加快收敛速度
# bucketing the distance (see __init__())
distance = (word_ids.unsqueeze(1) - word_ids[top_indices]
).clamp_min_(min=1) # 小于1的变成1
log_distance = distance.to(torch.float).log2().floor_()
log_distance = log_distance.clamp_max_(max=6).to(torch.long) # 大于最大值的元素将变为最大值。 那么就是64
# 一会log_distance一会distance的,看着就不容易理解,直接到log_distance多好😂😂😂😂😂😂
distance = torch.where(distance < 5, distance - 1, log_distance + 2)
distance = self.distance_emb(distance)

# 三、同一文档特征
genre = torch.tensor(self.genre2int[doc["document_id"][:2]],
device=self.device).expand_as(top_indices)
genre = self.genre_emb(genre)

return self.dropout(torch.cat((same_speaker, distance, genre), dim=2))

AnaphoricityScorer

这部分看着有点绕,看如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def forward(self, *,  # type: ignore  # pylint: disable=arguments-differ  #35566 in pytorch
all_mentions: torch.Tensor,
mentions_batch: torch.Tensor,
pw_batch: torch.Tensor,
top_indices_batch: torch.Tensor,
top_rough_scores_batch: torch.Tensor,
) -> torch.Tensor:

# [batch_size, n_ants, pair_emb]
pair_matrix = self._get_pair_matrix(
all_mentions, mentions_batch, pw_batch, top_indices_batch)

# [batch_size, n_ants]
scores = top_rough_scores_batch + self._ffnn(pair_matrix)
scores = utils.add_dummy(scores, eps=True)

return scores

def _ffnn(self, x: torch.Tensor) -> torch.Tensor:
"""
Calculates anaphoricity scores.

Args:
x: tensor of shape [batch_size, n_ants, n_features]

Returns:
tensor of shape [batch_size, n_ants]
"""
x = self.out(self.hidden(x))
return x.squeeze(2)

@staticmethod
def _get_pair_matrix(all_mentions: torch.Tensor,
mentions_batch: torch.Tensor,
pw_batch: torch.Tensor,
top_indices_batch: torch.Tensor,
) -> torch.Tensor:

emb_size = mentions_batch.shape[1]
n_ants = pw_batch.shape[1]
# 计算所有tokens和这50个tokens的关联度
a_mentions = mentions_batch.unsqueeze(1).expand(-1, n_ants, emb_size)
b_mentions = all_mentions[top_indices_batch]
similarity = a_mentions * b_mentions

out = torch.cat((a_mentions, b_mentions, similarity, pw_batch), dim=2)
return out

_get_pair_matrix中的b_mentions,可参考b_mentions。后续接了个ffnn,获得其最终得分。

整体代码作者挺喜欢参差网络和前馈神经网络这种操作。

loss计算

CorefLoss计算分成了两部分,一个是NLML,另外一个BCELoss.

1
2
3
4
5
6
@staticmethod
def _nlml(input_: torch.Tensor, target: torch.Tensor) -> torch.Tensor:
# gold这地方明显就想计算相关性。
gold = torch.logsumexp(input_ + torch.log(target), dim=1)
input_ = torch.logsumexp(input_, dim=1)
return (input_ - gold).mean()

附录

word-level实现demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# -*- coding: utf8 -*-
#

import torch


class WordEmbedding(torch.nn.Module):
def __init__(self, n_in, p):
super(WordEmbedding, self).__init__()
self.n_in = n_in
self.p = p
self.linear = torch.nn.Linear(in_features=n_in, out_features=1)

def forward(self, x, indices):
start_end_indices_to_tensor = torch.tensor(indices)
start_indices = start_end_indices_to_tensor[:, 0]
end_indices = start_end_indices_to_tensor[:, 1]
mask = torch.arange(5).expand(3, 5)

attn_mask = (mask >= start_indices.unsqueeze(1)) * (mask < end_indices.unsqueeze(1))
attn_mask = torch.log(attn_mask.to(torch.float))
attn_scores = self.linear(x).T
attn_scores = attn_scores.expand((len(indices), x.size(0)))
attn_scores = attn_scores + attn_mask
return torch.softmax(attn_scores, dim=1).mm(x)


if __name__ == '__main__':
# 假设为:我 是 中国人,5为每个subtoken,10为每个subtoken的embedding
word_feature = torch.arange(50, dtype=torch.float).view(5, 10)
# 那么index是:
start_end_indices = [(0, 1), (1, 2), (2, 5)]

we = WordEmbedding(n_in=10, p=0.1)
we.forward(word_feature, start_end_indices)

取索引操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>> a
tensor([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])

# b对应top50选出来的index
>>> b
tensor([[0, 1],
[1, 2],
[2, 2]])

>>> a[b]
tensor([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9]],

[[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]],

[[10, 11, 12, 13, 14],
[10, 11, 12, 13, 14]]])
>>> a[b].shape
torch.Size([3, 2, 5])



精彩例子

这种写法我挺喜欢的,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

>>> aa
tensor([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> mm
tensor([[ True, True, False, True, True],
[False, True, True, True, True]])

# 一般会在最后计算loss时加上mask进行降维铺平
>>> aa[mm]
tensor([0, 1, 3, 4, 6, 7, 8, 9])

# 形式1: 作者将无关的score置为-inf
>>> aa * torch.log(mm.to(torch.float))
tensor([[0., 0., -inf, 0., 0.],
[-inf, 0., 0., 0., 0.]])

# 形式2:
>>> aa * mm
tensor([[0, 1, 0, 3, 4],
[0, 6, 7, 8, 9]])

  • 算法

展开全文 >>

活到老学到老之index操作

2021-12-16

快速想一想,你能想到torch有哪些常见的index操作??

1. gather

1
2
3
4
5
6
>>> a = torch.tensor([[1, 2, 3],
[4, 5, 6]])
>>> a.gather(dim=1, index=torch.tensor([[0,1], [1,2]]))
tensor([[1, 2],
[5, 6]])

2. index_select

1
2
3
4
5
6
7
>>> a
tensor([[1, 2, 3],
[4, 5, 6]])
>>> a.index_select(dim=1, index=torch.tensor([1,2]))
tensor([[2, 3],
[5, 6]])

3. 骚气的来了哦

根据上面例子可以看到,a为矩阵,选择a中的index,但是下面介绍一个map操作.

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> index
tensor([[1, 2, 3],
[4, 5, 6]])

>>> a = torch.tensor([11, 22, 33, 44, 55, 66, 77])
>>> a
tensor([11, 22, 33, 44, 55, 66, 77])
>>> index
tensor([[1, 2, 3],
[4, 5, 6]])
>>> a[index]
tensor([[22, 33, 44],
[55, 66, 77]])

这种操作有一个真实场景,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 1. 这是两个特征
>>> words = ['我', '爱', '中', '国']
>>> pos = ['n', 'v', 'n', 'n']

# 2. 假设words变成了一个4 * 4的临接矩阵,用于表示每个token和其他token的一个关联重要程度

>>> words_attn = torch.rand(4,4)

>>> words_attn
tensor([[0.6279, 0.6234, 0.9831, 0.5267],
[0.2265, 0.8453, 0.5740, 0.4772],
[0.7759, 0.6952, 0.1758, 0.3800],
[0.9998, 0.3138, 0.5078, 0.5565]])


>>> scores, indices = words_attn.topk(k=2, dim=1)

>>> indices
tensor([[2, 0],
[1, 2],
[0, 1],
[0, 3]])

# 3. 假设pos转为了
>>> pos_tensor = torch.tensor([111, 222, 333, 444])

# 4. map操作
>>> pos_tensor[indices]
tensor([[333, 111],
[222, 333],
[111, 222],
[111, 444]])

# 5. 随后就可以接一个embedding搞事情了
pos_embedding(pos_tensor[indices])

# 6. 总结,这个示例的优点可以看出是快速计算,取topK然后再结合其他的特征进行操作。

4. batch_gather

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import torch


def batch_gather(data: torch.Tensor, index: torch.Tensor):
index = index.unsqueeze(-1).repeat_interleave(data.size()[-1], dim=-1) # (bs, n, hidden)
# index = index.unsqueeze(-1).expand(*(*index.shape, data.shape[-1]))
return torch.gather(data, 1, index)


if __name__ == '__main__':
a = torch.randn(3, 128, 312)
indices = torch.tensor([
[1, 2],
[5, 6],
[7, 7]
])
output = batch_gather(a, indices)
print(output.shape)
print((output[0][0] == a[0][1]).all())
print((output[0][1] == a[0][2]).all())
print((output[1][0] == a[1][5]).all())
print((output[1][1] == a[1][6]).all())
print((output[2][0] == a[2][7]).all())
print((output[2][1] == a[2][7]).all())

  • 算法

展开全文 >>

语义依存分析

2021-11-15

定义(ltp)

语义依存分析 (Semantic Dependency Parsing, SDP),分析句子各个语言单位之间的语义关联,并将语义关联以依存结构呈现。
使用语义依存刻画句子语义,好处在于不需要去抽象词汇本身,而是通过词汇所承受的语义框架来描述该词汇,而论元的数目相对词汇来说数量总是少了很多的。
语义依存分析目标是跨越句子表层句法结构的束缚,直接获取深层的语义信息。
例如以下三个句子,用不同的表达方式表达了同一个语义信息,即张三实施了一个吃的动作,吃的动作是对苹果实施的。



语义依存分析不受句法结构的影响,将具有直接语义关联的语言单元直接连接依存弧并标记上相应的语义关系。这也是语义依存分析与句法依存分析的重要区别。

如上例对比了句法依存和语义分析的结果,可以看到两者存在两个显著差别。
第一,句法依存某种程度上更重视非实词(如介词)在句子结构分析中的作用,而语义依存更倾向在具有直接语义关联的实词之间建立直接依存弧,非实词作为辅助标记存在。
第二,两者依存弧上标记的语义关系完全不同,语义依存关系是由论元关系引申归纳而来,可以用于回答问题,如我在哪里喝汤,我在用什么喝汤,谁在喝汤,我在喝什么。但是句法依存却没有这个能力。
第三,句法依存为树结构,语义依存为图结构,即是说当前词的依存弧可以有多个。

语义依存与语义角色标注之间也存在关联,语义角色标注只关注句子主要谓词的论元及谓词与论元之间的关系,而语义依存不仅关注谓词与论元的关系,还关注谓词与谓词之间、论元与论元之间、论元内部的语义关系。语义依存对句子语义信息的刻画更加完整全面。

实现

https://github.com/geasyheart/semantic-dependency-parser

欢迎Star!

1. 数据集

目前貌似公开的只有SEMEVAL2016数据集,地址在:HIT-SCIR/SemEval-2016,代码仓库中的数据集是将text和news两类合并而来。

额外插一句,对于一个算法项目来讲,不仅仅是算法部分,还要有数据,即使不能公开,也可以造一些例子,能够跑通算法,HanLP在这方面真的是无敌存在!

2. 模型结构

  • 这里使用到的模型结构:
1
2
3
4
5
6
7
8
9
10
11
semantic_dependency_parser.py [line:34] INFO SemanticDependencyModel(
(encoder): TransformerEmbedding(hfl/chinese-electra-180g-small-discriminator, n_layers=4, n_out=256, stride=256, pooling=mean, pad_index=0, dropout=0.33, requires_grad=True)
(tag_embedding): Embedding(41, 64)
(edge_mlp_d): MLP(n_in=320, n_out=600, dropout=0.33)
(edge_mlp_h): MLP(n_in=320, n_out=600, dropout=0.33)
(label_mlp_d): MLP(n_in=320, n_out=600, dropout=0.33)
(label_mlp_h): MLP(n_in=320, n_out=600, dropout=0.33)
(edge_attn): Biaffine(n_in=600, n_out=2, bias_x=True, bias_y=True)
(label_attn): Biaffine(n_in=600, n_out=158, bias_x=True, bias_y=True)
(criterion): CrossEntropyLoss()
)
  • HanLP使用的模型结构:
1
2
3
4
5
6
7
8
9
10
11
BiaffineDependencyModel(
(encoder): EncoderWithContextualLayer()
(biaffine_decoder): BiaffineDecoder(
(mlp_arc_h): MLP(n_in=256, n_out=500, dropout=0.33)
(mlp_arc_d): MLP(n_in=256, n_out=500, dropout=0.33)
(mlp_rel_h): MLP(n_in=256, n_out=100, dropout=0.33)
(mlp_rel_d): MLP(n_in=256, n_out=100, dropout=0.33)
(arc_attn): Biaffine(n_in=500, n_out=1, bias_x=True)
(rel_attn): Biaffine(n_in=100, n_out=136, bias_x=True, bias_y=True)
)
)

和dependency parser结构相同,但是loss计算和解码部分不同。

区别点在于,举个例子:

1
2
3
4
5
# pred_arcs.shape
(32, 49, 49)
# true_arcs.shape
(32, 49)

因为dependency parser有一个限制,即当前词只可能依存其他一个词,那么argmax(-1)即是在49那里获取最大的,表示和这49个词中最大的作为依存关系,使用交叉熵。

而semantic dependency parser没有这个限制,当前词可能和多个词存在依存关系,那么他的pred_arcs和true_arcs的维度是一样的,都是(32, 49, 49),所以使用BCELoss。

当然也可以用交叉熵,只需要将pred_arcs的维度转换成(32, 49, 49, 2)即可,也是我下面的做法。

3. loss计算和解码

在这里计算loss时,采用的是交叉熵,也就是说s_edge.size(-1) == 2,表示当前词和句子所有词之间是或者否,然后argmax(-1)进行解码。

在HanLP计算loss时,对于arc(即edge)的shape为(batch_size, seq_length, seq_length),因为biaffine的输出维度为1,所以这里计算loss时使用BCELoss,表示当前词和句子所有词之间是否存在关系。

另外一个两者的区别点在于计算rel时,HanLP采取的方式是各自计算各自的loss(即arc和rel),然后loss相加。
这里计算rel loss时融合了arc的信息进来,好处就在于能够快速收敛和提升准确度吧。

各模块技术指标

https://www.ltp-cloud.com/intro#benchmark

ltp关系类型

关系类型 Tag Description Example
施事关系 Agt Agent 我送她一束花 (我 <-- 送)
当事关系 Exp Experiencer 我跑得快 (跑 --> 我)
感事关系 Aft Affection 我思念家乡 (思念 --> 我)
领事关系 Poss Possessor 他有一本好读 (他 <-- 有)
受事关系 Pat Patient 他打了小明 (打 --> 小明)
客事关系 Cont Content 他听到鞭炮声 (听 --> 鞭炮声)
成事关系 Prod Product 他写了本小说 (写 --> 小说)
源事关系 Orig Origin 我军缴获敌人四辆坦克 (缴获 --> 坦克)
涉事关系 Datv Dative 他告诉我个秘密 ( 告诉 --> 我 )
比较角色 Comp Comitative 他成绩比我好 (他 --> 我)
属事角色 Belg Belongings 老赵有俩女儿 (老赵 <-- 有)
类事角色 Clas Classification 他是中学生 (是 --> 中学生)
依据角色 Accd According 本庭依法宣判 (依法 <-- 宣判)
缘故角色 Reas Reason 他在愁女儿婚事 (愁 --> 婚事)
意图角色 Int Intention 为了金牌他拼命努力 (金牌 <-- 努力)
结局角色 Cons Consequence 他跑了满头大汗 (跑 --> 满头大汗)
方式角色 Mann Manner 球慢慢滚进空门 (慢慢 <-- 滚)
工具角色 Tool Tool 她用砂锅熬粥 (砂锅 <-- 熬粥)
材料角色 Malt Material 她用小米熬粥 (小米 <-- 熬粥)
时间角色 Time Time 唐朝有个李白 (唐朝 <-- 有)
空间角色 Loc Location 这房子朝南 (朝 --> 南)
历程角色 Proc Process 火车正在过长江大桥 (过 --> 大桥)
趋向角色 Dir Direction 部队奔向南方 (奔 --> 南)
范围角色 Sco Scope 产品应该比质量 (比 --> 质量)
数量角色 Quan Quantity 一年有365天 (有 --> 天)
数量数组 Qp Quantity-phrase 三本书 (三 --> 本)
频率角色 Freq Frequency 他每天看书 (每天 <-- 看)
顺序角色 Seq Sequence 他跑第一 (跑 --> 第一)
描写角色 Desc(Feat) Description 他长得胖 (长 --> 胖)
宿主角色 Host Host 住房面积 (住房 <-- 面积)
名字修饰角色 Nmod Name-modifier 果戈里大街 (果戈里 <-- 大街)
时间修饰角色 Tmod Time-modifier 星期一上午 (星期一 <-- 上午)
反角色 r + main role 打篮球的小姑娘 (打篮球 <-- 姑娘)
嵌套角色 d + main role 爷爷看见孙子在跑 (看见 --> 跑)
并列关系 eCoo event Coordination 我喜欢唱歌和跳舞 (唱歌 --> 跳舞)
选择关系 eSelt event Selection 您是喝茶还是喝咖啡 (茶 --> 咖啡)
等同关系 eEqu event Equivalent 他们三个人一起走 (他们 --> 三个人)
先行关系 ePrec event Precedent 首先,先
顺承关系 eSucc event Successor 随后,然后
递进关系 eProg event Progression 况且,并且
转折关系 eAdvt event adversative 却,然而
原因关系 eCau event Cause 因为,既然
结果关系 eResu event Result 因此,以致
推论关系 eInf event Inference 才,则
条件关系 eCond event Condition 只要,除非
假设关系 eSupp event Supposition 如果,要是
让步关系 eConc event Concession 纵使,哪怕
手段关系 eMetd event Method
目的关系 ePurp event Purpose 为了,以便
割舍关系 eAban event Abandonment 与其,也不
选取关系 ePref event Preference 不如,宁愿
总括关系 eSum event Summary 总而言之
分叙关系 eRect event Recount 例如,比方说
连词标记 mConj Recount Marker 和,或
的字标记 mAux Auxiliary 的,地,得
介词标记 mPrep Preposition 把,被
语气标记 mTone Tone 吗,呢
时间标记 mTime Time 才,曾经
范围标记 mRang Range 都,到处
程度标记 mDegr Degree 很,稍微
频率标记 mFreq Frequency Marker 再,常常
趋向标记 mDir Direction Marker 上去,下来
插入语标记 mPars Parenthesis Marker 总的来说,众所周知
否定标记 mNeg Negation Marker 不,没,未
情态标记 mMod Modal Marker 幸亏,会,能
标点标记 mPunc Punctuation Marker ,。!
重复标记 mPept Repetition Marker 走啊走 (走 --> 走)
多数标记 mMaj Majority Marker 们,等
实词虚化标记 mVain Vain Marker
离合标记 mSepa Seperation Marker 吃了个饭 (吃 --> 饭) 洗了个澡 (洗 --> 澡)
根节点 Root Root 全句核心节点
  • 算法

展开全文 >>

bio-based语义角色标注

2021-11-12

定义

定义1:

1
Semantic Role Labeling (SRL) is defined as the task to recognize arguments for a given predicate and assign semantic role labels to them.

定义2(ltp):

1
语义角色标注 (Semantic Role Labeling, SRL) 是一种浅层的语义分析技术,标注句子中某些短语为给定谓词的论元 (语义角色) ,如施事、受事、时间和地点等。其能够对问答系统、信息抽取和机器翻译等应用产生推动作用。 仍然是上面的例子,语义角色标注的结果为:

实现

https://github.com/geasyheart/srl-parser

欢迎Star!

示例1:


看黄色那部分:

  • 他叫汤姆,他作为施事者,叫为谓语,汤姆为受事者
  • 去拿外衣(为一个完整语义)
  • 汤姆拿外衣,汤姆为施事者,拿为谓语,外衣为受事者

示例2:

‘各位/PN 好/VA ,/PU 欢迎/VV 您/PN 收看/VV 国际/NN 频道/NN 的/DEG 今日/NT 关注/NN 。/PU’

此图自己画的,如有需要可参考

  • 欢迎您,欢迎为谓语,您为受事者,收看国际频道的今日关注为语义角色
  • 其余忽略…

数据集

数据集来自ontonotes5.0,但是此为收费数据集,或者需要大学帐号注册,找到一个开源的https://github.com/GuocaiL/Coref_Resolution/archive/master.zip#data/,处理后的数据集以 jsonlines后缀存储,放到此处。

具体的处理逻辑可参考这里。

实现

目前常见的有span-based,bio-based,treecrf,treecrf是yzhangcs的实现方式。bio-based是用序列标注的方式来做(hanlp和ltp均以此实现),故是本文的重点。

数据处理

看这个文件,其中预测的label处理后是这个样子,解释如下:

  • 各位 好,好是第二个字,和第一个词有关系,关系为3。
  • 欢迎 您收看国际频道的今日关注, 对应关系为1, 13, 23, 23, 23, 23, 23。
1
2
3
4
5
6
7
8
9
10
11
12
13
tensor([[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
[ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 1, 13, 23, 23, 23, 23, 23, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

看到这里是否知道其模型结构了,biaffine+crf哇,biaffine转换成临接矩阵,用于预测谓词和论元的关系,论元用crf序列标注的方式来进行预测。

模型结构

1
2
3
4
5
6
7
SpanBIOSemanticRoleLabelingModel(
(transformer): TransformerEncoder(n_out=256,dropout=0.1)
(s_layer): MLP(n_in=256, n_out=300, dropout=0.1)
(e_layer): MLP(n_in=256, n_out=300, dropout=0.1)
(biaffine): Biaffine(n_in=300, n_out=64, bias_x=True, bias_y=True)
(crf): CRF(num_tags=64)
)

步骤

1. loss计算和解码

到biaffine这一层没什么需要特别注意的,bert获取词向量的方式从以前的求平均改成了以首字代表词向量。后面接两个mlp以及biaffine。重点在于如何和crf融合到一起?

  1. biaffine输出后维度为(batch_size,seq_length,seq_length,hidden_size),crf是用在第二个seq_length那一维。
  2. crf的输入为发射概率,此维度为(batch_size,seq_length,hidden_size)。

基于上述两个前提,将batch_size和第一个seq_length进行flatten,因为第一个seq_length为谓语,不影响论元的预测,转换后输入到crf中,就可以计算loss了,解码一样。

2. 评估指标

预测出来的结果示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# pred

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 13, 23, 23, 23, 23, 23, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[12, 6, 3, 4, 4, 4, 4, 4, 4, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

pred类型为List[List[int]],他的长度等于batch_tokens中每个词的长度,即:

1
len(pred) == sum([len(i) for i in batch["batch_tokens"]])

** 其中每一行表示的是当前词和整句每个词所呈现出来的关系。 **

基于上面结论,就不难写评估代码了,将其转成(token_index, start, end, label),然后set取交集,最终计算f1值,可看这里。

3. 解码预测

基本如上,具体可看。

性能

ltp v4

从这里也可以看出,语义角色标注任务任重道远。

ltp关系类型

ltp关系类型1
ltp关系类型2

关系类型

Tag

Description

Example

ARG0

causers or experiencers

施事者、主体、触发者

[政府 ARG0]鼓励个人投资服务业。

ARG1

patient

受事者

政府鼓励[个人 ARG1]投资服务业。

ARG2

range

语义角色2

政府鼓励个人[投资服务业 ARG2]。

ARG3

starting point

语义角色3

巴基斯坦[对谈判前景 ARG3]表示悲观。

ARG4

end point

语义角色4

产检部门将产检时间缩短到[一至三天 ARG4]。

ADV

adverbial

状语

我们[即将 ADV]迎来新年。

BNF

beneficiary

受益人

义务[为学童及老师 BNF]做超音波检查 。

CND

condition

条件

[如果早期发现 CND],便能提醒当事人注意血压的变化。

CRD

coordinated arguments

并列

跟南韩、[跟美国 CRD]谋求和平关系的举动也更加积极。

DGR

degree

程度

贫铀弹含有放射性比铀强[20万倍 DGR]。

DIR

direction

方向

[从此处 DIR] 我们可以发现寇克斯报告的精髓。

DIS

discourse marker

会话标记

警方上午针对目击者做笔录,[而 DIS]李士东仍然不见踪影。

EXT

extent

  • 算法

展开全文 >>

基于树形条件随机场的高阶句法分析

2021-11-02

此篇文章貌似没有重点,日常笔记吧。

基于树形条件随机场的高阶句法分析作者硕士毕业论文,关于句法分析的历史与实现基本讲了一遍,包括作者使用TreeCRF高阶建模等工作。
代码,这个项目包含了句法分析任务的实现。包括dependency parser,semantic dependency parser,constituency parser等。

对于句法分析工作,百度ddparser相比下来可能是工业上更好的选择,不过目前个人更倾向于语义句法工作,相比下来更接近直观感受(还是看任务啦~)。

不管是semantic role labeling(语义角色标注)或者semantic dependency parser(语义依存分析),看ltp的演示效果。

但是不能光看这种效果,从目前公开的论文水平来看,准确率并没有很高,另外高质量,高数量的标注数据集也相对少。

大家都是一样的模型,比的就是数据集喽,这点不得不夸HanLP,至少人家代码里面都有数据集,方便学习。

手动狗头

  • 算法

展开全文 >>

属性抽取调研-工业界

2021-10-30

属性抽取调研——工业界

目录

  • 1. 任务

    • 1.1. 背景
    • 1.2. 任务定义
    • 1.3. 数据集
    • 1.4. 评测标准
  • 2. 方法总结

    • 2.1. 基于无监督的属性抽取方法
      • 2.1.1. 基于规则的槽填充算法
      • 2.1.2.基于聚类的属性抽取方法
    • 2.2. 基于依存关系的半监督的槽填充方法
    • 2.3. 基于深度学习的序列标注方法
    • 2.4.基于元模式的属性抽取方法
  • 3. Paper List

    • 3.1. 论文列表
  • 4.相关链接

  • 5.参考资源

1. 任务

1.1. 背景

信息抽取是从非结构化、半结构化文本中将有价值的信息转化为结构化数据的过程,在抽取的过程中,根据抽取的内容不同又分为关系抽取、事件抽取、属性抽取等。

1.2. 任务定义

属性抽取(Attribute Extraction):属性抽取的目标是从不同信息源中采集特定实体的属性信息。比如人物实体的生日、性别、国籍等,都是它的属性信息,通过属性抽取,通过多个数据源的获取,我们就可以通过丰富的属性信息来较为完整地刻画一个实体。

1.3. 数据集

  • 目前属性抽取还没有统一的评测数据集,一般是根据不同的应用场景,对不同的数据进行抽取。

1.4. 评测标准

  • Accuracy
  • Precision
  • f1

2. 方法总结

可以划分为四类:基于无监督的抽取方法,基于依存关系的半监督的槽填充算法,基于深度学习的序列标注方法、基于元模式的属性抽取方法。

2.1. 基于无监督的属性抽取方法

2.1.1. 基于规则的槽填充算法

  • 场景:在纯文本中抽取人物属性

  • 论文:《中文人物属性槽填充技术的研究与实现》

  • 方法:通过人工编写规则针对人物场景进行属性抽取,由于人工构造规则模板比较麻烦,可以使用Bootstrapping方法生成规则。

    生成规则的步骤如下:

    1、人工置顶规则种子作为初始规则种子集Spatter,属性值集合Sattr

    2、使用规则种子集Spatter,遍历并匹配文本中的属性值,获取候选属性集合h

    3、计算候选属性值集合h中每个属性值的可行度,将可信度较高的三个属性值加入到种子属性值集合Sattr中,若收敛,则算法结束,否则,执行4

    4、使用属性值集合Sattr,遍历文本,由匹配到的属性值的上下文两个词,生成候选模板集合h’

    5、计算候选模板集合h’中每个候选模板的可信度,将可信度较高的3个候选模板加入到规则种子集合Spatter中,若Spatter收敛,则算法结束,否则执行步骤2

    重复2-5到满足一定的次数。

  • 效果:通过自动生成规则进行抽取的效果不好,准确率较低。

    2.1.2. 基于聚类的属性抽取方法

  • 场景:产品的属性抽取

  • 论文:《An Unsupervised Approach to Product Attribute Extraction》

  • 方法:

    1、数据预处理:

    找出限定性的短语和名词短语,论文认为一般属性出现在这种词语中

    2、对上一步筛选出的名词进行聚类,删除词语稍少的类

    3、从类中抽取属性:计算unigrams, bigrams and trigrams,使用作者定义的属性分数函数进行计算,得分高的则为属性。

2.2. 基于依存关系的半监督的槽填充算法

  • 场景:在纯文本中抽取人物属性

  • 论文:《中文人物属性槽填充技术的研究与实现》

  • 方法:

    依存关系:在自然语言处理中,用词与词之间的依存关系来描述语言结构的框架称为依存语法(dependence grammar),又称从属关系语法。利用依存句法进行句法分析也是自然语言理解的重要技术之一。(来自维基百科)。

    使用这种方法对人物进行属性抽取的步骤如下:

    1、为每个属性生成对应的触发词表

    2、根据属性槽特点,识别出句子中所有可能候选属性,比如出生地的NER标注为LOC,感觉是自己设置一些规则匹配一些属性出来

    3、通过句子的依存结构,确认侯选属性与主体实体(这里是人物)的关系。将依存关系树看作一个无向图,顶点对应pagerank算法中的网页,利用pagerank算法,计算两个词在句法上的相关性。

    4、计算<动词,人名,属性词>三元组的得分,取前top4,看动词是否出现在触发词中。

  • 效果:在有触发词的句子中效果较好,在描述句式灵活且对触发词依赖小的句子中,提取性能不好。

2.3. 基于深度学习的序列标注方法

序列标注属于一种较为常用的属性抽取方法,就是将属性值看作较长的实体值,对数据进行标注,使用序列标注模型进行训练和抽取。

  • 场景:这种方法被应用于多个场景中,比如人物属性的抽取,抽取在线评论文本的属性、从无上下文信息的标题中抽取产品属性等,只要有相应的标注数据,就可以使用这种方法进行抽取。
  • 论文:《基于弱监督的属性关系抽取方法》《面向非结构化文本的开放式实体属性抽取》《实体 —属性抽取的GRU+CRF方法》《Personal Attributes Extraction in Chinese Text Based on Distant-Supervision and LSTM》《Bootstrapped Named Entity Recognition for Product Attribute Extraction》等论文中都使用了这种方法进行抽取
  • 方法:将属性抽取看作序列标注问题,标注需要花费一定的人工成本,在有些场景下,比如人物属性的抽取,可以使用百度百科等百科词条的结构化信息框进行标注,可以降低一定的人工标注成本;同时,标注时也可以使用Bootstrap方法由种子发现更多潜在属性值,这种方法在《Bootstrapped Named Entity Recognition for Product Attribute Extraction》论文中提到,是一种类似于Pakhomov 2002提出的首字母扩写算法的算法。该算法学习如何将首字母缩写与其正确扩展相关联的上下文,作者认为,分类器在经过标记的已知品牌训练集上进行训练,可以学习可以区分当前含义的上下文模式。序列标注常使用的模型:CRF模型、神经网络模型如BI-GRU+CRF模型等。
  • 效果:使用这种方法进行属性抽取的效果较为理想,但也具有一定的局限性,由于属性值的内容和形式多种多样,对于字数较长的描述性属性,这种方法不能取得理想的效果;同时,对于某些不能使用百科词条数据进行回标的情况,将花费大量的人工成本进行标注,降低了可操作性。

2.4. 基于元模式的属性抽取方法

  • 场景:这种方法可以被应用于多个场景中,不具有局限性
  • 论文:《MetaPAD-Meta Pattern Discovery from Massive Text Corpora》
  • 方法:这种方法可以在海量语料库中发现元模式,在属性抽取的场景中,可以使用这种方法发现高质量的属性描述语句,作为属性值。

3. Paper List

3.1. 论文列表

会议/年份 论文 链接
ACM SIGKDD International Conference 2017 MetaPAD-Meta Pattern Discovery from Massive Text Corpora https://arxiv.org/pdf/1703.04213.pdf

近几年的属性抽取论文待补充

4. 相关链接

Bootstrapped Named Entity Recognition for Product Attribute Extraction

基于弱监督的属性关系抽取方法

中文人物属性槽填充技术的研究与实现

面向非结构化文本的开放式实体属性抽取

实体—属性抽取的GRU+CRF方法

5. 参考资源

医疗健康文本的关系抽取和属性抽取

属性和实体抽取(传统方法)

  • 算法

展开全文 >>

关系抽取-学术界

2021-10-30

关系抽取调研——学术界

目录

  • 1. 任务

    • 1.1. 任务定义
    • 1.2. 数据集
    • 1.3. 评测标准
    • 1.4. SOTA
  • 2. 方法总结

    • 2.1. 基于模式挖掘的方法

      • 2.1.1. 基于模板匹配的方法
      • 2.1.2. 基于依存句法的方法
    • 2.2. 监督学习

      • 2.2.1. 机器学习
        • 2.2.1.1. 基于特征向量的方法
        • 2.2.1.2. 基于核函数的方法
      • 2.2.2. 深度学习
        • 2.2.2.1. Pipeline(管道式)
        • 2.2.2.2. Joint(联合抽取式)
        • 2.2.2.3. 远监督学习
    • 2.3. 半监督/无监督方法

      • 2.3.1. Bootstrapping
      • 2.3.2. 联合训练
      • 2.3.3. 标签传播
      • 2.3.4. 关系实例聚类和关系类型词选择
  • 4. Paper List

    • 4.1. 论文列表

      • 4.1.1. 监督类方法
      • 4.1.2. 远监督方法
    • 4.2. 论文解读

  • 5.相关文献

1. 任务

1.1. 任务定义

自动识别句子中实体之间具有的某种语义关系。根据参与实体的多少可以分为二元关系抽取(两个实体)和多元关系抽取(三个及以上实体)。

通过关注两个实体间的语义关系,可以得到(subject, relation, object)三元组,其中subject和object表示两个实体,relation表示实体间的语义关系。

根据处理数据源的不同,关系抽取可以分为以下三种:

  • 面向结构化文本的关系抽取:包括表格文档、XML文档、数据库数据等
  • 面向非结构化文本的关系抽取:纯文本
  • 面向半结构化文本的关系抽取:介于结构化和非结构化之间

根据抽取文本的范围不同,关系抽取可以分为以下两种:

  • 句子级关系抽取:从一个句子中判别两个实体间是何种语义关系
  • 语料(篇章)级关系抽取:不限定两个目标实体所出现的上下文

根据所抽取领域的划分,关系抽取又可以分为以下两种:

  • 限定域关系抽取:在一个或者多个限定的领域内对实体间的语义关系进行抽取,限定关系的类别,可看成是一个文本分类任务
  • 开放域关系抽取:不限定关系的类别

限定域关系抽取方法:

  • 基于模板的关系抽取方法:通过人工编辑或者学习得到的模板对文本中的实体关系进行抽取和判别,受限于模板的质量和覆盖度,可扩张性不强
  • 基于机器学习的关系抽取方法:将关系抽取看成是一个分类问题

1.2. 数据集

  • ACE 2005

    数据集简介:ACE2005语料库是语言数据联盟(LDC)发布的由实体,关系和事件注释组成的各种类型的数据,包括英语,阿拉伯语和中文培训数据,目标是开发自动内容提取技术,支持以文本形式自动处理人类语言。ACE语料解决了五个子任务的识别:entities、values、temporal expressions、relations and events。这些任务要求系统处理文档中的语言数据,然后为每个文档输出有关其中提到或讨论的实体,值,时间表达式,关系和事件的信息。

    获取方式:数据集收费,需在LDC联盟的官网上注册再购买,LDC账号注册地址 ACE 2005 下载地址

  • TACRED

    数据集简介:TACRED(TAC Relation Extraction Dataset)是一个拥有106264条实例的大规模关系抽取数据集,这些数据来自于每年的TAC KBP(TAC Knowledge Base Population)比赛使用的语料库中的新闻专线和网络文本。包含了41关系类型,此外若句子无定义关系,被标注成no_relation类型。数据集的详细介绍可以访问TACRED文档

    获取方式:数据集收费,需在LDC联盟官网注册会员再购买 LDC账号注册地址 TACRED 下载地址

  • SemEval2010_task8

    image-20201005102419115

    数据集简介:对于给定了的句子和两个做了标注的名词,从给定的关系清单中选出最合适的关系。数据集一共9种关系类别数,此外包含一类Other关系,含有6674实例数量。

    获取方式: 原始数据

  • FewRel

    数据集简介:FewRel是目前最大规模的精标注关系抽取数据集,由孙茂松教授领导的清华大学自然语言处理实验室发布。一共100种关系类别数,含有70000实例数量。

    获取方式:FewRel 网站地址 论文地址

  • NYT10

    NYT-10数据集文本来源于纽约时报,命名实体是通过 Stanford NER 工具并结合 Freebase 知识库进行标注的。实体对之间的关系是链接Freebase知识库中的关系,结合远监督方法所得到。该数据集共含有53种关系类型,包括特殊关系类型NA,即头尾实体无关系。

    获取方式:原始数据

获取更多关系抽取数据集,可访问此处Annotated-Semantic-Relationships-Datasets

1.3. 评测标准

二分类:

Accuracy = (预测正确的样本数)/(总样本数)=(TP+TN)/(TP+TN+FP+FN)

Precision = (预测为正例且正确预测的样本数)/(所有预测为正例的样本数) = TP/(TP+FP)

Recall = (预测为正例且正确预测的样本数)/(所有真实情况为正例的样本数) = TP/(TP+FN)

F1 = 2 * (Precision * Recall) / (Precision + Recall )

多分类:

Macro Average

多类别(N类) F1/P/R的计算,即计算N个类别的F1/P/R,每次计算以当前类别为正例,其他所有类别为负例,最终将各类别结果求和并除以类别数取平均。

Micro Average

统计当前类别的TP、TN、FP、FN数量,再将该四类样本数各自求和作为新的TP、TN、FP、FN,计算F1/P/R公式同二分类。

P@N(最高置信度预测精度):

通常在远监督关系抽取中使用到,由于知识库所含关系实例的不完善,会出现高置信度包含关系实例的实体对被叛为负例,从而低估了系统正确率。此时可以采用人工评价,将预测结果中知识库已包含的三元组移除,然后人工判断抽取关系实例是否正确,按照top N的准确率对抽取效果进行评价。

1.4. SOTA

Relation Extraction on TACRED:

模型 average F1 论文题目 年份 论文链接 code
BERTEM+MTB 71.5 Matching the Blanks: Distributional Similarity for Relation Learning 2019 https://arxiv.org/pdf/1906.03158v1.pdf https://github.com/plkmo/BERT-Relation-Extraction
KnowBert-W+W 71.5 Knowledge Enhanced Contextual Word Representations 2019 https://arxiv.org/pdf/1909.04164v2.pdf
DG-SpanBERT 71.5 Efficient long-distance relation extraction with DG-SpanBERT 2020 https://arxiv.org/pdf/2004.03636v1.pdf
SpanBERT 70.8 SpanBERT: Improving Pre-training by Representing and Predicting Spans 2019 https://arxiv.org/pdf/1907.10529v3.pdf https://github.com/facebookresearch/SpanBERT
R-BERT 69.4 Enriching Pre-trained Language Model with Entity Information for Relation Classification 2020 https://arxiv.org/pdf/1905.08284v1.pdf https://github.com/wang-h/bert-relation-classification
C-GCN + PA-LSTM 68.2 Graph Convolution over Pruned Dependency Trees Improves Relation Extraction 2018 https://arxiv.org/pdf/1809.10185v1.pdf https://github.com/qipeng/gcn-over-pruned-trees

Relation Extraction on SemEval-2010 Task 8:

模型 average F1 论文题目 年份 论文链接 code
Skeleton-Aware BERT 90.36 Enhancing Relation Extraction Using Syntactic Indicators and Sentential Contexts 2019 https://arxiv.org/pdf/1912.01858v1.pdf https://github.com/wang-h/bert-relation-classification
EPGNN 90.2 Improving Relation Classification by Entity Pair Graph 2019 http://proceedings.mlr.press/v101/zhao19a/zhao19a.pdf
BERTEM+MTB 89.5 Matching the Blanks: Distributional Similarity for Relation Learning 2019 https://arxiv.org/pdf/1906.03158v1.pdf https://github.com/plkmo/BERT-Relation-Extraction
R-BERT 89.25 Enriching Pre-trained Language Model with Entity Information for Relation Classification 2020 https://arxiv.org/pdf/1905.08284v1.pdf https://github.com/wang-h/bert-relation-classification
KnowBert-W+W 89.1 Knowledge Enhanced Contextual Word Representations 2019 https://arxiv.org/pdf/1909.04164v2.pdf
Entity-Aware BERT 89 Extracting Multiple-Relations in One-Pass with Pre-Trained Transformers 2019 https://arxiv.org/pdf/1902.01030v2.pdf https://github.com/helloeve/mre-in-one-pass

Relation Extraction on ACE 2005:

模型 RELATION F1 ENTITY F1 SENTENCE ENCODER 论文题目 年份 论文链接 code
MRC4ERE++ 62.1 85.5 BERT base Asking Effective and Diverse Questions: A Machine Reading Comprehension based Framework for Joint Entity-Relation Extraction 2020 https://www.ijcai.org/Proceedings/2020/0546.pdf https://github.com/TanyaZhao/MRC4ERE
Multi-turn QA 60.2 84.8 BERT base Entity-Relation Extraction as Multi-Turn Question Answering 2019 https://arxiv.org/pdf/1905.05529v4.pdf
MRT 59.6 83.6 biLSTM Extracting Entities and Relations with Joint Minimum Risk Training 2018 https://www.aclweb.org/anthology/D18-1249
GCN 59.1 84.2 biLSTM Joint Type Inference on Entities and Relations via Graph Convolutional Networks 2019 https://www.aclweb.org/anthology/P19-1131
Global 57.5 83.6 biLSTM End-to-End Neural Relation Extraction with Global Optimization 2017 https://www.aclweb.org/anthology/D17-1182
SPTree 55.6 83.4 biLSTM End-to-End Relation Extraction using LSTMs on Sequences and Tree Structures 2016 https://arxiv.org/pdf/1601.00770v3.pdf https://github.com/tticoin/LSTM-ER

Relation Extraction on ACE 2004:

模型 RELATION F1 ENTITY F1 论文题目 年份 论文链接 code
DYGIE 59.7 87.4 A General Framework for Information Extraction using Dynamic Span Graphs 2019 https://arxiv.org/pdf/1904.03296v1.pdf https://github.com/luanyi/DyGIE
Multi-turn QA 49.4 83.6 Entity-Relation Extraction as Multi-Turn Question Answering 2019 https://arxiv.org/pdf/1905.05529v4.pdf
SPTree 48.4 81.8 End-to-End Relation Extraction using LSTMs on Sequences and Tree Structures 2016 https://arxiv.org/pdf/1601.00770v3.pdf https://github.com/tticoin/LSTM-ER
multi-head + AT 47.45 81.64 Adversarial training for multi-context joint entity and relation extraction 2018 https://arxiv.org/pdf/1808.06876v3.pdf https://github.com/bekou/multihead_joint_entity_relation_extraction
multi-head 47.14 81.16 Joint entity recognition and relation extraction as a multi-head selection problem 2018 https://arxiv.org/pdf/1804.07847v3.pdf https://github.com/bekou/multihead_joint_entity_relation_extraction
Attention 45.7 79.6 Going out on a limb: Joint Extraction of Entity Mentions and Relations without Dependency Trees 2017 https://www.aclweb.org/anthology/P17-1085

Relation Extraction on NYT:

模型 average F1 论文题目 年份 论文链接 code
REDN 89.8 Downstream Model Design of Pre-trained Language Model for Relation Extraction Task 2020 https://arxiv.org/pdf/2004.03786v1.pdf https://github.com/slczgwh/REDN
CASREL 89.6 A Novel Cascade Binary Tagging Framework 2019 https://arxiv.org/pdf/1909.03227v4.pdf https://github.com/weizhepei/CasRel
HBT 89.5 A Novel Cascade Binary Tagging Framework for Relational Triple Extraction 2019 https://arxiv.org/pdf/1909.03227v4.pdf https://github.com/weizhepei/CasRel
WDec 84.4 Effective Modeling of Encoder-Decoder Architecture for Joint Entity and Relation Extraction 2019 https://arxiv.org/pdf/1911.09886v1.pdf https://github.com/nusnlp/PtrNetDecoding4JERE
ETL-Span 78.0 Joint Extraction of Entities and Relations Based on a Novel Decomposition Strategy 2019 https://arxiv.org/pdf/1909.04273v3.pdf https://github.com/yubowen-ph/JointER
CopyRE’ OneDecoder 72.2 CopyMTL: Copy Mechanism for Joint Extraction of Entities and Relations with Multi-Task Learning 2019 https://arxiv.org/pdf/1911.10438v1.pdf https://github.com/WindChimeRan/CopyMTL

Relation Extraction on CoNLL04:

模型 RELATION F1 ENTITY F1 论文题目 年份 论文链接 code
SpERT 71.47 88.94 Span-based Joint Entity and Relation Extraction with Transformer Pre-training 2019 https://arxiv.org/pdf/1909.07755v3.pdf https://github.com/markus-eberts/spert
Multi-turn QA 68.9 87.8 Entity-Relation Extraction as Multi-Turn Question Answering 2019 https://arxiv.org/pdf/1905.05529v4.pdf
Global 67.8 85.6 End-to-End Neural Relation Extraction with Global Optimization 2017 https://www.aclweb.org/anthology/D17-1182
Biaffine attention 64.40 86.20 End-to-end neural relation extraction using deep biaffine attention 2018 https://arxiv.org/pdf/1812.11275v1.pdf https://github.com/datquocnguyen/jointRE
Relation-Metric with AT 62.29 84.15 Neural Metric Learning for Fast End-to-End Relation Extraction 2019 https://arxiv.org/pdf/1905.07458v4.pdf
multi-head 62.04 83.9 Joint entity recognition and relation extraction as a multi-head selection problem 2018 https://arxiv.org/pdf/1804.07847v3.pdf https://github.com/bekou/multihead_joint_entity_relation_extraction

Relation Extraction on FewRel:

模型 average F1 论文题目 年份 论文链接 code
ERNIE 88.32 ERNIE: Enhanced Language Representation with Informative Entities 2019 https://arxiv.org/pdf/1905.07129v3.pdf https://github.com/thunlp/ERNIE

2. 方法总结

2.1. 基于模式挖掘的方法

2.1.1. 基于模板匹配的方法

模板匹配:在关系分类中应用广泛。对于给定实体对的一段文本,基于现有模板库进行上下文匹配。若结果满足模板对应关系类别,则将该关系类别作为实体对之间的关系。

常见的模板匹配方法主要包括:

  • 人工模板:常见于判断实体间存在的上下位关系。基本出发点是统计和总结关系模式,通过专家定义寻找关系在上下文中表达的字符,语法及语义特征,将此作为模式与文本进行匹配,进行关系实例的获取。
  • 统计生成:无须人工构建,主要基于搜索引擎进行统计模板抽取。具体地,将已知实体对作为查询语句,抓取搜索引擎返回的前n个结果文档并保留包含该实体对的句子集合,寻找包含实体对的最长字串作为统计模板,保留置信度较高的模板用于关系分类。

(Marti A. Hearst 1992) [1]在该文中提出一种从不受限制的文本中自动获得下位词法关系的方法,用于提取分类关系is-a的实例:

示例:

句子中上下位关系,比如hyponym(China; Asia countries)。从下面两个句子中都可以抽取出这种关系:

  • Asia countries, especially China, Japan, and India…
  • Asia countries, such as China, Japan, and India…

两个实体之间的especially和such as可以看做这种关系的特征。通过寻找更多表达这种关系的句子,构造规则模板,即可用于抽取构成上下位关系的实体,从而发现新的三元组。

总结:

优点:

  • 该方法准确率较高。
  • 从某种意义上说,这是一种假设的工作,Hearst文中没有给出实验结果,但它对追随者影响很大,是之后Bootstraping方法的开篇之作。

缺点:

  • 召回率较低,且关系类别有限,仅仅包含is-a的关系。
  • 适用性有限,难以移植

2.1.2. 基于依存句法

基于NLP工具(常见的有Stanford CoreNLP、spaCy、LTP、HanLP等)获取句子相关特征,对处理结果一般进行如下处理:

  1. 输入文本完成分词、词性标注、命名实体识别、依存分析等处理步骤。
  2. 基于语法规则抽取出相关语法信息,如 “主谓宾”、“定状补”等,从而得到句子中各成分之间的联系和关系。
  3. 利用各成分之间相互关联关系总结出诸如定中关系,定语后置关系等抽取规则。
  4. 设定规则模板,并根据规则对抽取结果进行严格测试与调优。

示例

下面介绍一组基于LTP(语言技术平台)工具进行规则抽取三元组的例子:

  • 输入文本:杨燕萍,女,中国共产党党员,系江西省第十一届政协主席许爱民的妻子。

  • 经LTP得出依存句法分析结果:

​ 依存句法分析结果示例

​ 依存句法关系类型说明

由图示可知,可以以谓语动词为出发点构建规则,对节点上词性以及边上的关系进行设定。当前句子核心谓词是“系”,从前向后遍历句子解析结果可以从“主席”开始分析,由于“主席”与左右两侧词汇均构成定中关系且两侧词汇均被识别为命名实体。由此,可以提取出一项(政协,主席,许爱民)定中关系三元组。

总结

手写规则的 优点 :

  • 人工设定规则,准确率高(high-precision)
  • 结合专家知识,进行特定领域定制
  • 构建简单,适合小规模关系类别数据

缺点:

  • 规则总结无法穷尽,导致低召回率(low-recall)
  • 所有关系类别须定义相关规则pattern,耗时耗力
  • 难以维护及跨领域移植

2.2. 监督学习

2.2.1. 机器学习

2.2.1.1. 基于特征向量的方法

基于特征向量的方法是一种简单且行之有效 的关系抽取运用。其主要思想为:给定关系句子实例,从上下文中提取出具有类间区分度的特征(如词法信息,语法信息等),构造形成多维度加权特征向量,选取合适的分类器进行关系抽取模型训练。

基于特征向量的方法需要解决的三个基本问题:特征项选取,特征权重计算和分类器选择。

  • 特征项。作为向量模型的骨架,它需要包含足够的语义信息来表征自然文本,又需要在语义关系间具有良好的区分度。常见的特征项有:词法、实体、句法、语义及上下文结构化信息等。

  • 特征权重计算。众多候选特征项,对最终关系分类的贡献度不可能完全一样,比如实体间语义关系往往比实体词汇、句子长度等特征更加重要。因此,需要进行特征重要性权重计算。这里提供两种权重方法计算思路:一、公式计算权值并排序,如布尔权重、特征频度[5]。二、基于优化算法进行最优权向量搜索[6]

  • 分类器选取。特征向量构造完毕后,下一步便是选取合适的分类器。下面介绍两种具有代表性的分类器:

    • 最大熵模型(Maximum Entropy Model)

      Kambhatla 2004[2]基于文本中实体词,实体类型,实体引用类型、语法以及句法树在内的多种特征,采用最大熵分类器,对不同特征叠加后进行了实验对比,并在ACE RDC2003语料的子类关系中获得了52.8的F1值,表明多层面语言学特征能有效提升关系分类模型的效果。

    • 支持向量机(SVM)

      Zhou et al.,2005[3]在Kambhatla前期基础上,融入基本的词组块信息特征组合,基于SVM获得了55.5的F1性能,并得出实体类别特征对于关系抽取结果提升最大的结论。Zhao et al.,2005[4]引用了文字特征,语句解析和深层语法依存特征等组合。Jiang et al.,2007[5]选取文本词序列、句法、依存关系等特征组合,以不同类别特征对抽取结果贡献度进行了评估,他们总结出在这些类别特征中选取最基本的单位特征便可以有效的提升关系抽取的性能,而过于复杂的特征带来的性能提升效果则一般。

小结:

基于特征向量的方法是关系抽取中最常见的方法,特征工程是该方法核心。研究者启发式地以多层次语言特征为切入点,并构造特征向量,结合分类器训练,可以取得不错的效果。但该方法现如今难以寻找有效新特征,性能提升较为有限。

2.2.1.2. 基于核函数的方法

针对特征提取具有的局限性,便有研究者另辟蹊径,使用核函数的方法进行关系抽取。基于核函数的方法无需人为构造显性特征,而是以输入文本实例的字符串或者是句法分析树结构作为输入,通过计算任意两个输入对象间的核相似度函数来训练分类模型。基于核函数的方法通过核函数映射综合了更多方面的知识信息,使实体间关系表示更加灵活。核函数类型众多,有包含诸如多项式核函数,向量空间核函数,P-光谱核函数,全序列核函数等。基于核函数的方法灵活性较高,对于多个不同个体核函数可以进行复合,从而得到针对具体任务的核函数。

方法原理:在初始特征空间下,核函数将该空间里的数据点映射到一个新的特征空间下,在该空间中训练线性分类器。其本质是将句子潜在的隐式特征向量投影到新的特征空间,并通过计算投影的内积来表示输入空间特征向量的相似性,最终达到判定实体间关系类别相似性的效果。

基于核函数的方法抽取关系一般步骤:

  1. 针对句子中隐含的特征信息,选用合适的解析结构,如语法树等进行语句剖析;
  2. 在此基础上选择合适的基础核函数,计算解析结构中成分之间的相似性;
  3. 在基础核函数之上,将多个核函数复合,以充分利用各种隐式特征,提高分类精度。
  • 浅层树核(Zelenko,2003)[6]

  • 依存树核(Culotta et al., 2004)[7]

  • 最短依存树核(Bunescu et al., 2005)[8]

  • 卷积树核(Zhang et al., 2006[9];Zhou et al., 2007[10])

  • 其他的还有诸如

    • constituent parse trees [Collins & Duffy, 2001]

    • string sequencies [Cancedda & al., 2003]

    • directed acyclic graphs [Suzuki & al., 2003]

    • dependency parse trees [Moschitti, 2006]

    • feature-enriched/semantic tree kernel [Plank & Moschitti,2013; Sun & Han, 2014]

小结:

基于核函数的方法可以规避构造基于向量方法中显式特征集合,且更能够充分利用句子的长距离特征。然而核方法将多个不同核函数符合后,虽然可以表达高纬度或无穷维度特征空间,但也导致该方法学习和训练速度 过程较为缓慢,对于大规模数据抽取场景耗费时空代价巨大。

二者比较

方法 特征项 特征表示方法 核心步骤
基于特征向量的方法 词、词性、上下文结构信息、依存分析、句法树等 显式 特征工程
基于核函数的方法 依存树核、卷积树核等 隐式高维 设计核函数计算

2.2.2. 深度学习

2.2.2.1. Pipeline(管道式)

Pipeline方法先在句子中抽取实体、而后再抽取关系。即实体识别,关系分类被视为两个独立的部分,互不干涉,但关系的识别依赖于实体识别的效果。

2.2.2.2. Joint(联合抽取式)

现有联合抽取模型总体上有两大类:

1、共享参数联合抽取模型

通过共享参数(共享输入特征或者内部隐层状态)实现联合,此种方法对子模型没有限制,但是由于使用独立的解码算法,导致实体模型和关系模型之间交互不强。

Miwa[11]等人针对上游任务实体识别抽取出的实体对,对当前句子所对应的依存句法树上提取出能覆盖实体对的最小依存树,并基于TreeLSTM生成该子树相对应的表示向量。最终,基于子树根节点对应的TreeLSTM向量完成SoftMax关系分类。

Katiyar[12] 等人采取指针网络解码,指针网络实际上有R层(R为关系总数)。对当前实体查询在其位置前的所有实体(向前查询),并计算注意力得分。

2、联合解码抽取模型

为了增强实体模型和关系模型之间的交互性,由此提出了复杂的联合解码方案,但需要对子模型特征的丰富性以及联合解码的精确性之间做权衡:一方面如果设计精确的联合解码算法,往往需要对模型特征进行限制,例如用条件随机场建模,使用维特比解码算法可以得到全局最优解,但是往往需要限制特征的阶数。

另一方面如果使用近似解码算法,比如集束搜索,在特征方面可以抽取任意阶的特征,但是解码得到的结果是不精确的。因此,需要让算法可以在不影响子模型特征丰富性的条件下加强子模型之间的交互。

Zheng[13]等人对实体和关系标注框架进行了统一,直接以关系标签进行实体的BIOES标注,但该方案未考虑关系重叠问题,比如一个实体存在多种关系的情况。 Dai[14]等人针对一句话含有多种关系的场景,在含有n个token的句子中,准备n个不同标注框架。对于每个位置的token都进行一次可能的实体或关系类型标注,由此一个句子进行了n次重复编码,复杂度高。

2.2.2.3. 远监督学习

Distant Supervision提出主要基于假设:两个实体如果在知识库中存在某种关系,则包含该两个实体的非结构化句子均能表示出这种关系。常用的做法是通过将知识库与各非结构化文本对齐来自动构建大量训练数据,减少模型对人工标注数据的依赖,增强模型跨领域适应能力。但该假设过于肯定,导致引入大量噪声数据,且构造过程依赖于NER等工具,中间过程可能造成错误传播问题。

针对这些问题,目前主要有四类方法:

(1)将先验知识作为限制引入构造数据集的过程中。

(2)利用概率图模型对数据样例打分,将置信度较低的句子过滤。

(3)利用多示例学习进行包级别关系标注并融入句子级别的注意力机制对包内样例赋予权值。

(4)基于强化学习。

(5)基于预训练机制。

Zeng[15]等人针对数据标注错误和传统统计模型特征抽取出现的错误提出解决方案。在数据标注错误问题上,作者采用多示例学习的方式从训练集中提取置信度高的训练样例训练模型。在模型改进方面,作者提出 piece-wise 的卷积神经网络(PCNN)。先通过 word2vec 的 Skip-gram 模型将词表示成向量形式,与位置特征向量(句子中词语与两个实体的相对位置)进行拼接作为输入,而后通过卷积层得到 feature map。在池化层中基于两个实体位置将 feature map 分为三段进行池化,其目的是为了更好的捕获两个实体间的结构化信息。最后,通过 softmax 层进行分类。

Lin[16]等人在Zeng[15]的基础上,认为多示例学习虽然缓解了噪声数据过多的问题,但每次只采用包中置信度最高的样例作为该关系正例有可能损失其他句子重要信息。在模型上,作者提出基于 attention 机制的卷积神经网络模型,由原先选取置信度最高的样例改为对包中所有样例赋予句子级别权重,最终各个样例向量进行加权求和通过分类器得到关系分类结果。

Zhang[17] 基于Lin[8]的工作,对句子级别的注意力机制设计进行了改进,利用卷积神经网络捕获实体描述特征,用于提供更多的背景知识,最后通过计算实体间关系与句子间的相似度赋予句子不同的权重。

Feng[18]基于强化学习的CNN+RL模型主要构成包括样例选择器和关系分类器。其中样例选择器负责从样例中获取高质量的句子,采取强化学习方式在考虑当前句子的选择状态下选择样例;接着经过关系分类器向样例选择器反馈来改进选择策略。该方法相较之前句子级别和Bag级别的关系分类模型取得更好效果。

Soares[19]首次在预训练过程中引入关系分类目标,使用「BLANK」标识符来替换实体mention。该方法将样本中含有相同实体对的句子对视为正样本,反之为负样本。相较于传统的远程监督,该方法在训练中未引入关系标签,而是采用二元分类器对句子对之间进行相似度计算。结果显示在FewRel数据集上,在未进行tuning就已经超过了有监督的关系抽取结果。

4. Paper List

4.1. 论文列表

4.1.1. 监督类方法

4.1.1.1. 利用语法信息的方法
论文题目 抽取任务 关键词 论文链接 会议及年份 code
Attention Guided Graph Convolutional Networks for Relation Extraction 关系提取 注意力导向图卷积网络(AGGCN);语义依赖树;软修剪;自动学习子结构; https://www.aclweb.org/anthology/P19-1024.pdf ACL2019
A Richer-but-Smarter Shortest Dependency Path with Attentive Augmentation for Relation Extraction 关系提取 最短依赖路径SDP;注意力模型;深度神经模型;LSTM网络;CNN https://www.aclweb.org/anthology/N19-1298 NAACL 2019 https://github.com/catcd/RbSP
4.1.1.2. 不利用语法信息的方法
论文题目 抽取任务 关键词 论文链接 会议及年份 code
Joint Type Inference on Entities and Relations via Graph Convolutional Networks 抽取三元组的joint任务 实体关系联合推断;图卷积模型(GCN);二元关系分类 https://pdfs.semanticscholar.org/7ce8/ce2768907421fb1a6cbfe13a8a36992721a7.pdf ACL2019
GraphRel: Modeling Text as Relational Graphs for Joint Entity and Relation Extraction 抽取三元组的joint任务 端到端关系抽取;图卷积网络; https://tsujuifu.github.io/pubs/acl19_graph-rel.pdf ACL2019
Exploiting Entity BIO Tag Embeddings and Multi-task Learning for Relation Extraction with Imbalanced Data 关系抽取 BIO字符/词嵌入;多任务体系结构;关系分类 https://arxiv.org/pdf/1906.08931.pdf ACL2019
Entity-Relation Extraction as Multi-turn Question Answering 关系抽取 多回合QA;上下文识别答案范围任务 https://arxiv.org/pdf/1905.05529.pdf ACL2019
Graph Neural Networks with Generated Parameters for Relation 关系抽取 图神经网络(GNN);多跳关系推理 https://arxiv.org/pdf/1902.00756.pdf ACL2019
Kernelized Hashcode Representations for Biomedical Relation Extraction 关系分类 核化的局部敏感哈希(KLSH);降低计算成本 https://arxiv.org/pdf/1711.04044.pdf ACL2019
Connecting the Dots: Document-level Neural Relation Extraction with Edge-oriented Graphs 关系抽取 图神经网络模型;文档级关系提取 https://arxiv.org/pdf/1909.00228v1.pdf EMNLP2019

4.1.2. 远监督方法

论文题目 抽取任务 关键词 论文链接 会议及年份 code
Hybrid Attention-based Prototypical Networks for Noisy Few-Shot Relation Classification 关系分类 远监督;噪声;混合注意力圆形网络 https://gaotianyu1350.github.io/assets/aaai2019_hatt_paper.pdf AAAI2019 https://github.com/thunlp/HATT-Proto
A Hierarchical Framework for Relation Extraction with Reinforcement Learning 关系提取 增强关系类型系和实体交互;分层强化学习(HRL)框架;远监督数据集 https://arxiv.org/pdf/1811.03925.pdf AAAI2019
Cross-relation Cross-bag Attention for Distantly-supervised Relation Extraction 关系提取 远监督抗噪;Cross-relation Cross-bag Selective Attention;多实例学习;句子级别;注意力机制;关注高质量实体对 https://arxiv.org/pdf/1812.10604.pdf AAAI2019
Structured Minimally Supervised Learning for Neural Relation Extraction 关系提取 最小监督;学习的表示形式;结构化学习 https://arxiv.org/pdf/1904.00118.pdf NAACL2019
Combining Distant and Direct Supervision for Neural Relation Extraction 关系提取 降噪;监督学习+远监督模型 https://arxiv.org/pdf/1810.12956.pdf NAACL2019 https://github.com/allenai/comb_dist_direct_relex/
Distant Supervision Relation Extraction with Intra-Bag and Inter-Bag Attentions 关系提取 句子级别的Attention; https://www.aclweb.org/anthology/N19-1288.pdf NAACL2019
GAN Driven Semi-distant Supervision for Relation Extraction 关系提取 半远监督;生成对抗网络(GAN) https://www.aclweb.org/anthology/N19-1307 NAACL 2019
Improving Distantly-Supervised Relation Extraction with Joint Label Embedding 关系提取 多层注意力模型;联合标签嵌入 https://www.aclweb.org/anthology/D19-1395.pdf NAACL 2019
Self-Attention Enhanced CNNs and Collaborative Curriculum Learning for Distantly Supervised Relation Extraction 关系提取 协作式学习;卷积神经网(CNN);卷积运算内部自注意机制 https://www.aclweb.org/anthology/D19-1037.pdf NAACL 2019

5. 相关文献

收录文章

  • [1] Automatic Acquisition of Hyponyms From Large Text Corpora.
  • [2] Combining Lexical, Syntactic, and Semantic Features with Maximum Entropy Models for Information Extraction.
  • [3] Extracting Relations with Integrated Information Using Kernel Methods
  • [4] Exploring Various Knowledge in Relation Extraction
  • [5] A Systematic Exploration of the Feature Space for Relation Extraction
  • [6] Kernel Methods for Relation Extraction
  • [7] Dependency Tree Kernels for Relation Extraction
  • [8] A Shortest Path Dependency Kernel for Relation Extraction
  • [9] A Composite Kernel to Extract Relations between Entities with Both Flat and Structured Features
  • [10] Tree Kernel-Based Relation Extraction with Context-Sensitive Structured Parse Tree Information
  • [11] End-to-End Relation Extraction using LSTMs on Sequences and Tree Structures. ACL 2016:1105–1116
  • [12] Katiyar, et al. Going out on a limb: Joint Extraction of Entity Mentions and Relations without Dependency Trees. ACL 2017: 917-928
  • [13] Zheng, et al. Joint extraction of entities and relations based on a novel tagging scheme. ACL 2017: 1227-1236
  • [14] Dai,et al. Joint Extraction of Entities and Overlapping Relations Using Position-Attentive Sequence Labeling. AAAI 2019: 6300-6308
  • [15] Zen, et al. Distant Supervision for Relation Extraction via Piecewise Convolutional Neural Networks. EMNLP 2015: 1753-1762
  • [16] Lin ,et al. Neural Relation Extraction with Selective Attention over Instances. ACL 2016:2124–2133
  • [17] Distant Supervision for Relation Extraction with Sentence-level Attention and Entity Descriptions
  • [18] Feng ,et al. Reinforcement Learning for Relation Classification from Noisy Data. AAAI 2018: 5779-5786
  • [19] Soared ,et al. Matching the Blanks: Distributional Similarity for Relation Learning. ACL 2019: 2895-2905
  • 算法

展开全文 >>

关系抽取调研-工业界

2021-10-30

关系抽取调研——工业界

目录

  • 1. 任务

    • 1.1. 任务定义
    • 1.2. 数据集
    • 1.3. 评测标准
  • 2. 方法总结

    • 2.1. 基于模板的方法
      • 2.1.1. 基于触发词/字符串
      • 2.1.2. 基于依存句法
    • 2.2. 监督学习
      • 2.2.1. 机器学习
      • 2.2.2. 深度学习 Pipeline vs Joint Model
    • 2.3. 半监督/无监督方法
      • 2.3.1. Bootstrapping
      • 2.3.2. 基于远程监督的方法
  • 3. 抽取工具应用

    • 3.1. TextRunner
    • 3.2. OLLIE:开放三元组知识抽取
    • 3.3. IEPY
    • 3.4. spaCy
    • 3.5. NELL
    • 3.6. Deepdive
    • 3.7. Standford
  • 4.相关文献

  • 5.参考资源

1. 任务

1.1. 任务定义

自动识别句子中实体之间具有的某种语义关系。根据参与实体的多少可以分为二元关系抽取(两个实体)和多元关系抽取(三个及以上实体)。

通过关注两个实体间的语义关系,可以得到(arg1, relation, arg2)三元组,其中arg1和arg2表示两个实体,relation表示实体间的语义关系。

根据处理数据源的不同,关系抽取可以分为以下三种:

  • 面向结构化文本的关系抽取:包括表格文档、XML文档、数据库数据等。
  • 面向非结构化文本的关系抽取:纯文本。
  • 面向半结构化文本的关系抽取:介于结构化和非结构化之间。

根据抽取文本的范围不同,关系抽取可以分为以下两种:

  • 句子级关系抽取:从一个句子中判别两个实体间是何种语义关系。
  • 语料(篇章)级关系抽取:不限定两个目标实体所出现的上下文。

根据所抽取领域的划分,关系抽取又可以分为以下两种:

  • 限定域关系抽取:在一个或者多个限定的领域内对实体间的语义关系进行抽取,限定关系的类别,可看成是一个文本分类任务。
  • 开放域关系抽取:不限定关系的类别。

限定域关系抽取方法:

  • 基于模板的关系抽取方法:通过人工编辑或者学习得到的模板对文本中的实体关系进行抽取和判别,受限于模板的质量和覆盖度,可扩张性不强。
  • 基于机器学习的关系抽取方法:将关系抽取看成是一个分类问题。

1.2. 常见数据集

工业界数据集

由于工业界的数据集通常来自其自身业务的记录,并不对外公开,故以下只举例介绍相关比赛中出现的数据集(下载链接因版权原因,随时删除):

2019全国知识图谱与语义计算大会

​ 数据集 提取码:ta8z

  • 任务目标

    • 在本次任务中,我们重点关注人物之间的关系抽取研究,简称IPRE(Inter-Personal Relationship Extraction)。给定一组人物实体对和包含该实体对的句子,找出给定实体对在已知关系表中的关系。我们将从以下两个方面进行评测:
    • Sent-Track:从句子级别上根据给定句子预测给定人物实体对的关系
      • 输入:一组人物实体对和包含该实体对的一个句子
      • 输出:该人物实体对的关系
      • 样例一:
      • 输入:
      • 贾玲\t冯巩\t贾玲,80后相声新秀,师承中国著名相声表演艺术家冯巩。
      • 输出:
      • 人物关系/师生关系/老师
    • Bag-Track:从包级别上根据给定句子集合预测给定人物实体对的关系
      • 输入:一组人物实体对和包含该实体对的若干句子
      • 输出:该人物实体对的关系
  • 数据来源

    • 主要来源于互联网网页文本,其中验证集和测试集是通过人工进行标注的,而训练集是通过远程监督(Distant Supervision)自动生成的。
    • 总共有34类人物关系,包括一类特殊关系NA
    • 本次竞赛使用的SKE数据集是业界规模最大的基于schema的中文信息抽取数据集,其包含超过43万三元组数据、21万中文句子及50个已定义好的schema,表1中展示了SKE数据集中包含的50个schema及对应的例子。数据集中的句子来自百度百科和百度信息流文本。数据集划分为17万训练集,2万验证集和2万测试集。其中训练集和验证集用于训练,可供自由下载,测试集分为两个,测试集1供参赛者在平台上自主验证,测试集2在比赛结束前一周发布,不能在平台上自主验证,并将作为最终的评测排名。
  • 评价指标:

    • 精确率(Precision, P)、召回率(Recall, R)和F1值(F1-measure, F1),分为Sent-Track和Bag-Track的两个部分,每部分按F1值分别排名。只统计预测结果中非NA的数目。
    • F1最终结果越接近1分数越高。
  • 解决方案

    • top1评测论文:https://conference.bj.bcebos.com/ccks2019/eval/webpage/pdfs/eval_paper_3_2.pdf

2019语言与智能技术竞赛

  • 数据集 提取码:dk4n

  • 任务目标

    • 给定schema约束集合及句子sent,其中schema定义了关系P以及其对应的主体S和客体O的类别,例如(S_TYPE:人物,P:妻子,O_TYPE:人物)、(S_TYPE:公司,P:创始人,O_TYPE:人物)等。 任务要求参评系统自动地对句子进行分析,输出句子中所有满足schema约束的SPO三元组知识*Triples=[(S1, P1, O1), (S2, P2, O2)…]*。
    • 输入/输出:
    • (1) 输入:schema约束集合及句子sent
    • (2) 输出:句子sent中包含的符合给定schema约束的三元组知识Triples
  • 数据集说明

  • 使用的SKE数据集是业界规模最大的基于schema的中文信息抽取数据集,其包含超过43万三元组数据、21万中文句子及50个已定义好的schema,表1中展示了SKE数据集中包含的50个schema及对应的例子。数据集中的句子来自百度百科和百度信息流文本。数据集划分为17万训练集,2万验证集和2万测试集。其中训练集和验证集用于训练,可供自由下载,测试集分为两个,测试集1供参赛者在平台上自主验证,测试集2在比赛结束前一周发布,不能在平台上自主验证,并将作为最终的评测排名。

  • 具体说明:https://www.biendata.com/competition/chip2019/data/

  • 评价指标

    • Precision、Recall、F1值
  • top1方案及结果

    • 解决方案:Schema约束的知识抽取系统架构(“信息抽取”任务冠军队伍报告)
    • 最高得分:89.3% F1 在测试集,投入使用效果 87.1% F1。
    • 其他方案:
      • Baidu Official Baseline Model(Python2.7)
      • Baseline Model(Python3)
      • Multiple-Relations-Extraction-Only-Look-Once
      • Schema-based-Knowledge-Extraction

2020语言与智能技术竞赛

  • 数据集 提取码:8ccx

  • 任务目标:

    • 在给定的文本句子中,根据预先定义的schema集合,抽取出所有满足 schema 约束的 SPO 三元组。schema 定义了关系 P 以及其对应的主体 S 和客体 O 的类别,根据 O 类型的复杂程度可以划分为以下两种:

      1. 简单 O 值:也就是说 O 是一个单一的文本。简单 O 值是最常见关系类型,去年竞赛中所发布的所有 schema 都属于这种类型。为了保持格式统一,简单 O 值类型的 schema 定义通过结构体保存,结构体中只有一个 @value 字段存放真正的 O 值类型。例如,「妻子」关系的 schema 定义为:

        1
        2
        3
        4
        5
        6
        7
        {
        S_TYPE: 人物,
        P: 妻子,
        O_TYPE: {
        @value: 人物
        }
        }
      2. 复杂 O 值:也就是说 O 是一个结构体,由多个语义明确的文本共同组成,多个文本对应了结构体中的多个槽位(slot)。在复杂 O 值类型的定义中,@value 槽位可以认为是该关系的默认 O 值槽位,对于该关系不可或缺,其他槽位均可缺省。例如,「饰演」关系中 O 值有两个槽位 @value 和 inWork,分别表示「饰演的角色是什么」以及「在哪部影视作品中发生的饰演关系」,其 schema 定义为:

        1
        2
        3
        4
        5
        6
        7
        8
        {
        S_TYPE: 娱乐人物,
        P: 饰演,
        O_TYPE: {
        @value: 角色
        inWork: 影视作品
        }
        }
    • 输入/输出:

      • 输入:schema约束集合及句子sent
      • 输出: 句子sent中包含的符合给定schema约束的三元组知识Triples
  • 数据集说明:

    • 使用的DuIE2.0数据集是业界规模最大的基于schema的中文信息抽取数据集,其包含超过21万中文句子及48个已定义好的schema,表1 中展示了DuIE2.0数据集中包含的43个简单知识的schema及对应的例子,表2 中展示了DuIE2.0数据集中包含的5个复杂知识的schema及对应的例子。数据集中的句子来自百度百科、百度贴吧和百度信息流文本。数据集划分为17万训练集,2万验证集和2万测试集。
  • 评估方法:

    • 对测试集上给出的 SPO 结果和人工标注的 SPO 结果进行精准匹配,采用 Precision,Recall 和 F1 值作为评价指标。对于复杂 O 值类型的 SPO,必须所有槽位都精确匹配才认为该 SPO 抽取正确。
  • 基线系统 Baseline Systems

    • GitHub 基线系统
      https://github.com/PaddlePaddle/Research/tree/master/KG/DuIE_Baseline
    • 百度AI Studio 基线系统示例
      https://aistudio.baidu.com/aistudio/projectdetail/357344

1.3. 评测标准

  • P: 准确率

  • R:召回率

  • F1: 2 P*R/(P+R)

2. 方法总结

2.1. 基于模板的方法

模板匹配:是关系分类中最常见的方法,使用一个模板库对输入文本两个给定实体进行上下文匹配,如果满足模板对应关系,则作为实体对之间的关系。常见的模板匹配方法主要包括:

  • 人工模板:主要用于判断实体间是否存在上下位关系。上下位关系的自然语言表达方式相对有限,采用人工模板就可以很好完成关系分类。但对于自然语言表达形式非常多的关系类型而言,这就需要采取统计模板。
  • 统计模板:无须人工构建,主要基于搜索引擎进行统计模板抽取。具体地,将已知实体对作为查询语句,抓取搜索引擎返回的前n个结果文档并保留包含该实体对的句子集合,寻找包含实体对的最长字串作为统计模板,保留置信度较高的模板用于关系分类。

2.1.1. 基于触发词/字符串

例:句子中上下位关系,比如hyponym(China; Asia countries)。从下面两个句子中都可以抽取出这种关系:

Asia countries, especially China, Japan, and India…

Asia countries, such as China, Japan, and India…

两个实体之间的especially和such as可以看做这种关系的特征。寻找更多表达这种关系的句子,构造规则模板,即可用于抽取构成上下位关系的实体,从而发现新的三元组。

2.1.2. 基于依存句法

使用NLP工具获取句子相关特征,对处理结果一般进行如下处理:

  1. 对输入句子进行分词、词性标注、命名实体识别、依存分析等处理
  2. 根据句子依存句法树结构进行规则匹配,每匹配一条规则就生成一个三元组
  3. 根据扩展规则对抽取到的三元组进行扩展
  4. 对三元组实体和触发词进一步处理抽取出关系

小结

手写规则的 优点 :

  • 人工规则有高准确率(high-precision)
  • 可以为特定领域定制(tailor)
  • 在小规模数据集上容易实现,构建简单

缺点:

  • 低召回率(low-recall)
  • 特定领域的模板需要专家构建,要考虑周全所有可能的 pattern 很难,也很费时间精力
  • 需要为每条关系来定义 pattern
  • 难以维护
  • 可移植性差

2.2. 监督学习

有监督的关系抽取方法:

  • 基于特征工程的方法:需要显示地将关系实例转换成分类器可以接受的特征向量
  • 基于核函数的方法:直接以结构树为处理对象,在计算关系之间距离的时候不再使用特征向量的内积而是用核函数
  • 基于神经网络的方法:直接从输入的文本中自动学习有效的特征表示,是一个端到端的过程

2.2.1. 机器学习

将关系抽取看成是一个基于构造特征的分类问题

常见特征:

  • 实体特征,包括实体前后的词,实体类型,实体之间的距离等

  • chunk,如 NP,VP,PP 这类短语

  • 实体间的依存关系,实体间树结构的距离,及其他特定的结构信息

标准流程:

  • 预先定义提取的关系集合
  • 选择相关命名实体集合
  • 寻找并标注数据
  • 选择有代表性的语料库
  • 标记命名实体
  • 人工标注实体间关系
  • 分割训练、开发、测试集
  • 设计特征
  • 选择并训练分类器
  • 评估结果

通常会训练两个分类器,第一个分类器是 yes/no 的二分类,判断命名实体间是否有关系,如果有关系,再送到第二个分类器,给实体分配关系类别。这样做的好处是通过排除大多数的实体对来加快分类器的训练过程,另一方面,对每个任务可以使用基于具体任务的特征集。常用的分类器包括 MaxEnt、Naive Bayes、SVM 等。

2.2.2. 深度学习 Pipeline vs Joint Model

Pipeline

Pipeline方法先在句子中抽取实体、而后再抽取关系。即把实体识别和关系分类作为两个完全独立的过程,互不影响,关系的识别依赖于实体识别的效果。

Joint Model

现有联合抽取模型总体上有两大类:

1、共享参数的联合抽取模型

通过共享参数(共享输入特征或者内部隐层状态)实现联合,此种方法对子模型没有限制,但是由于使用独立的解码算法,导致实体模型和关系模型之间交互不强。

2、联合解码的联合抽取模型

为了加强实体模型和关系模型的交互,复杂的联合解码算法被提出来,比如整数线性规划等。这种情况下需要对子模型特征的丰富性以及联合解码的精确性之间做权衡:

  • 一方面如果设计精确的联合解码算法,往往需要对特征进行限制,例如用条件随机场建模,使用维特比解码算法可以得到全局最优解,但是往往需要限制特征的阶数。
  • 另一方面如果使用近似解码算法,比如集束搜索,在特征方面可以抽取任意阶的特征,但是解码得到的结果是不精确的。

因此,需要一个算法可以在不影响子模型特征丰富性的条件下加强子模型之间的交互。

此外,很多方法再进行实体抽取时并没有直接用到关系的信息,然而这种信息是很重要的。需要一个方法可以同时考虑一个句子中所有实体、实体与关系、关系与关系之间的交互。

Pipeline对比 Joint Model:

相比于传统的Pipeline方法,联合抽取能获得更好的性能。虽然Pipeline方法易于实现,这两个抽取模型的灵活性高,实体模型和关系模型可以使用独立的数据集,并不需要同时标注实体和关系的数据集。但存在以下缺点:

  1. 误差积累:实体抽取的错误会影响下一步关系抽取的性能。
  2. 实体冗余:由于先对抽取的实体进行两两配对,然后再进行关系分类,没有关系的候选实体对所带来的冗余信息,会提升错误率、增加计算复杂度。
  3. 交互缺失:忽略了这两个任务之间的内在联系和依赖关系。

2.3. 半监督/无监督方法

2.3.1. Bootstrapping

Bootstrapping:利用少量的实例作为初始种子集合,然后在种子集合上学习获得关系抽取的模板,再利用模板抽取更多的实例,加入种子集合中并不断迭代。Bootstrapping的优点构建成本低,适合大规模的关系任务并且具备发现新关系的能力,但也存在对初始种子较为敏感、存在语义漂移、准确率等问题。Bootstrapping 如今在工业界中依旧是快速构建大规模知识图谱的重要方法。在实际使用中,可以考虑结合基于深度语义模型的关系抽取方法,进一步提高图谱召回。

工业应用:

bootstrapping比较常见的方法有DIPRE和Snowball。和DIPRE相比,Snowball通过对获得的模板pattern进行置信度计算,一定程度上可以保证抽取结果质量。

DIPRE: Dual Iterative Pattern Expansion

DIPRE是从HTML文档集合中提取结构化关系(或表格)的一种方法。 该方法在类似Web的环境下效果最好,其中的表格要提取的tuples往往会在反复出现在集合文档中一致的context内。 DIPRE利用这种集合冗余和内在的结构以提取目标关系并简化训练。

DIPRE Pipeline

DIPRE pattern由5-tuple <order, urlprefix, left, middle, right>组成,并通过将具有相等字符串分隔实体(middle)的共现种子tuples group在一起生成,然后将 left 字符串和 right 字符串分别设置为实体左侧和右侧上下文的最长公共子字符串。 order 反映了实体出现的顺序,urlprefix 设置为发现了 tuples 的源URL的最长公共子串。在从最初的种子 tuples 中生成一些 pattern 之后,DIPRE扫描包含 pattern 可匹配的文本片段的可用文档。随后,DIPRE生成新的tuples,并将它们用作新的“种子”。DIPRE反复迭代以上过程找到文档中的新 tuples 以识别新的可靠 patterns。

伪代码:

1
2
3
4
5
6
收集具有关系R的一组种子tuples

迭代:
1.找到包含这些种子tuples的句子
2.查看种子tuples之间或周围的上下文,并泛化该上下文以生成patterns
3.用这些patterns找到更多种子tuples

DIPRE样例

从 5 个种子 tuples 开始,找到包含种子的实例,替换关键词,形成 pattern,迭代匹配,就为 (author,book) 抽取到了 relation pattern,x, by y, 和 x, one of y’s。

DIPRE利弊

优点:

  1. 能够从非结构化文本中抽取出结构化的关系
  2. 训练成本低,每个新场景只需要少量种子tuples。

缺点:

  1. 依赖 HTML 标签
  2. 缺少对新 pattern 和 tuples 的评估
  3. 抽取结果噪声较多
  4. 抽取结果 Recall 较低

2.3.2. 基于远程监督的方法

远程监督算法基于一个非常重要的假设:对于一个已有的知识图谱中的一个三元组(由一对实体和一个关系构成),外部文档库中任何包含这对实体的句子,在一定程度上都反映了这种关系。基于这个假设,远程监督算法可以基于一个标注好的小型知识图谱,给外部文档库中的句子标注关系标签,相当于做了样本的自动标注,因此是一种半监督的算法。

(1)多示例学习:主要基于Bag的特征进行关系分类,主要代表文献包括PCNN[1]、Selective Attention over Instances[2]、Multi-label CNNs[3]、APCNNs[4],其中Bag的表示主要方式和池化方式为:

img

(2)强化学习:在采用多示例学习策略时,可能会出现整个Bag包含大量噪声的情况。基于强化学习的CNN+RL[5]比句子级别和Bag级别的关系分类模型取得更好效果。

模型主要由样例选择器和关系分类器构成。样例选择器负责从样例中选择高质量的句子,采取强化学习方式在考虑当前句子的选择状态下选择样例;关系分类器向样例选择器反馈,改进选择策略。

(3)预训练机制:采取“Matching the Blank[6]”方法,首次在预训练过程中引入关系分类目标,但仍然是自监督的,没有引入知识库和额外的人工标注,将实体metion替换为「BLANK」标识符。

  • 该方法认为包含相同实体对的句子对为正样本,而实体对不一样的句子对为负样本。如图,rA和rB构成正样本,rA和rC构成rB和rC构负样本。
  • 不同于传统的远程监督,该方法训练中不使用关系标签,采用二元分类器对句子对进行相似度计算。预训练的损失包含2部分:MLM loss 和 二元交叉熵关系损失。
  • 在FewRel数据集上,不进行任何tuning就已经超过了有监督的结果。

img

3. 抽取工具应用

3.1. TextRunner

TEXTRUNNER三个关键步骤:

Open Information Extraction from the Web(TextRunner, 2007,华盛顿大学)

  • Self-Supervised Learner:构造训练数据集,学习一个贝叶斯分类器,判断(e*i, relation words, e_*j)是否是可信的关系
  • Single-Pass Extractor:输入一句话,产生所有可能的候选三元组,使用分类器判别,保留可信的三元组
  • Redundancy-Based Assessor:统计(e_*i, relation words, e_*j)发生在不同句子中的频次,保留高频词的结果作为最终结果

Self-Supervised Learner:

  • parsing :在一个小的数据集进行语法解析,解析句子中的名词短语

  • 构造三元组:将名词短语作为可能的实体e_i,两个名词短语之间的词语作为关系,构成三元组候选集合

  • 使用约束构造正负样本: 满足下述三个条件的作为正样本

    • ei e_j存在依赖路径,并且路径长度小于一定的值
    • The path from ei to ej along the syntax tree does not cross a sentence-like boundary (e.g. relative clauses)
    • ei ej都不是代词
  • 训练分类器:三元组 [公式] ,将三元组特征化,训练一个贝叶斯分类器;特征有

    • presence of part-of-speech tag sequences in the relation [公式]
    • the number of tokens in [公式]
    • the number of stopwords in [公式]
    • whether or not an object e is found to be a proper noun
    • the part-of-speech tag to the left of ei
    • the part-of-speech tag to the right of ej .

Single-Pass Extractor:

输入一个句子,处理过程如下

  • 先进行词性标注,然后使用lightweight noun phrase chunker识别名词短语
  • 识别名词短语之间的词语作为关系表示
  • 使用分类器进行分类,判别这个三元组候选是否可信

Redundancy-based Assessor:

  • 会通过启发式的规则归一化关系短语,比如去除不必要的修饰词语
  • 统计三元组的频数,如果这个三元组是从k个不同的句子中抽取得到的话

3.2. OLLIE

OLLIE支持基于语法依赖树的关系抽取。流程图如下,主要包含三个步骤

  • Constructing a Bootstrapping Set:使用REVERB已经抽取到的高质量的三元组作为Seed Tuples,使用Seed Tuple抽取包含这些seed tuple的句子,构造一个比较大的训练数据集
  • Open Pattern Learning:基于语法解析,使用训练数据集学习open pattern templates/抽取模式模板
  • Pattern Matching for Extraction:使用学习到的open pattern templates来抽取新的三元组

3.3. IEPY

开源项目:https://github.com/machinalis/iepy

主要做关系抽取:IEPY is an open source tool for Information Extraction focused on Relation Extraction.

工具特征:

  1. 带web-UI的语料标注⼯具。

  2. 基于主动学习的关系抽取的工具。

  3. 基于规则的关系抽取工具。

  4. 有web-UI帮助使用:

    1)方便非专业用户使用部分功能。

    2)允许分布式的用户输入。

  5. 通过斯坦福CoreNLP做共指解析。

  6. 可以基于开源代码作二次开发。

使用

安装:

作为Python包安装,pip install iepy, 并下载第三方数据 iepy –download-third-party-data

使⽤:

1 创建项目

iepy –create

2 导⼊要抽取的语料

python bin/csv_to_iepy.py data.csv

3 数据预处理( text tokenization, sentence splitting, lemmatization, part-of-speech tagging, and named entity recognition)

python bin/preprocess.py

4 启动web-ui查看项⽬

python bin/manage.py runserver

5 进行active learning(需要自己再依据工具提示标一些数据)或rule-based(写规则)关系抽取

6 在界面上标⼀些测试集来验证抽取效果。

总结

功能:

对于要处理的语料导⼊到项目里,提供前面的预处理和两种方式的关系抽取。Active Learning的需要自己定义关系和标⼀些数据。Rule-based的需要自己写规则。也封装好了⼀些脚本⽅便的做导⼊数据、预处理、规则检查等。

使用方式:

python包 + webUI,类似pyspider。可以用界面来定义关系和查看抽取结果、标注测试集等。不过还是需要⽤命令行来load数据,预处理等,这部分其实也可以在界面实现。

评价:

由于开发的时间早,抽取的方法不新,也没有预先在⼤数据集上训练得到通用领域关系抽取的模型,需要用户自己定义关系并标注数据。每⼀个抽取任务创建⼀个project,使⽤web界面方便操作和可视化,感觉我们做领域迁移也可以采用这种⽅法,把流程固定,然后通过创建不同的project,导⼊不同的数据,定义不同的关系,然后⽤webUI进⾏可视化和人工操作。

3.4. spaCy

3.4.1 介绍

工业级的NLP工具:功能很强⼤,不⽌是做Information Extraction,⽤Cython优化,各种处理超级快(官网fastest in the world),能⽤于在真实场景和产品里的。适合对用于Deep Learning的⽂本进行预处理。能和TensorFlow, PyTorch, scikit-learn, Gensim 等深度学习框架无缝衔接。

3.4.2 工具特点:

  • 无损的tokenization
  • 命名实体识别
  • ⽀持53+语言
  • 支持11种语言上的17个统计模型
  • 预训练好的词向量
  • SOTA的速度
  • 方便与深度学习集成
  • POS标注
  • 带标记的依存句法分析
  • 句法驱动的句子分割
  • 内置用于语法和NER的可视化工具
  • 方便的字符串->哈希值映射
  • 导出到numpy数组
  • 高效的⼆进制序列化
  • 方便的模型打包和部署
  • 稳健,经过严格评估的准确性

3.4.3 总结

并非专门做信息抽取,也没有抽取关系的功能。封装了NLP相关的基础工作,并优化了速度以用于真实产品。

同时也允许用户自己训练模型load后使⽤。

使用方式:

python包+load下载的模型。

评价:

功能很多很实用,定位在于做深度学习前面的文本预处理,且优化速度。使用方式和很多⼯具⼀样,使用python包,封装好各种通用功能和接口,再通过加载不同的模型实现使⽤在不同领域、语言或者应对方法改进的情况。

3.5 NELL

3.5.1 介绍

永恒语⾔学习:

Never-ending Language Learning。不断学习语⾔知识,2010年提出。

architecture:

流程:

利⽤少量标记样本集合训练学习模型, 然后⽤该模型去标记更多样本。(需要偶尔人工标注)。运⽤多视角学习(multi-view learning)分别从文本背景信息、网页结构信息、构词法特征以及规则学习4个角度进行新知识抽取和知识库的扩充。

3.5.2 总结

评价:

可以借鉴这种方式扩充构建好的知识库,对于通用领域知识库可以在网页文本上抽取,特定领域的可以喂相关领域的文档或者爬取到的网页文本。信息抽取工具应该不包含这个功能,而是通过这个⼯具的使用能够实现这种功能。

3.6 Deepdive

官网地址:http://deepdive.stanford.edu/

Deepdive是stanford大学InfoLab实验室开发的一个开源知识抽取系统,它通过弱监督学习,从非结构化的文本中提取结构化的关系数据。DeepDive用于提取实体之间的复杂关系并推断涉及这些实体的事实。在使用Deepdive进行关系抽取的时候,使用者不需要关心算法,只需要指定实体的特征,Deepdive通过联合推理,即可得出两个实体之间有关系的概率。

Deepdive的优点如下:
(1)可以处理带噪声的数据,用户可以通过对断言设置置信度来矫正噪声
(2)可以通过使用已有的领域知识来指导推理结果,通过用户反馈的结果来提高预测的准确率
(3)使用远监督技术,不需要或仅需要少量数据即可完成抽取

抽取流程如下:

一个中文抽取示例:股权抽取 https://zhuanlan.zhihu.com/p/43143663

3.7 Stanford

官网地址:https://stanfordnlp.github.io/CoreNLP

Stanford CoreNLP是斯坦福大学提供的自然语言处理工具,是由Java写成的,可通过使用Web服务与CoreNLP进行交互,从而使用python等其他语言进行编程,目前提供python接口可直接安装使用,支持多种语言。

Open IE(开放信息提取)是指从纯文本中提取关系元组,与其他提取不同的是,Open IE 不需要提前定义schema,主要利用语言结构进行开放领域信息抽取。Stanford Open IE是Stanford CoreNLP包中的一个开放领域信息抽取模块,该模块的抽取思路如下:

1、先将句子分成几个子句(学习一个分类器)

2、最大程度地缩短每个子句,产生一组所需的句子片段

3、从片段中提取三元组(自然逻辑)

相关论文链接:https://nlp.stanford.edu/pubs/2015angeli-openie.pdf

Relation Extractor(关系抽取)是Stanford CoreNLP中的另一个处理模块,用于抽取特定领域的关系。目前支持Live_In, Located_In, OrgBased_In, Work_For, and None这几种关系。用户可以使用提供的接口使用自己的数据集训练自己的模型,从而实现特定领域的关系抽取。该模块的抽取思路如下:

1、数据预处理:tokenization,part of speech tagging

2、实体识别(标注)

3、使用多类逻辑回归分类器对关系进行分类

Stanford Open IE& Relation Extractor对比

模块 领域 使用方法 用户使用
Open IE 开放领域 下载StandfordCoreNLP包 可以使用java或者其他语言进行服务器与来进行编码
Relation Extractor 特定领域 下载StandfordCoreNLP包,用户可自行训练特定领域的模型 可以使用java或者其他语言与服务器交互来进行编码

4. 相关文献

  1. Distant Supervision for Relation Extraction via Piecewise Convolutional Neural Networks. EMNLP
  2. Attention over Instances (Lin 2016)
  3. Relation Extraction with Multi-instance Multi-label Convolutional Neural Networks.
  4. Distant Supervision for Relation Extraction with Sentence-Level Attention and Entity Descriptions
  5. Reinforcement Learning for Relation Classification from Noisy Data
  6. Matching the Blanks: Distributional Similarity for Relation Learning
  7. Riedel, Sebastian, Limin Yao, and Andrew McCallum. “Modeling relations and their mentions without labeled text.”Joint European Conference on Machine Learning and Knowledge Discovery in Databases. Springer, Berlin, Heidelberg, 2010.

5. 参考资源

收录文章
https://zhuanlan.zhihu.com/p/139485679

https://zhuanlan.zhihu.com/p/77868938

SemEval-2020自由文本关系抽取冠军方案解读

https://github.com/WindChimeRan/NREPapers2019

https://paperswithcode.com/sota

2019全国知识图谱与语义计算大会

望江人工智库 信息抽取

https://github.com/yuanxiaosc/Entity-Relation-Extraction

https://zhuanlan.zhihu.com/p/145812779

  • 算法

展开全文 >>

bert和xlnet

2021-10-28

1. AR与AE语言模型

AR: Autoregressive Language modeling
AE: AutoEncoding Language modeling

AR语言模型:指的是,依据前面(或后面)出现的tokens来预测当前时刻的token,代表有ELMO,GPT等。
AE语言模型:通过上下文信息来预测被mask的token,代表有 BERT , Word2Vec(CBOW) 。

二者有着它们各自的优缺点:

AR 语言模型:

缺点: 它只能利用单向语义而不能同时利用上下文信息。ELMO 通过双向都做AR 模型,然后进行拼接,但从结果来看,效果并不是太好。
优点: 对生成模型友好,天然符合生成式任务的生成过程。这也是为什么 GPT 能够编故事的原因。

AE 语言模型:

缺点: 由于训练中采用了 [MASK] 标记,导致预训练与微调阶段不一致的问题。BERT独立性假设问题,即没有对被遮掩(Mask)的 token 之间的关系进行学习。此外对于生成式问题, AE 模型也显得捉襟见肘。
优点: 能够很好的编码上下文语义信息(即考虑句子的双向信息), 在自然语言理解相关的下游任务上表现突出。

总结

所以,AR方式所带来的自回归性学习了预测 token 之间的依赖,这是 BERT 所没有的;而 BERT 的AE方式带来的对深层次双向信息的学习,却又是像ELMo还有GPT单向语言模型所没有的,不管是有没有替换 [MASK]。于是,自然就会想,如何将两者的优点统一起来?这时就到了XLNet登场的时间。

2. Permutation Language Model

具体实现方式是,通过随机取一句话的一种排列,然后将末尾一定量的词给遮掩(和 BERT 里的直接替换 [MASK] 有些不同)掉,最后用 AR 的方式来按照这种排列依次预测被遮掩掉的词。

3. Transformer-XL

4. Relative Positional Encoding

简单知识点

1. bert mask之间相互独立

BERT进行了独立假设,比如句子[New, York, is, a, city], 假定MASK掉New York,输入为[MASK, MASK, is, a, city], Bert根据is a city 预测New; 根据is a city预测York. 也就是预测New和预测York是独立的,不相关的。

作者提出的Generalized Autoregressive LM在预测York依赖了New。

总结:BERT: Masked Language Model, 使用了双边的context信息,但是忽略了masked token之间的依赖关系。

参考文章

一文看懂XLNet

  • 算法

展开全文 >>

biaffine分析

2021-10-16

下面改动这个代码,方便理解和实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

class Biaffine(torch.nn.Module):
def __init__(self, n_in=768, n_out=2, bias_x=True, bias_y=True):
super(Biaffine, self).__init__()
self.n_in = n_in
self.n_out = n_out
self.bias_x = bias_x
self.bias_y = bias_y

self.weight = nn.Parameter(torch.Tensor(n_out, n_in + bias_x, n_in + bias_y))
self.reset_parameters()
def reset_parameters(self):
# 改动这里
nn.init.ones_(self.weight)

def forward(self, x, y):
if self.bias_x:
x = torch.cat((x, torch.ones_like(x[..., :1])), -1)
if self.bias_y:
y = torch.cat((y, torch.ones_like(y[..., :1])), -1)

b = x.shape[0]
o = self.weight.shape[0]

x = x.unsqueeze(1).expand(-1, o, -1, -1)
weight = self.weight.unsqueeze(0).expand(b, -1, -1, -1)
y = y.unsqueeze(1).expand(-1, o, -1, -1)

s = torch.matmul(torch.matmul(x, weight), y.permute((0, 1, 3, 2)))
if s.shape[1] == 1:
s = s.squeeze(dim=1)
return s


# 1 表示分类个数,下面改成2也是在此处哦
model = Biaffine(3, 1, bias_x=False, bias_y=False)
x = torch.arange(12, dtype=torch.float).reshape(2, 2, 3)
y = torch.arange(12, dtype=torch.float).reshape(2, 2, 3)
result = model(x, y)
print(result)

分析:

1. x.shape

1
2
3
4
5
6
7
8
x
Out[56]:
tensor([[[ 0., 1., 2.],
[ 3., 4., 5.]],
[[ 6., 7., 8.],
[ 9., 10., 11.]]])

表示的是sequence_length为2, 那么[0,1,2]表示第一个字,[3,4,5]表示第二个字.

2. x和weight点积

1
2
3
4
5
6
7
8
9
## 中间过程忽略

torch.matmul(x, weight)
Out[2]:
tensor([[[[ 3., 3., 3.],
[12., 12., 12.]]],
[[[21., 21., 21.],
[30., 30., 30.]]]], grad_fn=<UnsafeViewBackward>)

3. 怎么来的呢

1
2
3
4
5
6
7

0 * 1 + 1 * 1 + 2 * 1 = 3
3 * 1 + 4 * 1 + 5 * 1 = 12

6 * 1 + 7 * 1 + 8 * 1 = 21
9 * 1 + 10 * 1 + 11 * 1 = 30

4. y.permute((0, 1, 3, 2))

1
2
3
4
5
6
7
8
9
10
y.permute((0, 1, 3, 2))

Out[3]:
tensor([[[[ 0., 3.],
[ 1., 4.],
[ 2., 5.]]],
[[[ 6., 9.],
[ 7., 10.],
[ 8., 11.]]]])

5. torch.matmul(torch.matmul(x, weight), y.permute((0, 1, 3, 2)))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
torch.matmul(torch.matmul(x, weight), y.permute((0, 1, 3, 2)))
Out[4]:
tensor([[[[ 9., 36.],
[ 36., 144.]]],
[[[441., 630.],
[630., 900.]]]], grad_fn=<UnsafeViewBackward>)


# 怎么来的呢

3 * 0 + 3 * 1 + 3 * 2 = 9
3 * (3 + 4 + 5) = 36
12 * (0 + 1 + 2) = 36
12 * (3 + 4 + 5) = 144



# 发现了没,sequence_length那一维(即每个字)都和其他的字进行点积,并乘以权重,从而获取最终的output。
# 是不是瞬间发现厉害的地方。。。。。

final. 扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 扩展,如果out为2的话

s
Out[2]:
tensor([[[[ 9., 36.], // 分类1
[ 36., 144.]],

[[ 9., 36.], // 分类2
[ 36., 144.]]],

[[[441., 630.],
[630., 900.]],
[[441., 630.],
[630., 900.]]]], grad_fn=<UnsafeViewBackward>)

// 即表示多分类情况下每个分类的输出,通过反向更新weight
// 是不是get到重点了。

  • 算法

展开全文 >>

&laquo; Prev1…56789…28Next &raquo;
© 2025 张宇
Hexo Theme Yilia by Litten
  • 所有文章
  • 友链
  • 关于我

tag:

  • linux
  • 技术
  • 小桥流水人家
  • MySQL
  • flutter
  • 算法
  • machine learning
  • SQLAlchemy
  • python
  • CI
  • git
  • go
  • grpc
  • 机器学习

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • Github
  • Google
  • StackOverFlow
探索世界美好的存在。