【windows下CRF++的安装与使用】
###一、CRF++工具包的下载与安装
CRF 的工具有两种,一种是支持Linux环境的,一种是支持Windows环境的,大家可以自行根据自己的系统进行下载。
CRF++0.58资源链接:https://pan.baidu.com/s/1GKjKYSsgw46pLqjyMwf23A 密码:oj1q
在windows下安装很简单,解压到某目录下即可。
在此附CRF理论及工具包的使用讲解:https://wenku.baidu.com/view/5f805e0d8762caaedd33d491.html
windows下解压得到如下:
- doc文件夹:就是官方主页的内容
- example文件夹:有四个任务的训练数据(test.data)、测试数据(train.data)和模板文件(template),还有一个执行脚本文件exec.sh。
- sdk文件夹:CRF++的头文件和静态链接库。
- clr_learn.exe:CRF++的训练程序
- crl_test.exe:CRF++的测试程序
- libcrffpp.dll:训练程序和测试程序需要使用的静态链接库。
- 实际上,需要使用的就是crf_learn.exe,crf_test.exe和libcrfpp.dll,这三个文件。
###2 测试和体验
在源码包中有example,可以执行./exec.sh体验一下(Linux下的操作)
exec.sh #训练和测试脚本
template #模板文件
test.data #测试文件
train.data #训练文件
###3.生成训练数据【中文】
下载人民日报语料,对于语料有嵌套的标注,例如:[中央/n 电视台/n]nt,为了处理方便,只考虑最细粒度的分词结果,即当作是 中央/n 电视台/n 两个词进行处理。
通过下面python脚本,根据人民日报的语料库生成crf的测试和训练数据。原始数据中随机10%是测试数据,90%是训练数据。
两种格式:
6tag:S,单个词;B,词首;E,词尾;M1/M2/M,词中
4tag:S,单个词;B,词首;E,词尾;M,词中
运行Python脚本示例:
C:\Users\Administrator>python F:\pycodes\NLP\trainDataGenerate.py 4
其中参数4是传给了sys.argv[1] ,原因见:Python中 sys.argv[]的用法简明解释,因此执行main方法中的else部分。
# -*- coding: utf8 -*-
import sys
home_dir = "F:/pycodes/NLP/people_daily//"
def splitWord(words):
uni = words.decode('utf-8')
li = list()
for u in uni:
li.append(u.encode('utf-8'))
return li
#4 tag
#S/B/E/M
def get4Tag(li):
length = len(li)
#print length
if length == 1:
return ['S']
elif length == 2:
return ['B','E']
elif length > 2:
li = list()
li.append('B')
for i in range(0,length-2):
li.append('M')
li.append('E')
return li
#6 tag
#S/B/E/M/M1/M2
def get6Tag(li):
length = len(li)
#print length
if length == 1:
return ['S']
elif length == 2:
return ['B','E']
elif length == 3:
return ['B','M','E']
elif length == 4:
return ['B','M1','M','E']
elif length == 5:
return ['B','M1','M2','M','E']
elif length > 5:
li = list()
li.append('B')
li.append('M1')
li.append('M2')
for i in range(0,length-4):
li.append('M')
li.append('E')
return li
def saveDataFile(trainobj,testobj,isTest,word,handle,tag):
if isTest:
saveTrainFile(testobj,word,handle,tag)
else:
saveTrainFile(trainobj,word,handle,tag)
def saveTrainFile(fiobj,word,handle,tag):
if len(word) > 0:
wordli = splitWord(word)
if tag == '4':
tagli = get4Tag(wordli)
if tag == '6':
tagli = get6Tag(wordli)
for i in range(0,len(wordli)):
w = wordli[i]
h = handle
t = tagli[i]
fiobj.write(w + '\t' + h + '\t' + t + '\n')
else:
#print 'New line'
fiobj.write('\n')
#B,M,M1,M2,M3,E,S
def convertTag(tag):
fiobj = open( home_dir + 'people-daily.txt','r')
trainobj = open( home_dir + tag + '.train.data','w' )
testobj = open( home_dir + tag + '.test.data','w')
arr = fiobj.readlines()
i = 0
for a in arr:
i += 1
a = a.strip('\r\n\t ')
if a=="":continue
words = a.split(" ")
test = False
if i % 10 == 0:
test = True
for word in words:
# print "---->", word
word = word.strip('\t ')
if len(word) > 0:
i1 = word.find('[')
if i1 >= 0:
word = word[i1+1:]
i2 = word.find(']')
if i2 > 0:
w = word[:i2]
word_hand = word.split('/')
# print "----",word
w,h = word_hand
#print w,h
if h == 'nr': #ren min
#print 'NR',w
if w.find('·') >= 0:
tmpArr = w.split('·')
for tmp in tmpArr:
saveDataFile(trainobj,testobj,test,tmp,h,tag)
continue
if h != 'm':
saveDataFile(trainobj,testobj,test,w,h,tag)
if h == 'w':
saveDataFile(trainobj,testobj,test,"","",tag) #split
trainobj.flush()
testobj.flush()
# sys.argv[0]表示代码本身文件路径
# Sys.argv[ ]其实就是一个列表,里边的项为用户输入的参数,关键就是要明白这参数是从程序外部输入的
if __name__ == '__main__':
if len(sys.argv) < 2:
print 'tag[6,4] convert raw data to train.data and tag.test.data'
else:
tag = sys.argv[1]
convertTag(tag)
# print len(sys.argv)
####4、模板
template格式
a) 特征选取的行是相对的,列是绝对的,一般选取相对行前后m行,选取n-1列(假设语料总共有n列),特征表示方法为:%x[行,列],行列的初始位置都为0。
# Unigram
U00:%x[-1,0]
U01:%x[0,0]
U02:%x[1,0]
U03:%x[-1,0]/%x[0,0]
U04:%x[0,0]/%x[1,0]
U05:%x[-1,0]/%x[1,0]
###5、训练和测试
#!/bin/sh
crf_learn -f 3 -c 4.0 template 4_train.data 4_model > 4_train.rst
crf_test -m 4_model 4_test.data > 4_test.rst
crf_learn <模板> <训练语料> <模板文件> > <训练输出文件>
其中模板和训练语料是需要事先准备好的,模板文件(4_model)在训练完成后生成。
通过追加-t可以得到CRF模型文件。
crf_learn -f 3 -c 4.0 template 4_train.data 4_model -t > 4_train.txt
可以得到4_model.txt这个CRF模型文件。
crf_test <模板文件> <测试语料> > <测试输出文件>
测试用到训练过程的模板文件。
可选参数说明:
-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 显示帮助并退出
###6、计算F值
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
if __name__=="__main__":
try:
file = open(sys.argv[1], "r")
except:
print "result file is not specified, or open failed!"
sys.exit()
wc_of_test = 0
wc_of_gold = 0
wc_of_correct = 0
flag = True
for l in file:
if l=='\n': continue
_, _, g, r = l.strip().split()
if r != g:
flag = False
if r in ('E', 'S'):
wc_of_test += 1
if flag:
wc_of_correct +=1
flag = True
if g in ('E', 'S'):
wc_of_gold += 1
print "WordCount from test result:", wc_of_test
print "WordCount from golden data:", wc_of_gold
print "WordCount of correct segs :", wc_of_correct
#查全率
P = wc_of_correct/float(wc_of_test)
#查准率,召回率
R = wc_of_correct/float(wc_of_gold)
print "P = %f, R = %f, F-score = %f" % (P, R, (2*P*R)/(P+R))
操作过程如下:
追加-t操作过程:
更多推荐
所有评论(0)