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/

审核编辑 :李倩

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

    评论

    相关推荐

    台湾华科贴片电容的命名及封装

    台湾华科(YAGEO)贴片电容的命名规则及封装方式相对复杂但富有逻辑性,以下是对其命名规则及封装方式的详细归纳: 命名规则 台湾华科贴片电容的命名通常包含多个部分,每个部分代表不同的信
    的头像 发表于 11-13 14:59 119次阅读
    台湾华科贴片电容的<b class='flag-5'>命名</b>及封装

    风华贴片瓷介电容型号识别命名方法

    风华贴片瓷介电容的型号识别命名方法主要包括以下几个关键部分,以下将按照清晰的结构进行分点表示和归纳: 1、封装尺寸 : 常见的封装尺寸包括0201、0402、0603、0805、1206等,这些
    的头像 发表于 11-05 16:16 103次阅读
    风华贴片瓷介电容型号<b class='flag-5'>识别</b>及<b class='flag-5'>命名</b>方法

    nlp自然语言处理的主要任务及技术方法

    (Tokenization)、词性标注(Part-of-Speech Tagging)和命名实体识别(Named Entity Recognition)等子任务。 1.1.1 分词(T
    的头像 发表于 07-09 10:26 817次阅读

    llm模型有哪些格式

    Representations from Transformers):BERT是一种双向预训练模型,通过大量文本数据进行预训练,可以用于各种NLP任务,如文本分类、问答、命名实体识别等。 b. GPT(
    的头像 发表于 07-09 09:59 530次阅读

    【大语言模型:原理与工程实践】大语言模型的应用

    操作。所谓零样本提示(Zero-Shot Prompt),指的是在提示词中不包含与指令任务相似的任何示例。 当大语言模型训练完成后,它便具备了分析情绪和识别命名实体等常见任务的能力,这些能力源于预训练
    发表于 05-07 17:21

    【大语言模型:原理与工程实践】探索《大语言模型原理与工程实践》2.0

    《大语言模型“原理与工程实践”》是关于大语言模型内在机理和应用实践的一次深入探索。作者不仅深入讨论了理论,还提供了丰富的实践案例,帮助读者理解如何将理论知识应用于解决实际问题。书中的案例分析有助于
    发表于 05-07 10:30

    苹果ReALM模型在实体识别测试中超越OpenAI GPT-4.0

    “我们的模型在识别各种类型实体方面都有显著提升,即使是小尺寸模型,在屏幕实体识别准确性上也已超过原有的系统5%以上。在与GPT-3.5和GPT-4.0的比较中,小型模型与GPT-4.0
    的头像 发表于 04-02 11:23 410次阅读

    柏恩Bourns推出全新CRF CRF系列大电流金属条Jumper

    美国柏恩 Bourns 全球知名电源、保护和传感解决方案电子组件领导制造供货商,推出全新 CRF CRF 系列大电流金属条 Jumper。
    的头像 发表于 03-21 14:07 362次阅读

    ST25DV04可以读取实体IC卡吗?

    我最近打算使用ST25DV04做一个NFC卡,这款芯片可以读取实体IC卡,获取IC卡信息,并模拟IC卡刷卡吗?
    发表于 03-18 07:04

    陀螺仪实体和支持有什么区别

    陀螺仪实体和支持之间存在着一些区别。陀螺仪实体是指由物理材料构成的实际设备,而支持是指陀螺仪实体所具备的技术、算法、软件和硬件的功能和特性。下面将从不同的方面详细讨论陀螺仪实体和支持之
    的头像 发表于 01-02 14:47 1802次阅读

    了解SiC器件的命名规则

    了解SiC器件的命名规则
    的头像 发表于 11-27 17:14 792次阅读
    了解SiC器件的<b class='flag-5'>命名</b>规则

    python变量命名规则

    的规则和约定。本文将详尽、详实、细致地探讨Python变量的命名规则,帮助读者了解如何正确命名变量并在编程中遵循最佳实践。 一、变量命名规则的重要性 合适的变量
    的头像 发表于 11-23 15:44 1189次阅读

    英飞凌IGBT模块命名规则

    英飞凌IGBT模块命名规则
    的头像 发表于 11-23 09:09 1548次阅读
    英飞凌IGBT模块<b class='flag-5'>命名</b>规则

    英飞凌IGBT单管命名规则

    英飞凌IGBT单管命名规则
    的头像 发表于 11-23 09:09 1319次阅读
    英飞凌IGBT单管<b class='flag-5'>命名</b>规则

    实体电源电路设计案例

    电子发烧友网站提供《实体电源电路设计案例.doc》资料免费下载
    发表于 11-20 10:58 6次下载
    <b class='flag-5'>实体</b>电源电路设计案例