实现spaCy实体标注模型
命名实体识别是指对现实世界中某个对象的名称的识别。与词性标注一样,是自然语言处理的技术基础之一。它的作用主要是通过模型识别出文本中需要的实体,也可以推导出实体之间的关系(实体消歧)。
本文介绍的是运用Python从头训练一个spaCy模型来识别中标公告中中标公司的名字,现通过爬虫爬取了大约200篇中标公告(爬取过程省略),利用人工对其中的150篇训练集公告进行标注中标公司,使用spaCy训练一个实体抽取模型并进行本地保存,再调取训练好的模型对剩余的50篇公告进行测试,检验该模型对中标公司提取的准确率。
1、获取数据和数据清洗
首先,需要对爬取下来的中标公告文件数据进行清洗处理,分别对其进行去重和删除网络格式(比如 ),清洗前后对比如下:

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实体标注模型的更多相关文章
- BiLstm与CRF实现命名实体标注
众所周知,通过Bilstm已经可以实现分词或命名实体标注了,同样地单独的CRF也可以很好的实现.既然LSTM都已经可以预测了,为啥要搞一个LSTM+CRF的hybrid model? 因为单独LSTM ...
- 基于keras的BiLstm与CRF实现命名实体标注
众所周知,通过Bilstm已经可以实现分词或命名实体标注了,同样地单独的CRF也可以很好的实现.既然LSTM都已经可以预测了,为啥要搞一个LSTM+CRF的hybrid model? 因为单独LSTM ...
- 数据库 之 E-R实体关系模型
E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. 1.表示方法 E-R是描述现实世界概念结构模型的 ...
- .NET使用DAO.NET实体类模型操作数据库
一.新建项目 打开vs2017,新建一个项目,命名为orm1 二.新建数据库 打开 SqlServer数据库,新建数据库 orm1,并新建表 student . 三.新建 ADO.NET 实体数据模型 ...
- powerdesigner 实体关系模型CDM与物理数据模型PDM互转
1.创建CDM 2.CDM转换PDM 3.PDM转CDM 环境 powerdesigner15.1 1.创建CDM File --> new Model-->Conceptual data ...
- 使用modelarts部署bert命名实体识别模型
模型部署介绍 当我们通过深度学习完成模型训练后,有时希望能将模型落地于生产,能开发API接口被终端调用,这就涉及了模型的部署工作.Modelarts支持对tensorflow,mxnet,pytorc ...
- 通俗理解BiLSTM-CRF命名实体识别模型中的CRF层
虽然网上的文章对BiLSTM-CRF模型介绍的文章有很多,但是一般对CRF层的解读比较少. 于是决定,写一系列专门用来解读BiLSTM-CRF模型中的CRF层的文章. 我是用英文写的,发表在了gith ...
- bi-Lstm +CRF 实现命名实体标注
1. https://blog.csdn.net/buppt/article/details/82227030 (Bilstm+crf中的crf详解,包括是整体架构) 2. 邹博关于CRF的讲解视频 ...
- DL4NLP —— 序列标注:BiLSTM-CRF模型做基于字的中文命名实体识别
三个月之前 NLP 课程结课,我们做的是命名实体识别的实验.在MSRA的简体中文NER语料(我是从这里下载的,非官方出品,可能不是SIGHAN 2006 Bakeoff-3评测所使用的原版语料)上训练 ...
随机推荐
- eclipse中lombok注解不生效
现象:eclipse中在对象上使用lombok的@Data,引用get方法时,没有set.get方法. 解决办法: 1.在lombok官网(https://www.projectlombok.org/ ...
- Python爬虫系统学习(1)
Python爬虫系统化学习(1) 前言:爬虫的学习对生活中很多事情都很有帮助,比如买房的时候爬取房价,爬取影评之类的,学习爬虫也是在提升对Python的掌握,所以我准备用2-3周的晚上时间,提升自己对 ...
- 适配三星Galaxy S8及S8+ 屏幕比例为 18.5:9
开发者只需在App的AndroidManifest.xml文件<application> </application>中添加如下代码: <meta-data androi ...
- Spring IoC总结
Spring 复习 1.Spring IoC 1.1 基本概念 1.1.1 DIP(Dependency Inversion Principle) 字面意思依赖反转原则,即调用某个类的构造器创建对象时 ...
- Python列表元组和字典解析式
目录 列表解析式List comprehensive 集合解析式Set comprehensive 字典解析式Dict comprehensive 总结 以下内容基于Python 3x 列表解析式Li ...
- MySQL全面瓦解25:构建高性能索引(案例分析篇)
回顾一下上面几篇索引相关的文章: MySQL全面瓦解22:索引的介绍和原理分析 MySQL全面瓦解23:MySQL索引实现和使用 MySQL全面瓦解24:构建高性能索引(策略篇) 索引的十大原则 1. ...
- 2018.8.30 nowcoder oi赛制测试1
2018.8.30 nowcoder oi赛制测试1 普及组难度,发现了一些问题 A 题目大意:求斐波那契数列\(f(k-1)f(k+1)-f(k)^2\),范围极大 打表可得规律 其实是卡西尼恒等式 ...
- android消息线程和消息队列
基于消息队列的线程通信: 消息队列与线程循环 MessageQueue: 利用链表来管理消息. Mess ...
- WorkSkill整理之 技能体系
- Codeforces Round #546 C. Nastya Is Transposing Matrices
题面: 传送门 题目描述: 给出两个n x m的矩阵A,B.矩阵A可以把正方子矩阵进行"转置操作",问:可不可以对矩阵A进行多次这样的操作,使矩阵A变为矩阵B? 题目分析: 这 ...