0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

命名实体识别实践 - CRF

深度学习自然语言处理 来源:ChallengeHub 作者:致Great 2022-03-24 13:42 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1

条件随机场-CRF

CRF,英文全称为Conditional Random Field, 中文名为条件随机场,是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫(Markov)随机场。

较为简单的条件随机场是定义在线性链上的条件随机场,称为线性链条件随机场(linear chain conditional random field)。

线性链条件随机场可以用于序列标注等问题,需要解决的命名实体识别(NER)任务正好可通过序列标注方法解决。

a98099ce-a359-11ec-952b-dac502259ad0.png

在条件概率模型P(Y|X)中,Y是输出变量,表示标记序列(或状态序列),X是输入变量,表示需要标注的观测序列。

训练时,利用训练数据集通过极大似然估计或正则化的极大似然估计得到条件概率模型p(Y|X);
预测时,对于给定的输入序列x,求出条件概率p(y|x)最大的输出序列y

利用线性链CRF来做实体识别的时候,需要假设每个标签 的预测同时依赖于先前预测的标签 和 的词语输入序列,如下图所示a999a4dc-a359-11ec-952b-dac502259ad0.png每个 NER标签仅依赖于其直接前前继和后继标签以及 x

CRF是一种选择因子的特定方式,换句话说,就是特征函数。定义因子的 CRF 方法是采用实值特征函数 与参数 和 的线性组合的指数,下面是特征函数与权重参数在时间步上是对应的:

关于Linear-chain CRF的训练推导,可以查看文章:条件随机场CRF(一)从随机场到线性链条件随机场

2

实践1:基于CRF++实现NER

CRF++简介

CRF++是著名的条件随机场的开源工具,也是目前综合性能最佳的CRF工具,采用C++语言编写而成。其最重要的功能我认为是采用了特征模板。这样就可以自动生成一系列的特征函数,而不用我们自己生成特征函数,我们要做的就是寻找特征,比如词性等。a9b5538a-a359-11ec-952b-dac502259ad0.png官网地址:http://taku910.github.io/crfpp/

安装

CRF++的安装可分为Windows环境和Linux环境下的安装。关于Linux环境下的安装,可以参考文章:CRFPP/CRF++编译安装与部署 。在Windows中CRF++不需要安装,下载解压CRF++0.58文件即可以使用

a9d1495a-a359-11ec-952b-dac502259ad0.png

训练语料创建

在训练之前需要将标注数据转化为CRF++训练格式文件:

分两列,第一列是字符,第二例是对应的标签,中间用 分割。

比如标注方案采用BISO,效果如下:

a9efe72a-a359-11ec-952b-dac502259ad0.png

模板

