介绍
共指解析,按照百度的定义如下:
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 | def _bertify(self, doc: Doc) -> torch.Tensor: |
- 获取word level embedding
1 | from typing import Tuple |
- 这部分可以看我最后简单示例,说明实现方式。
假设tokens长度为455, 这里输出就变成了word level embedding。
粗排(rough score)
还是觉得,不考虑batch_size那一维,整个代码都方便理解许多😂😂😂😂😂😂😂😂😂😂。
1 | class RoughScorer(torch.nn.Module): |
获取词对特征
看到么看到么,人家到这里才开始干活~
top_indices的维度为(405,50),表示这个句子一共有405个tokens,然后获取每个token最相关联的50个tokens的索引。
1 | def forward(self, # type: ignore # pylint: disable=arguments-differ #35566 in pytorch |
AnaphoricityScorer
这部分看着有点绕,看如下代码:
1 | def forward(self, *, # type: ignore # pylint: disable=arguments-differ #35566 in pytorch |
_get_pair_matrix中的b_mentions,可参考b_mentions。后续接了个ffnn,获得其最终得分。
整体代码作者挺喜欢参差网络和前馈神经网络这种操作。
loss计算
CorefLoss计算分成了两部分,一个是NLML,另外一个BCELoss.
1 |
|
附录
word-level实现demo
1 | # -*- coding: utf8 -*- |
取索引操作
1 | a |
精彩例子
这种写法我挺喜欢的,比如:
1 |
|