CRF++训练中文命名实体识别
本文不涉及任何知识点的介绍,有兴趣自行查询。完全从小白到命名实体识别训练
参考文章如下:
python CRF中文分词(crf++工具)
用CRF做命名实体识别(一)
CRF++使用简介(windows下非接口)
【实战】运用CRF++进行实体识别实战
windows 用户 crfpp 安装以及导入到 python
本文仅做学习使用,若侵权,留言秒删,
1、首先创建语料
以十个数学题目为例,文本以txt形式保存:
文本自取:链接:https://pan.baidu.com/s/1o45y3xgtnyfifuC3c7e9fQ
提取码:ho22
内容如下图,每一个题目为一行,并对需要识别的语料打上标签,左右以空格隔开:
然后通过以下代码将语料转换为CRF++能够识别的文本形式,文本以data形式保存:
import codecs
def character_tagging(input_file, output_file):
input_data = codecs.open(input_file, 'r', 'utf-8')
output_data = codecs.open(output_file, 'w', 'utf-8')
for line in input_data.readlines():
word_list = line.strip().split()
for word in word_list:
if "/" in word:
word_lines = word.split("/")
output_data.write(word_lines[0][0] + "\tB_%s\n" % word_lines[1])
for w in word_lines[0][1:len(word_lines[0]) - 1]:
output_data.write(w + "\tM_%s\n" % word_lines[1])
output_data.write(word_lines[0][len(word_lines[0]) - 1] + "\tE_%s\n" % word_lines[1])
else:
for w in word:
output_data.write(w + "\tO\n")
output_data.write('\n')
input_data.close()
output_data.close()
if __name__ == "__main__":
input_file = r"train_data.txt"
output_file = r"train.data"
character_tagging(input_file, output_file)
文本保存形式如下并命名为train.data:
所有的十个题目进行转换后保存进一个文本里面,并且每行只有一个(标签除外)
O:表示其他、B:表示实体开始、M:表示实体中间、E:表示实体结束(这里有涉及相关知识点,自行查阅)
2、下载CRF++0.58
链接:https://pan.baidu.com/s/1YwVmt5cBzrRX6L1T_VX5-Q
提取码:6n36
文件夹格式如下,随便你放那个盘,(这里不对这些内容作介绍,自行了解):
并在该文件夹下创建新的文件夹命名为chinese(或者其他地方其他名字,无所谓),下面图中下半部分标记的文件复制后拖入chinese文件夹中:
以及在chinese文件夹将template文本创建(不要txt,data等格式,文本输入template后直接保存),内容如下(为什么这个样子,有兴趣自行查阅):
# Unigram
U01:%x[-1,0]
U02:%x[0,0]
U03:%x[1,0]
U04:%x[2,0]
U05:%x[-2,0]
U06:%x[0,0]/%x[-1,0]
U07:%x[0,0]/%x[1,0]
U08:%x[-1,0]/%x[-2,0]
U09:%x[1,0]/%x[2,0]
U10:%x[-1,0]/%x[1,0]
# Bigram
B
最后将前面的train.data拖入chinese文件夹后,里面的内容如下:
3、训练
输入win+r输入cmd或者shift+右击打开powershell输入cd …/chinese命名行,并输入如下命名:
crf_learn template train.data model 更改为 .\crf_learn template train.data model
将出现如下错误:
按提示更改:
最后文件夹下生成model文件:
建立新文件夹(命名自己想)将model文件拖进去,并创建如下py文件(这里涉及CRFPP的windows版本安装,请自行百度):
import CRFPP
import sys
import re
class crf_ner:
def __init__(self,model_path):
self.model_path = model_path
self.tagger = self.load_model()
def load_model(self):
cmd = '-m' + ' ' + self.model_path + ' ' + '-v 3 -n2'
try:
tagger = CRFPP.Tagger(cmd)
except RuntimeError as e:
print("RuntimeError: ", e)
tagger.clear()
return tagger
def parase_sentence(self,sentence):
assert len(sentence) > 0
for word in sentence:
self.tagger.add(word)
self.tagger.parse()
size = self.tagger.size()
x_size = self.tagger.xsize()
res = []
words = ""
label = ""
for i in range(0,size):
for j in range(0,x_size):
char = self.tagger.x(i,j)
tag = self.tagger.y2(i)
# print('char ' + char)
# print('tag ' + tag)
if tag[0] == 'B':
label = re.sub('B_','',tag)
words = char
elif tag[0] == 'M':
words+=char
elif tag[0] == 'E':
words += char
res.append((words, label))
label = ''
words = ''
elif tag[0] == 'S':
label = re.sub('S_', '', tag)
res.append((char, label))
label = ""
else:
continue
if words:
res.append((words,label))
self.tagger.clear()
return res
if __name__ == '__main__':
crfpp_ner = crf_ner('model') #model路径改为自己的model路径
string = '在三角形ABC中,AB垂直于BC,AB=3,BC=4,求该三角形的面积'
ret = crfpp_ner.parase_sentence(string)
print(ret)
运行后会生成如下结果:
表明初步运行成功,进阶的我也还走完,里面的知识点我也不明白。
可能有些朋友会需要到model文件,这里贴出百度链接:https://pan.baidu.com/s/1lKl0edbOi8Xgmt7muL2kdw
提取码:1xyc
由于最近主要方向没有在NER方向,有疑问的小伙伴可以私信我问题,如果有需要我可以再进一步去学习该方向的知识,然后整理好发布出来。