信息抽取(二)实体识别之经典方法介绍

AI 2年前 (2022) admin
261 0 0
作者简介:Neo,二范数智能AI团队成员,武汉大学硕士,研究方向为信息检索、知识图谱、医疗数据挖掘与分析,对机器学习、深度学习在NLP领域的应用有着浓厚兴趣。



1、引言

通过信息抽取(一)信息抽取任务初识一文,我们对于信息抽取任务有了初步的认识,即识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。通常包括两部分:(1)实体边界识别;(2) 确定实体类别(人名、地名、机构名或其他)。

 

我们能够看到,这是一种序列处理思想,目前主流处理序列处理任务的方法按照技术演化可以分为基于规则和词典的方法基于统计(机器学习)的方法深度学习的方法等。本节我们为大家回顾各类方法的经典模型,为后文实现复杂场景下的实体识别提供方法支撑。


2、基于规则和词典的方法

(1)基于规则的方法

计算机中的规则可以理解为一种和文本匹配的通用符号语言。需要分析实体及其类别具备的文本的通用特征,将其转化为通用的符号语言,由此实现同一类别下文本的匹配。
 
正则表达式就基于上述思想设计了一系列模式,由此实现文本的检索或替换符合某种模式的文本。
场景应用
应用优点:
  • 推理的准确性非常好
  • 可解释性好,其是具有逻辑性的

应用局限:
  • 其需要专家制定大量的推理规则
  • 对于不知道规则的泛化性能力比较差

总结:
大多数时候,规则往往依赖具体语言领域文本风格,难以覆盖所有的语言现象。也正是因为费时费力的局限,目前已经很少有研究完全依赖正则表达式,但这不代表正则不重要,虽然研究的范式已经朝向模型计算演化,但是对于模型产生的一些异常结果(即badcase),往往要写规则,使用正则人工干预。除此之外,正则也可以广泛使用于构建模型的数据集中。
 
正则外部资源:
Python为正则提供了re模块,关于re模块的语法介绍,可以参考下文:
https://zhuanlan.zhihu.com/p/28672572?group_id=883065970518790144
 
语法掌握固然重要,但是实践才能系统的掌握应用,关于正则的实践,可以通过下列网站进行练习:
https://regex101.com/
正则知识介绍:
正则可通过分组断言来辅助实体识别任务
分组:将正则语句分组,使得你明确知道当前匹配属于哪一组
断言:使得在匹配时限定一些上下文条件,指明某个字符串前边或者后边,将会出现满足某种规律的字符串
示例如下图所示
 

信息抽取(二)实体识别之经典方法介绍

正则应用举例:
我们做了通过正则匹配的案例,以供大家参考:
  • 身份证号码信息的抽取
regex = "d{17}[d|x|X]"text = "身份证号码信息是410403198805135531"id_number = re.findall(regex, text)print(id_number)
#抽取结果:['410403198805135531']

  • Ip地址信息的抽取
regex = "(?:(?:[0,1]?d?d|2[0-4]d|25[0-5]).){3}(?:[0,1]?d?d|2[0-4]d|25[0-5])"text = "ip地址信息是127.0.0.1"ip = re.findall(regex, text)print(ip)
#抽取结果:['127.0.0.1'']

  • 电话号码信息的抽取
regex = "1[34578]d{9}"text = "电话号码信息是18768875303"phone_number = re.findall(regex, text)print(phone_n umber)
#抽取结果:['18768875303']


3、基于机器学习的方法

机器学习模型应用于实体抽取最重要的思想是获取实体的特征信息,本文将以经典的隐马尔代夫模型HMM模型以及随机条件场CRF进行介绍。

(1)预备定义:
随机场:
HMM模型和CRF有着相似的思想,它们都和随机场这个概念有关,而随机场是由若干个位置组成的整体,当给每一个位置中按照某种分布随机赋予一个值之后,其全体就叫做随机场。
马尔可夫随机场:
马尔科夫随机场是随机场的特例,它假设随机场中某一个位置的赋值仅仅与和它相邻的位置的赋值有关,和与其不相邻的位置的赋值无关。
条件随机场:
CRF是马尔科夫随机场的特例,它假设马尔科夫随机场中只有X和Y两种变量,X一般是给定的,而Y一般是在给定X的条件下我们的输出。
 
从上面的介绍我们能够看出,HMM与CRF在任务处理中有着类似的思想。
 
