命名实体识别是指对现实世界中某个对象的名称的识别。与词性标注一样,是自然语言处理的技术基础之一。它的作用主要是通过模型识别出文本中需要的实体,也可以推导出实体之间的关系(实体消歧)。

本文介绍的是运用Python从头训练一个spaCy模型来识别中标公告中中标公司的名字,现通过爬虫爬取了大约200篇中标公告(爬取过程省略),利用人工对其中的150篇训练集公告进行标注中标公司,使用spaCy训练一个实体抽取模型并进行本地保存,再调取训练好的模型对剩余的50篇公告进行测试,检验该模型对中标公司提取的准确率。

1、获取数据和数据清洗

首先,需要对爬取下来的中标公告文件数据进行清洗处理,分别对其进行去重和删除网络格式(比如&nbsp),清洗前后对比如下:

2、标注实体

对于清洗后的数据集,需要把标注后的结果以下例格式进行储存(即文本+实体标注的索引+实体标注类别标签):

TRAIN_DATA = [
('Who is Shaka Khan?', {
'entities': [(7, 17, 'PERSON')]
###实体标注的索引从0开始17是最后一字符的索引+1
}),
('I like London and Berlin.', {
'entities': [(7, 13, 'LOC'), (18, 24, 'LOC')]
})
]

也就是说,需要找出需要被标注实体的开始索引和结束索引。由于有204篇公告,每篇公告都都需要人工标注,鉴于数据量和寻找索引工作量都很大,所以通过编写Python程序且小组分工后每位成员人工标注中标公司名称,并把结果储存成上述格式。标注代码如下:

import pandas as pd
import re def find_company_name(name,text):
if re.search(name,text):
tup = list(re.search(name,text).span())
tup.append("LOC")
tup=tuple(tup)
return (text,{'entities':tup})
return False
from IPython.display import clear_output as clear

textall= []
data5 = pd.read_csv("home_work_clear.txt",encoding="utf-8",sep="\n",header=None)
start=int(input("请输入第几行开始"))
end=int(input("请输入第几行结束")) for line in data5[0][start:end]:
clear()#清除输出
print(line)
while True:
panduan="not break"
company_name = input("请输入公司名字")
if find_company_name(company_name,line):
print(find_company_name(company_name,line))
textall.append(find_company_name(company_name,line))
break
elif company_name == "break":
panduan='break'
break
else:
print("输入公司名字可能有误,重新输入")
print
if panduan=="break":
break f = open("result%d-%d.txt" % (start,end),"w+",encoding="gbk")
f.write(str(textall))
f.close()

(1)首先输入需要标注的开始位置和结束位置:

(2)然后输入每份公告的中标公司名称:

(3)最后,把标注后的结果保存到txt中:



上图表示文本中索引121-133为中标公司。

3、划分训练集和测试集

经标注后,一共有204个数据集,其中设定训练集150篇公告,测试集为54篇公告:

4、spaCy模型训练

对于处理好的训练集,输入到spaCy模型中进行训练,并对训练后的模型进行保存,代码如下:

def main(model=None, output_dir = None, n_iter=100):   ##参数意义,model:是否存在现有的模型,output_dir:模型存储位置,n_iter迭代次数
"""Load the model, set up the pipeline and train the entity recognizer."""
if model is not None:
nlp = spacy.load(model) # load existing spaCy model ###这里的作用是对现有的模型进行优化 *非常重要
print("Loaded model '%s'" % model)
else:
nlp = spacy.blank('zh') # create blank Language class
print("Created blank 'zh' model") if 'ner' not in nlp.pipe_names:
ner = nlp.create_pipe('ner')
nlp.add_pipe('ner', last=True)
# otherwise, get it so we can add labels
else:
ner = nlp.get_pipe('ner') # add labels
for _, annotations in TRAIN_DATA: ##添加train data的标签
for ent in annotations.get('entities'):
ner.add_label(ent[2]) other_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'ner']
with nlp.disable_pipes(*other_pipes): # 仅训练我们标注的标签,假如没有则会对所有的标签训练,
#建议不要对下载的spacy的模型进行训练可能导致下载的语言模型出错,训练一个空白语言模型就好
optimizer = nlp.begin_training() ##模型初始化
for itn in range(n_iter):
random.shuffle(TRAIN_DATA) ##训练数据每次迭代打乱顺序
losses = {} ##定义损失函数
for text, annotations in TRAIN_DATA:
example = Example.from_dict(nlp.make_doc(text), annotations) ##对数据进行整理成新模型需要的数据
print("example:",example)
nlp.update(
[example], # batch of annotations
drop=0.5, # dropout - make it harder to memorise data
sgd=optimizer, # 更新权重
losses=losses)
print(losses) # 保存模型
if output_dir is not None:
output_dir = Path(output_dir)
if not output_dir.exists():
output_dir.mkdir()
nlp.to_disk(output_dir)
print("Saved model to", output_dir)

对上述训练过程进行计时,由于代码运行时间过久,测试得当训练5个数据集需要花费差不多1分钟的时间:



通过检查发现代码中的迭代次数为100,为了提高速度把100改为了50,训练150个训练集,花费时间为(约47分钟):

并把训练好的模型保存到本地,方便后续测试时可以直接加载已训练好的模型得出预测结果。

5、测试集测试模型

训练完spaCy模型后,导入测试数据进行测试,代码如下:

import spacy