模板是使用CRF++的关键,它能帮助我们自动生成一系列的特征函数,而不用我们自己生成特征函数,而特征函数正是CRF算法的核心概念之一。一个简单的模板文件如下:aa0ca608-a359-11ec-952b-dac502259ad0.png在这里,我们需要好好理解下模板文件的规则。T**:%x[#,#]中的T表示模板类型,两个"#"分别表示相对的行偏移与列偏移。一共有两种模板:aa273c0c-a359-11ec-952b-dac502259ad0.png

训练

crf_learn-f3-c4.0-m100templatetrain.datacrf_model>train.rst

其中,template为模板文件,train.data为训练语料,-t表示可以得到一个model文件和一个model.txt文件,其他可选参数说明如下:

-f,–freq=INT使用属性的出现次数不少于INT(默认为1)

-m,–maxiter=INT设置INT为LBFGS的最大迭代次数(默认10k)

-c,–cost=FLOAT设置FLOAT为代价参数,过大会过度拟合(默认1.0)

-e,–eta=FLOAT设置终止标准FLOAT(默认0.0001)

-C,–convert将文本模式转为二进制模式

-t,–textmodel为调试建立文本模型文件

-a,–algorithm=(CRF|MIRA)选择训练算法,默认为CRF-L2

-p,–thread=INT线程数(默认1),利用多个CPU减少训练时间

-H,–shrinking-size=INT设置INT为最适宜的跌代变量次数(默认20)

-v,–version显示版本号并退出

-h,–help显示帮助并退出

输出信息

iter:迭代次数。当迭代次数达到maxiter时,迭代终止

terr:标记错误率

serr:句子错误率

obj:当前对象的值。当这个值收敛到一个确定值的时候,训练完成

diff:与上一个对象值之间的相对差。当此值低于eta时,训练完成

预测

在训练完模型后,我们可以使用训练好的模型对新数据进行预测,预测命令格式如下:

crf_test-mcrf_modeltest.data>test.rstt

-m model表示使用我们刚刚训练好的model模型,预测的数据文件为test.data> test.rstt 表示将预测后的数据写入到test.rstt 中。aa465aa6-a359-11ec-952b-dac502259ad0.png

3

实践2:基于sklearn_crfsuite实现NER

sklearn_crfsuite简介

sklearn-crfsuite是基于CRFsuite库的一款轻量级的CRF库。该库兼容sklearn的算法,因此可以结合sklearn库的算法设计实体识别系统。sklearn-crfsuite不仅提供了条件随机场的训练和预测方法还提供了评测方法。

https://sklearn-crfsuite.readthedocs.io/en/latest/#

aa5dd37a-a359-11ec-952b-dac502259ad0.png

安装:pip install sklearn-crfsuite

特征与模型创建

特征构造:aa777b72-a359-11ec-952b-dac502259ad0.png模型初始化

crf_model=sklearn_crfsuite.CRF(algorithm='lbfgs',c1=0.25,c2=0.018,max_iterations=100,
all_possible_transitions=True,verbose=True)
crf_model.fit(X_train,y_train)

完整代码如下:

importre
importsklearn_crfsuite
fromsklearn_crfsuiteimportmetrics
importjoblib
importyaml
importwarnings

warnings.filterwarnings('ignore')



defload_data(data_path):
data=list()
data_sent_with_label=list()
withopen(data_path,mode='r',encoding="utf-8")asf:
forlineinf:
ifline.strip()=="":
data.append(data_sent_with_label.copy())
data_sent_with_label.clear()
else:
data_sent_with_label.append(tuple(line.strip().split("")))
returndata

defword2features(sent,i):
word=sent[i][0]

features={
'bias':1.0,
'word':word,
'word.isdigit()':word.isdigit(),
}
ifi>0:
word1=sent[i-1][0]
words=word1+word
features.update({
'-1:word':word1,
'-1:words':words,
'-1:word.isdigit()':word1.isdigit(),
})
else:
features['BOS']=True

ifi>1:
word2=sent[i-2][0]
word1=sent[i-1][0]
words=word1+word2+word
features.update({
'-2:word':word2,
'-2:words':words,
'-3:word.isdigit()':word1.isdigit(),
})

ifi>2:
word3=sent[i-3][0]
word2=sent[i-2][0]
word1=sent[i-1][0]
words=word1+word2+word3+word
features.update({
'-3:word':word3,
'-3:words':words,
'-3:word.isdigit()':word1.isdigit(),
})

ifi< len(sent)-1:
        word1 = sent[i+1][0]
        words = word1 + word
        features.update({
            '+1:word': word1,
            '+1:words': words,
            '+1:word.isdigit()': word1.isdigit(),
        })
    else:
        features['EOS'] = True

    if i < len(sent)-2:
        word2 = sent[i + 2][0]
        word1 = sent[i + 1][0]
        words = word + word1 + word2
        features.update({
            '+2:word': word2,
            '+2:words': words,
            '+2:word.isdigit()': word2.isdigit(),
        })

    if i < len(sent)-3:
        word3 = sent[i + 3][0]
        word2 = sent[i + 2][0]
        word1 = sent[i + 1][0]
        words = word + word1 + word2 + word3
        features.update({
            '+3:word': word3,
            '+3:words': words,
            '+3:word.isdigit()': word3.isdigit(),
        })

    return features

def sent2features(sent):
    return [word2features(sent, i) for i in range(len(sent))]


def sent2labels(sent):
    return [ele[-1] for ele in sent]
train=load_data('data/train.txt')
valid=load_data('data/train.txt')
test=load_data('data/train.txt')
print(len(train),len(valid),len(test))

sample_text=''.join([c[0] for c in train[0]])
sample_tags=[c[1] for c in train[0]]
print(sample_text)
print(sample_tags)


X_train = [sent2features(s) for s in train]
y_train = [sent2labels(s) for s in train]

X_dev = [sent2features(s) for s in valid]
y_dev = [sent2labels(s) for s in valid]
# **表示该位置接受任意多个关键字(keyword)参数,在函数**位置上转化为词典 [key:value, key:value ]
crf_model = sklearn_crfsuite.CRF(algorithm='lbfgs',c1=0.25,c2=0.018,max_iterations=100,
                                 all_possible_transitions=True,verbose=True)
crf_model.fit(X_train, y_train)

训练效果如下:

labels=list(crf_model.classes_)
labels.remove("O")
y_pred=crf_model.predict(X_dev)
metrics.flat_f1_score(y_dev,y_pred,
average='weighted',labels=labels)
sorted_labels=sorted(labels,key=lambdaname:(name[1:],name[0]))
print(metrics.flat_classification_report(
y_dev,y_pred,labels=sorted_labels,digits=3
))
aa8c45de-a359-11ec-952b-dac502259ad0.png

完整代码 https://www.heywhale.com/home/competition/6216f74572960d0017d5e691/content/

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    风华电阻器命名规范解析

    在电子制造与维修领域,电阻器作为最基本的电子元器件之一,其命名规范对于元器件的选型、采购、库存管理以及应用都具有重要意义。风华电阻器作为国内知名的电阻器品牌,其命名规范遵循一定的行业标准和内部规则
    的头像 发表于 09-22 15:22 411次阅读
    风华电阻器<b class='flag-5'>命名</b>规范解析

    无人机智能巡检系统在违章建筑识别中的应用与实践

           无人机智能巡检系统在违章建筑识别中的应用与实践        无人机智能巡检系统集成了多项先进技术,构建了一套完整的违章建筑识别解决方案。该系统采用分层架构设计,包含数据采集层、传输层
    的头像 发表于 09-15 20:17 354次阅读

    Arm产品命名体系的演变

    继 Arm 首席执行官 Rene Haas 宣布 Arm 推出新的产品命名体系后,本文将为你详解新的计算平台名称,以及新命名体系内的新 IP 名称标识。
    的头像 发表于 06-19 10:38 779次阅读
    Arm产品<b class='flag-5'>命名</b>体系的演变

    PCB设计中的焊盘命名规范

    1.焊盘命名规范 获取完整文档资料可下载附件哦!!!!如果内容有帮助可以关注、点赞、评论支持一下哦~
    发表于 05-29 16:01

    旺诠合金电阻的命名规则

    旺诠合金电阻的命名规则相对严谨且包含丰富的信息,通常包括电阻值、精度、温度系数和功率等级等关键参数。以下是对旺诠合金电阻命名规则的详细解读: 一、电阻值 电阻值是电阻本身的物理特性,通常以欧姆
    的头像 发表于 05-20 11:22 476次阅读
    旺诠合金电阻的<b class='flag-5'>命名</b>规则

    顺络贴片电容规格都是怎么命名

    顺络贴片电容的规格命名通常包含一系列字符,这些字符用于标识电容的关键规格和属性。虽然不同制造商的命名规则可能有所不同,但一般来说,顺络贴片电容的命名规则可能包含以下参数: 1、尺寸:这部分通常
    的头像 发表于 04-29 15:31 816次阅读
    顺络贴片电容规格都是怎么<b class='flag-5'>命名</b>的

    【「# ROS 2智能机器人开发实践」阅读体验】+ROS2应用案例

    的知识,还需要对ROS 2的节点通信和数据处理有一定的了解。通过实践这一部分内容,我掌握了如何在ROS 2中实现二维码识别,这对于提高机器人的智能性和交互性具有重要意义。 地图构建:SLAM技术
    发表于 04-27 11:42

    风华电容命名方法深度解析

    在电子元器件领域,风华电容凭借其清晰的命名体系、全面的技术参数和广泛的应用场景,成为国内外市场的标志性品牌。本文将从命名规则、技术参数、行业应用及市场优势四个维度,深度解析风华电容的技术特性
    的头像 发表于 04-11 11:58 1054次阅读

    EMC电机控制器测试整改:从问题识别到优化实践

    深圳南柯电子|EMC电机控制器测试整改:从问题识别到优化实践
    的头像 发表于 03-20 09:34 749次阅读
    EMC电机控制器测试整改:从问题<b class='flag-5'>识别</b>到优化<b class='flag-5'>实践</b>

    PCB最全封装命名规范

    范围本规范适用于主流EDA软件在PCB设计前的封装建库命名。 获取完整文档资料可下载附件哦!!!!
    发表于 03-12 13:26

    AI开发者实践|多宠识别开启科技养宠新时代

    随着越来越多的家庭饲养多只宠物,传统智能喂食器的单一识别功能,已难以满足用户需求。如何确保每只宠物都能公平进食?如何实时了解不同宠物的健康状况?如何通过信息分析优化喂养策略?这些问题正深深困扰着养
    的头像 发表于 02-13 20:58 1080次阅读
    AI开发者<b class='flag-5'>实践</b>|多宠<b class='flag-5'>识别</b>开启科技养宠新时代

    BEM+Sass结合使用的最佳实践

    和开发效率。 一、BEM命名规范 块(Block) :代表页面中的独立组件或模块,具有独立的样式和功能。块名应简洁明了,易于识别。 元素(Element) :块内部的组成部分,与块有直接的从属关系。元素名应使用双下划线(__)与块名连接。 修饰符(Modifier) :用
    的头像 发表于 02-12 16:50 956次阅读

    做ADS解码专用 实践ADS1605

    实践ADS1605 因为设计要做ADS解码专用,所以找来找去用到了ADS1605这个芯片,并口设计,信号可以识别小信号的。 因为买的是专业板子,所以上面都集成好了。 板子流程图。 用到解码流程图 效果还不错,就是数据容易受到干扰的。
    发表于 01-21 07:58

    【实战】人工智能0基础入门:基于Python+OpenCV的车牌识别项目(课程+平台实践

    01引言随着智能交通系统的发展,车牌识别技术在车辆管理、交通监控、停车收费等多个领域发挥着重要作用。接下来小编将带你深入了解车牌识别项目的全流程,从理论基础到实际应用,让你掌握如何构建一个高效、准确
    的头像 发表于 12-16 10:43 1177次阅读
    【实战】人工智能0基础入门:基于Python+OpenCV的车牌<b class='flag-5'>识别</b>项目(课程+平台<b class='flag-5'>实践</b>)

    SMA连接器的完整名称及其命名由来

    世纪60年代被开发出来,专为微波应用设计,其特点在于小型化和高性能,适用于高频传输  命名由来  SMA连接器的命名遵循了射频同轴连接器的命名规则,其中“Su
    的头像 发表于 12-12 11:12 1785次阅读
    SMA连接器的完整名称及其<b class='flag-5'>命名</b>由来