(2)HMM模型定义:
  • HMM模型描述的就是由隐状态序列(实体标记) 生成可观测状态(可读文本)的过程
举例分析:
假设这么一种情况,我们今天呆在家门不出去,不知道外面的天气情况,但是我们能通过邻居的穿衣多少情况来判断天气。这就是一种基于隐马尔可夫模型的例子。
在上述例子中:
  • 观测状态就是:衣服穿多少隐状态则是:今天的天气温度
  • 迁移到我们nlp领域就是,观测状态输入:一串可观测文本,输出则是:文本对应的状态序列。
如下图所示,它其实必须满足一个前提和两个假设:
前提:马尔可夫假设仅作用于状态序列

两个假设

假设1:当前状态Yt仅仅依赖于前一个状态Yt-1,连续多个状态构成隐马尔可夫链y

假设2:任意时刻的观测X只依赖于该时刻的状态Yt,与其他时刻的状态或观测独立无关

信息抽取(二)实体识别之经典方法介绍


重要要素
那么如何通过观测序列来得到状态序列呢?这就和三个重要矩阵相关。
1初始状态矩阵
系统启动时的第一个状态就叫做初始状态。以实体识别任务为例,Y1是第一个字的词性,它有四种可能的取值B,M,E,S,那么如果给定了先验pi,初始状态Y1的取值分布也就确定了。
2转移矩阵
Yt如何转移到Yt+1呢?根据马尔可夫假设,t+1时的状态仅仅取决于t时的状态,既然一共有N种状态,那么从状态Si到状态S的概率就构成了一个N*N的方阵,称为状态转移矩阵A。
信息抽取(二)实体识别之经典方法介绍

3发射矩阵
给定每种Y, x都是一个独立的离散型随机变量。假设观测x一共有M种可能的取值,由于Y共有N种,所以这些参数向量构成了N*M的矩阵,称为发射概率矩阵B。
 

信息抽取(二)实体识别之经典方法介绍

三个基本问题
已有要素:
  • 模型:(π, A, B)
  • 观测序列:O = (o1, o2, … ,oT)
  • 状态序列:I =(i1, i2, … , iT)

HMM是围绕以上关键要素进行问题阐述:
1概率计算问题:已知模型参数 ,和观测序列 , 计算观测序列出现的概率。以看病问题为例, 计算一个人连续出现 {正常,冷,头晕} 感觉的概率。
 
2预测问题:也叫做解码问题。已知模型参数和观测序列,计算该观测序列对应的最可能的状态序列。以村民看病问题为例,假设一个病人连续出现 {正常,冷,头晕} 的感觉,计算病人对应的最可能的健康状态序列。
 
3学习问题:已知观测序列,模型参数未知,推断模型参数。有两种可能的场景,一种是监督学习的场景,已知观测序列和对应的状态序列,推断模型参数,第二种是非监督学习的场景,只知道诸多观测序列,推断模型参数。
 
预测问题就是nlp中很重要的问题,实体识别也是借鉴其思想发展而来,其遵循如下流程:
  • 首先不考虑最大概率问题,先计算出联合概率p(x, y)
  • 在所有这些成对的x和y的概率里面找到最大的那个概率,也就意味着找到了给定观测序列x时最可能出现的隐状态序列y,这样问题就解决了
任务目标:
信息抽取(二)实体识别之经典方法介绍
分解目标

(1)先求p(y)

信息抽取(二)实体识别之经典方法介绍

信息抽取(二)实体识别之经典方法介绍
信息抽取(二)实体识别之经典方法介绍

(2)再求p(x|y)

信息抽取(二)实体识别之经典方法介绍

(3)CRF模型原理图:

信息抽取(二)实体识别之经典方法介绍


如上图所示,X为输入文本序列,也称观测序列Y是输出标签序列,也称状态序列
  • 我们能够看到CRFHMM模型十分相似,但有不同的是,每一个状态,都可以由每一个状态,都可以和整个观测序列X决定,即y3与X都相关。
  • 每一个状态,仅与它相邻的状态相关,即y2仅与y1和y3相关
 

计算公式:

信息抽取(二)实体识别之经典方法介绍

信息抽取(二)实体识别之经典方法介绍


转移特征函数:

信息抽取(二)实体识别之经典方法介绍   

转态特征函数:

信息抽取(二)实体识别之经典方法介绍

信息抽取(二)实体识别之经典方法介绍