def load_model_test(path,text):
nlp = spacy.load(path)
print("Loading from", path)
doc = nlp(text)
for i in doc.ents:
print(i.text,i.label_)

训练结果如下:



根据上图测试结果来看,总体预测结果良好,能准确找出中标公司名称。但是,也存在少许预测失败的数据,说明该模型还不是非常精确,后续可以在迭代次数和训练数据量两方面进行改进。

实现spaCy实体标注模型的更多相关文章

  1. BiLstm与CRF实现命名实体标注

    众所周知,通过Bilstm已经可以实现分词或命名实体标注了,同样地单独的CRF也可以很好的实现.既然LSTM都已经可以预测了,为啥要搞一个LSTM+CRF的hybrid model? 因为单独LSTM ...

  2. 基于keras的BiLstm与CRF实现命名实体标注

    众所周知,通过Bilstm已经可以实现分词或命名实体标注了,同样地单独的CRF也可以很好的实现.既然LSTM都已经可以预测了,为啥要搞一个LSTM+CRF的hybrid model? 因为单独LSTM ...

  3. 数据库 之 E-R实体关系模型

    E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. 1.表示方法 E-R是描述现实世界概念结构模型的 ...

  4. .NET使用DAO.NET实体类模型操作数据库

    一.新建项目 打开vs2017,新建一个项目,命名为orm1 二.新建数据库 打开 SqlServer数据库,新建数据库 orm1,并新建表 student . 三.新建 ADO.NET 实体数据模型 ...

  5. powerdesigner 实体关系模型CDM与物理数据模型PDM互转

    1.创建CDM 2.CDM转换PDM 3.PDM转CDM 环境 powerdesigner15.1 1.创建CDM File --> new Model-->Conceptual data ...

  6. 使用modelarts部署bert命名实体识别模型

    模型部署介绍 当我们通过深度学习完成模型训练后,有时希望能将模型落地于生产,能开发API接口被终端调用,这就涉及了模型的部署工作.Modelarts支持对tensorflow,mxnet,pytorc ...

  7. 通俗理解BiLSTM-CRF命名实体识别模型中的CRF层

    虽然网上的文章对BiLSTM-CRF模型介绍的文章有很多,但是一般对CRF层的解读比较少. 于是决定,写一系列专门用来解读BiLSTM-CRF模型中的CRF层的文章. 我是用英文写的,发表在了gith ...

  8. bi-Lstm +CRF 实现命名实体标注

    1. https://blog.csdn.net/buppt/article/details/82227030 (Bilstm+crf中的crf详解,包括是整体架构) 2. 邹博关于CRF的讲解视频 ...

  9. DL4NLP —— 序列标注:BiLSTM-CRF模型做基于字的中文命名实体识别

    三个月之前 NLP 课程结课,我们做的是命名实体识别的实验.在MSRA的简体中文NER语料(我是从这里下载的,非官方出品,可能不是SIGHAN 2006 Bakeoff-3评测所使用的原版语料)上训练 ...

随机推荐

  1. IDEA重新安装之后配置GIT

    注:此方法可用于配置gitlab也可用于配置github 1.在github中创建一个账号:https://github.com/join?source=header-home 2.下载并安装git: ...

  2. 【Notes_8】现代图形学入门——几何(基本表示方法、曲线与曲面)

    几何 几何表示 隐式表示 不给出点的坐标,给数学表达式 优点 可以很容易找到点与几何之间的关系 缺点 找某特定的点很难 更多的隐式表示方法 Constructive Solid Geometry .D ...

  3. Vue框架:vue-cookies组件

    目录 一.vue-cookies简介 二.vue-cookies安装与配置 三.vue-cookies的使用 一.vue-cookies简介 vue-cookies组件是vue框架用来操作浏览器coo ...

  4. Virtual DOM 简直就是挥霍

    彻底澄清"Virtual DOM 飞快"的神话. 注意:原文发表于2018-12-27,随着框架不断演进,部分内容可能已不适用. 近年来,如果你有使用过 JavaScript 框架 ...

  5. Android7.0无需FileProvide搞定URI拍照、应用安装问题

    根据官方文档,从Android7.0版本开始 使用URI打开或安装文件需要单独在应用里配置了,问了度娘,有好多版本的结果,个人认为最靠谱的就是下边这个方法,只需在application的oncreat ...

  6. 身份认证:JSON Web Token

    JSON Web Token(JWT)是一种基于JSON的开放标准((RFC 7519),也是目前最流行的跨域认证解决方案. 传统的 cookie 认证方式看起来遵守了 REST 架构的无状态要求,但 ...

  7. 树莓派4B安装官方Ubuntu20 Server版(64位)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. C++的标识符的作用域与可见性

    下面是关于C++的标识符的作用域与可见性学习记录,仅供参考 标识符的作用域与可见性 作用域是一个标识符在程序正文中有效的区域. 作用域分类 ①函数原型作用域 ②局部作用域(快作用域) ③类作用域 ④文 ...

  9. BERT 服务化 bert-as-service

    bert-as-service 用 BERT 作为句子编码器, 并通过 ZeroMQ 服务托管, 只需两行代码就可以将句子映射成固定长度的向量表示; 准备 windows10 + python3.5 ...

  10. WebService和Web API 区别

    WebService的特征: 1 基于SOAP协议的,数据格式为XML 2 只支持HTTP协议,只能部署在IIS上 3 不是开源的,但可以被任意一个了解XML的人使用 SOAP :简单对象访问协议Si ...