zoukankan      html  css  js  c++  java
  • CRF++工具包的使用

      CRF学习完了,但是理论不结合实践总是无法出真知的。使用CRF进行命名实体识别有很多方法,比如CRF++工具包、sklearn包中的crfsuite套装、keras框架、tensorflow框架、pytorch框架等等,下面总结借助CRF++工具包实现的几点心得。

    一、CRF++工具包的安装与配置

    1.CRF++:Yet Another CRF toolkit

      CRF++是基于C++开发、可自定义特征集、基于LBFGS快速训练等等高效特征的CRF开源工具包。用于对序列数据进行分割和标记,主要用于NLP任务,例如命名实体识别、信息提取和序列标注等任务。

    2.安装

      截至目前更新的最新版为2013-02-13的CRF0.58版本。Windows下的安装很简单,只需要下载下来解压即可。解压包中的文件如图1所示。实际上使用的文件主要有CRF++的训练程序(crf_learn.exe)文件、CRF++的测试程序(crf_test.exe)文件和训练程序和测试程序需要使用的静态链接库(libcrfpp.dll)三个文件。

     

    图表 1 CRF++0.58解压后文件目录

      以上图中各个文件夹内容:

    • doc文件夹:官方主页的html内容。
    • example文件夹:分别有四个任务:基础任务英文命名实体识别basenp、英文分词chunking、日文分词seg、日文实体识别JapaneseNE,每个人物对应的训练数据(train.data)、测试数据(test.data)、模板文件(template)和执行脚本文件(exec.sh)。
    • sdk文件夹:CRF++的头文件和静态链接库。
    3.命令行使用
    (1)训练(encoding):crf_learn template_file train_file model_file >> train_info_file。

    即训练需要准备template_file、train_file两个文件,输出model_file文件。训练有以下几个参数:

    • -a CRF-L2/CRF-L1/MIRA:规范化算法选择,默认是CRF-L2。一般情况L2算法要比L1算法稍微好一点,虽然L1算法中非零特征的数值要比L2中大幅度的小。在0.45版本后的CRF++,还支持single-best MIRA训练算法。
    • -c float:设置CRF的hyper-parameter。默认为1.0,c的数值越大,CRF拟合训练数据的程度越高。这个参数可以调整过度拟合和不拟合之间的平衡度,通过交叉验证等方法寻找较优的参数。
    • -f NUM:设置特征的cut-off threshold。CRF++使用训练数据中至少NUM次出现的特征。默认值为1,当使用CRF++到大规模数据时,只出现一次的特征可能会有几百万,这个选项就会在这样的情况下起到作用。
    • -p NUM:多核CPU,通过多线程提升训练速度。NUM是线程数量。
    • -t:同时生成文本格式的模型,用于调试。
    • -e float:设置停止条件的阈值,float是一个大于0的浮点数。
    • -v:显示版本并退出程序。
    • -m NUM:设置LBFGS的最大迭代次数,NUM是一个整数,默认为10K。

      训练时输出内容的参数:

    • iter:表示迭代次数
    • terr:表示标记的训练错误率,等于标记的训练错误数量/标记的总数。
    • serr:表示sentence的训练错误率,等于sentence的训练错误数量/sentence的总数。
    • obj:当前的目标函数值。当目标函数值收敛到某个固定值时,CRF++停止迭代。
    • diff:目标函数值的相对变化。它等于当前的目标函数值减去上一个目标函数值。
    (2)测试:crf_test -m model_file test_files >> result_file。

    此处有两个参数:-v和-n。-v用来预测标签概率值,默认值为0,级别越高输出的内容越多;-n NUM显示不同可能序列的概率值。eg. crf_test -v0 -n 20 -m model test.data

    二、实验

    1.准备训练文件
    (1)训练测试文件格式
    • 文件由很多token组成,每个token占据一行,包含固定的字段。
    • 所有token的字段数量相等,字段的数量没有限制,字段之间用空白分割(空格符或者tab符)。
    • 每个字段通常表示某种含义。如:第一列表示单词,第二列表示词性,第三列表示属性等等……h
    • 一个sentence由多个token表述,sentence之间通过空行来区分边界。
    • 训练文件中,最后一个字段必须是标记,将作为CRF++训练的目标。
    (2)模板文件

      CRF++使用模板文件来生成特征。模板文件需要用户编写,从而指定需要生成哪些特征。文件中的每一行定义了一个特征模板,以#开头的行是注释行,空行也被认为是注释行而被剔除。有两种类型的特征模板,通过特征模板的第一个字符区分。

    • 宏语句:特征模板中使用的宏语句%x[row,col],%x是固定的,宏语句的引导字符。row是一个整数,指定了相对于当前的数据行的行数,col是一个整数,指定了采用第几个字段(从0开始编号)。
    • Unigram特征模板:模板的第一个字符串为U,这种特征模板用于描述unigram特征。

      给定一个Unigram特征模板U01:%x[0,1],它会生成M个特征函数,其中M为训练数据的行数(剔除空行,因为空行是sentence的分隔符)。每个特征函数为:

    “““

    func1 = if (output = LABEL1 and feature = “U01:xx1”) return 1 else return 0

    func2 = if (output = LABEL2 and feature = “U01:xx2”) return 1 else return 0

    func3 = if (output = LABEL3 and feature = “U01:xx3”) return 1 else return 0

    ……

    funcM = if (output = LABELM and feature = “U01:xxM”) return 1 else return 0

    ”””

        其中LABEL1,……,LABELM是训练文件中每一行的标记,feature=“U01:xx1”,……,feature="U01:xxM"是训练文件中,每一行由U01:%x[0,1]指定的,从该行提取到的特征。

       需要注意的是,上述生成的特征函数会有大量重复,假设标记的种类一共有L个,由U01:%x[0,1]指定,从该行提取到的特征的种类一共有N个,则特征函数的种类一共有L×N个。CRF++会按照L中标记,N中特征来自动生成L×N个特征函数。

    • Bigram特征模型:模板的第一个字符串为B,这种特征模板用于描述bigram特征。

       给定一个Bigram特征模板B01:%x[0,1],它会生成M个特征函数,其中M为训练数据的行数(剔除空白行,因为空白行是sentence的分隔符)。每个特征函数为

    “““

    func2 = if (output = LABEL2/LABEL1 and feature="B01:xx2") return 1 else return 0

    func3 = if (output = LABEL3/LABEL2 and feature="B01:xx3") return 1 else return 0

    func4 = if (output = LABEL4/LABEL3 and feature="B01:xx4") return 1 else return 0

    ....

    funcM = if (output = LABELM/LABELM_1 and feature="B01:xxM") return 1 else return 0

    ”””

        在Bigram中,特征函数中的output是当前的输出标记和前一个输出标记的联合,即联合的是标记而不是特征,特征的联合由宏语句来实现。其他的意义和Unigram中的相同。

      此时生成的特征函数也会有大量重复。假设标记的种类一共有L个,由B01:%x[0,1]指定的,从该行提取到的特征的种类一共有N个,则CRF++会按照L种标记,N种特征自动生成L×L×N个特征函数,训练后函数的权值反映了上一个节点的标签对当前节点的影响。

      当标记的种类L较大时,Bigram会生成非常多的特征函数,其中非常多的特征函数在样本中的返回值只有少量的1,此时,模型的训练和测试将会非常低效。

      如果某一行的内容只有一个字符B,表示:由当前的输出标记和前一个输出标记的联合生成的特征函数。

    三、实践

    (1)用CRF进行命名实体识别

    博客:https://www.jianshu.com/p/12f2cdd86679

    参考文献

    [1] http://www.huaxiaozhuan.com/%E5%B7%A5%E5%85%B7/CRF/chapters/crfpp.html,CRF++使用。

    [2] http://taku910.github.io/crfpp/,CRF

    本文为博主原创文章,未经博主允许禁止转载,需转载请注明出处,欢迎指正!
  • 相关阅读:
    ansible(十)roles
    playbook变量(九)for循环
    playbook变量(八)循环迭代
    playbook变量(七)template 基本使用 when
    playbook变量(六)template 基本使用
    playbook变量(五)
    Sqoop2常用命令介绍
    Sqoop2入门之导入关系型数据库数据到HDFS上
    Sqoop2环境搭建
    Spark On Yarn中spark.yarn.jar属性的使用
  • 原文地址:https://www.cnblogs.com/caoer/p/14855922.html
Copyright © 2011-2022 走看看