……
t() 、s() 为指示函数, 表达式为True时返回1, 否则返回0,相当于0、1判断,这就类似于HMM的发射矩阵和转移矩阵。

模型应用
1、训练阶段(编码)
获得特征函数,并且根据训练集,使用一些最优化算法来迭代获得每个特征函数的权重;
 
2、预测阶段(解码)
根据特征函数及其权重,使用维特比算法,找到一条概率最高的标签路径;
 
维特比算法(代码)
定义:
一种用以选择最优路径动态规划算法,从开始状态后每走一步,记录到达该状态所有路径的最大概率值,最后以最大值为基准继续向后推进。最后再从结尾回溯最大概率, 也就是最有可能的最优路径。

信息抽取(二)实体识别之经典方法介绍


如以上图所示,现在的问题如下:
我们要求从init到end的最优序列,中间有4个时刻,每个时刻对应不同观测序列的概率,而每个时刻不同的观测标签有3个。
对应的解决思路
1、暴力解法:求所有路径中最优路径,最容易想到的就是暴力解法,直接把所有路径全部计算出来,然后找出最优的。这方法理论上是可行,但当序列很长时,时间复杂度很高。而且进行了大量的重复计算。
2、维特比解法:
  • viterbi算法是每次记录到当前时刻,每个观察标签的最优序列,同样以上图例子举例,假设我们在t3时刻已经保存了从0到t3时刻最佳路径,那么在t4时刻,只需要计算从t3到t4的最优就好了。
  • 每次只需要保存到当前位置最优路径,之后循环向后走。到结束时,从最后一个时刻的最优值回溯到开始位置,回溯完成后,这个从开始到结束的路径就是最优的。
 
简单计算
利用特征函数,每个节点值为:
sum(状态特征函数 * 其权重) + sum(转移特征函数 * 其权重)
 

信息抽取(二)实体识别之经典方法介绍

(4)CRF和HMM对比

二者的对比如下表所示,我们能够看出CRF有着更高的处理效能。

属性
CRF
HMM
建模范围
多,涵盖HMM的范围
特征集合
全局特征、广泛
局部特征、稀少
权重取值
任意权重值
受限于概率约束

4、基于深度学习的方法

深度学习也历经了传统深度学习预训练范式的转变,我们首先先介绍最经典的传统深度学习模型

(1)TEXTCNN模型

首先,先看由传统CNN演化的TEXTCNN模型,它的核心思想是使用不同尺寸的卷积核, 在文本序列上做一维卷积。
 

信息抽取(二)实体识别之经典方法介绍

由上图可知,整个网络分为4层:分别是Embedding层卷积层池化层全连接分类层

1、 Embedding层
  • 输入一句话,句长为7, embedding size为5,每个词被表示成一个5维的向量

2、卷积层

  • 卷积层拥有3种高度(2、3、4)的卷积核,表示捕获的上下文长度,类似于n-gram;

  • 卷积核的宽度都和词向量的大小(embedding size)一致;

  • 每种高度的卷积核,我们设置了2个卷积核,于是最终将拥有6个卷积核,每个卷积核提取不同的特征;

  • 每个卷积核在文本序列上滑窗,产生一个特征图(feature map)

3、池化层
  • 是一个1-max pooling,每个不等长的特征图被综合成一个数字,最后我们将6个数字拼接起来,形成一个6维的向量

4、全连接层
  • 我们使用一个6维的向量, 进行多分类, 使用softmax返回每个标签对应的概率;
 
2IDCNN模型(Iterated Dilated CNN,膨胀卷积网络)
首先,我们先看普通卷积层的思路,如下图所示,在两层卷积后,g3可以间接连接到5个输入。
 

信息抽取(二)实体识别之经典方法介绍

而在IDCNN, 可以分别设置膨胀宽度1、2、4, 跳跃部分输入,实现三层卷积,能够间接连接到15个输入。
 

信息抽取(二)实体识别之经典方法介绍

通过上述对比,我们能够发现膨胀卷积可以指数级增加网络的感受野,这也是IDCNN的核心,即不堆积更多层卷积的基础上,指数级扩大网络捕获上下文的能力
膨胀卷积使用原因:
  • 低效的池化层:由于序列标注里每个位置都对应一个标签, 针对特征图的池化会降低输出表示的精度,但不加池化层会使感受野变小,学不到全局的特征。如果我们单纯的去掉池化层、扩大卷积核的话,这样纯粹的扩大卷积核势必导致计算量的增大,此时最好的办法就是就是使用它所提出的膨胀卷积。
 
3Lattice LSTM
介绍了从CNN演化的经典模型后,再让我们看看RNN如何更好的匹配实体识别任务。
传统RNN的局限:
  • 传统的LSTM应用于中文任务时, 如下图所示,它的输入要么基于字切分,要么基于词切分。但是基于字的用不了词汇信息,基于词的可能存在分词误差,而分词误差对下游的NER影响是致命的。
 
信息抽取(二)实体识别之经典方法介绍

Lattice LSTM改进点
  • Lattice LSTM将词汇信息引入到基于字的LSTM中,如下图所示,将词汇单元增加到词尾位置,以“长江大桥”为例,“长江”,“长江大桥”,“大桥”就消除了实体“江大桥”的可能性。
 
信息抽取(二)实体识别之经典方法介绍
信息抽取(二)实体识别之经典方法介绍

  • 它对每个词构建词汇单元(Cell),将词汇Cell接入Char级别LSTM,从词首位置开始,到词尾位置终止。
 
信息抽取(二)实体识别之经典方法介绍

具体到模型层面时,我们可以对比一下传统LSTM单元Lattice LSTM词汇单元的内部结构:
  • 下图是词汇单元的结构,b、e分别表示词开始和词终止的位置;上标c、w分别表示字级别和词级别

实现流程:

  • 信息抽取(二)实体识别之经典方法介绍


信息抽取(二)实体识别之经典方法介绍

信息抽取(二)实体识别之经典方法介绍

4BiLSTM-CRF模型
首先由于深度学习模型可以自动学习到有区分性的特征,而机器学习模型能够从统计角度学习模型的规则特征,将两者结合能够取长补短,发挥模型更大的效能。
 
如下图的BiLSTM-CRF模型,它可以通过深度学习模型来获取特征,再通过CRF层学习统计层面中的句子依赖从而制定约束,排除不可能的结果。
我们可以类比一下各层的作用:
1、输入层(embedding层):
文本转化为字词向量序列,字词向量可以在事先训练好或随机初始化,在模型训练时还可以再训练。
2、特征抽取层
经BiLSTM特征提取,输出是每个单词对应的预测标签,这可以看作是CRF的发射概率
3、CRF约束层
CRF层能够学习到句子的前后依赖,从而加入一些约束来保证最终预测结果有效,这可以看作是状态概率
 
信息抽取(二)实体识别之经典方法介绍

5BERTBiLSTM-CRF模型

预训练模型实现了传统深度学习模型的跨越,它被证明能够学习到更多有用的语义信息,目前的研究多使用BERT模型的词向量作为embdding层的语义表示,在BERTBiLSTM-CRF中,与BiLSTM-CRF相比,它只是将输入的embedding层换成了BERT词向量,其余和BiLSTM-CRF基本保持一致。
 

信息抽取(二)实体识别之经典方法介绍

  • 需要注意的是,由于LSTM和BERT层承担的作用基本一致,都起到特征抽取的作用,在实际应用场景中,也可以去除LSTM层,直接将CRF接到BERT层后即可。
 

总结回顾:

本次分享中,从规则、机器学习、深度学习等角度对实体抽取的经典通用模型进行介绍,接下来我们的视角将关注实体抽取的嵌套、不连续等复杂问题的抽取。

 
核心代码如下:
(1)维特比解码:
 def _viterbi_decode(self, feats):        backpointers = []
# 在对数空间初始化维特比变量 init_vvars = torch.full((1, self.tagset_size), -10000.) init_vvars[0][self.tag_to_ix[START_TAG]] = 0
# 第i步的 forward_var 存放第i-1步的维特比变量 forward_var = init_vvars
for feat in feats: bptrs_t = [] # 存放这一步的后指针 viterbivars_t = [] # 存放这一步的维特比变量
for next_tag in range(self.tagset_size):
# next_tag_var[i] 存放先前一步标签i的维特比变量, 加上了从标签i到next_tag的转移 # (这里暂时没有将发射score添加进来,因为最大值并不依赖它们。我们下面会加它。) next_tag_var = forward_var + self.transitions[next_tag] best_tag_id = argmax(next_tag_var) bptrs_t.append(best_tag_id) viterbivars_t.append(next_tag_var[0][best_tag_id].view(1))
# 现在将所有发射score相加,更新forward_var forward_var = (torch.cat(viterbivars_t) + feat).view(1, -1) backpointers.append(bptrs_t)
# 转移到STOP_TAG terminal_var = forward_var + self.transitions[self.tag_to_ix[STOP_TAG]] best_tag_id = argmax(terminal_var) path_score = terminal_var[0][best_tag_id]
# 使用后指针解码最优路径 best_path = [best_tag_id] for bptrs_t in reversed(backpointers): best_tag_id = bptrs_t[best_tag_id] best_path.append(best_tag_id)
# 弹出开始标签,无需返回它 start = best_path.pop()
assert start == self.tag_to_ix[START_TAG] best_path.reverse() return path_score, best_path

2BiLSTM_CRF的模型定义部分:
class BiLSTM_CRF(nn.Module):
def __init__(self, vocab_size, tag_to_ix, embedding_dim, hidden_dim): """ :param vocab_size: 词库大小 :param tag_to_ix: tag id映射 :param embedding_dim: embedding维度 :param hidden_dim: 隐含层维度 """ super(BiLSTM_CRF, self).__init__() self.embedding_dim = embedding_dim self.hidden_dim = hidden_dim self.vocab_size = vocab_size self.tag_to_ix = tag_to_ix self.tagset_size = len(tag_to_ix) # 获得tag size
# 定义embedding层, # 设置 # 词库大小(输入序列的最大id不能超过它) # embedding维度(一个词被表示为向量的维度) self.word_embeds = nn.Embedding(vocab_size, embedding_dim)
# 定义lstm层, # 设置 # 输入dim为embedding_dim # 隐含层单元为 1/2 hidden_dim(双向拼接之后为hidden_dim,送入下一层) # 一层lstm # 设置双向 self.lstm = nn.LSTM(embedding_dim, hidden_dim // 2, num_layers=1, bidirectional=True)
# 将bilstm的输出通过全连接层映射到标签空间 self.hidden2tag = nn.Linear(hidden_dim, self.tagset_size)
# CRF层的核心参数,转移矩阵 # transitions[i,j]表示从j转移到i的score self.transitions = nn.Parameter( torch.randn(self.tagset_size, self.tagset_size) )
# 使不能出现 转移到START_TAG self.transitions.data[tag_to_ix[START_TAG], :] = -10000 # 使不能出现 从STOP_TAG转移 self.transitions.data[:, tag_to_ix[STOP_TAG]] = -10000

3Bert_BiLSTM_CRFModel的模型定义部分:
class BertBiLSTMCRFModel(nn.Module):
def __init__(self, bert_base_model_dir, label_size, drop_out_rate=0.5): super(BertCRFModel, self).__init__() self.label_size = label_size
if 'albert' in bert_base_model_dir.lower(): # 注意albert base使用bert tokenizer,参考https://huggingface.co/voidful/albert_chinese_base self.bert_tokenizer = BertTokenizer.from_pretrained(bert_base_model_dir) self.bert_model = AlbertModel.from_pretrained(bert_base_model_dir) elif 'electra' in bert_base_model_dir.lower(): self.bert_tokenizer = ElectraTokenizer.from_pretrained(bert_base_model_dir) self.bert_model = ElectraModel.from_pretrained(bert_base_model_dir) else: self.bert_tokenizer = BertTokenizer.from_pretrained(bert_base_model_dir) self.bert_model = BertModel.from_pretrained(bert_base_model_dir)
self.lstm=nn.LSTM(self.bert_model.config.hidden_size,384,num_layers=1, bidirectional=True,batch_first=True) ##双向lstm self.dropout = nn.Dropout(drop_out_rate) #self.linear = nn.Linear(self.bert_model.config.hidden_size, label_size) self.linear = nn.Linear(768, label_size)##bilstm层 self.crf = CRF(label_size) # # 定义CRF层
 

关于二范数智能:二范数AI教育是一家新锐的AI+科创公司,团队主要来自阿里巴巴,成员毕业于华科、武大、东南大学等知名高校。我们在自然语言处理、计算机视觉、推荐系统等领域有深厚的技术积累,同时也具备多年的教育经验。AI培训,我们是最专业的!


欢迎大家通过下面联系方式联系我们:

信息抽取(二)实体识别之经典方法介绍

原文始发于微信公众号(二范数智能):信息抽取(二)实体识别之经典方法介绍

版权声明:admin 发表于 2022年11月22日 下午9:01。
转载请注明:信息抽取(二)实体识别之经典方法介绍 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...