• 文件由很多token组成,每个token 占据一行,包含固定数量的字段。
      • 所有token 的字段数量相等,字段的数量没有限制,字段之间用空白分隔(空格符或者tab 符)。
      • 每个字段通常表示某种含义。如:第一列表示单词、第二列表示词性、第三列表示属性…。
      • 一个sentence 由多个token 表述,sentence 之间通过空行来区分边界。
      • 训练文件中,最后一个字段必须是标记,它将作为CRF++ 训练的目标。
    1. CRF++ 使用模板文件来生成特征。模板文件需要用户编写,从而指定需要生成哪些特征。

    2. 模板文件中,每一行都定义了一个特征模板。

    3. 模板文件中,以 # 开头的行是注释行。

      空行也会被认为是注释行而被剔除。

    4. 有两种类型的特征模板,它们通过特征模板的第一个字符来区分。

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

    2.2.1 宏语句

    1. 特征模板中,经常使用宏语句 %x[row,col] 。其中:

      • %x 是固定的,是宏语句的引导字符。

      • row 是一个整数,指定了相对于当前的数据行的行数。

      • col 是一个整数,指定了采用第几个字段(从0 开始编号)。

        注意:标记列不能作为特征,因此也就不能出现在特征模板中。

    2. 假设输入数据为:

      则下列特征模板为:

      1. %x[0,0] --> the
      2. %x[0,1] --> DT
      3. %x[-1,0] --> reckons
      4. %x[-2,1] --> PRP
      5. %x[0,0]/%x[0,1] --> the/DT
      6. ABC%x[0,1]123 --> ABCDT123

    2.2.2 Unigram 特征模板

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

      每个特征函数为:

      1. func1 = if (output = LABEL1 and feature="U01:xx1") return 1 else return 0
      2. func2 = if (output = LABEL2 and feature="U01:xx2") return 1 else return 0
      3. func3 = if (output = LABEL3 and feature="U01:xx3") return 1 else return 0
      4. ....
      5. 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] 指定的、从该行提取到的特征。
    2. 事实上,上述生成的特征函数会有大量重复。

      假设标记的种类一共有 个,由 U01:%x[0,1] 指定的、从该行提取到的特征的种类一共有 二、使用 - 图2 个, 则特征函数的种类一共有 个。

      CRF++ 会按照 二、使用 - 图3 种标记, 种特征来自动生成 二、使用 - 图4 个特征函数。

    2.2.3 Bigram 特征模板

    1. 上述生成的特征函数也会有大量重复。

      假设标记的种类一共有 个,由 U01:%x[0,1] 指定的、从该行提取到的特征的种类一共有 二、使用 - 图5 个,则CRF++ 会按照 种标记,二、使用 - 图6 种特征自动生成 个特征函数。

    2. 当标记的种类 二、使用 - 图7 较大时, Bigram 会生成非常多的特征函数,其中非常多的特征函数在样本中的返回值只有少量的1

      这中情况下,模型的训练和测试将会非常低效。

    2.2.4 模板标识符

    1. Unigram 特征模板和Bigram 特征模板中,在U 或者B 之后往往跟随一个数字作为标识符。

    2. 标识符的作用是区分不同模板生成的特征。

      例如:

      1. The DT B-NP
      2. pen NN I-NP
      3. a DT B-NP
      • 如果有标识符,则以下两个模板生成的特征函数为:

        • U01:%x[-2,1]if (output = B-VP and feature="U01:DT") return 1 else return 0
        • U02:%x[1,1]if (output = B-VP and feature="U02:DT") return 1 else return 0
      • 如果没有标识符,则以下两个模板生成的特征函数为:

        • U:%x[-2,1]if (output = B-VP and feature="U:DT") return 1 else return 0
        • U:%x[1,1]if (output = B-VP and feature="U:DT") return 1 else return 0

        可见这两个模板生成的特征函数无法区分。

    3. 如果你需要使用Bag Of Words:BOW 特征,则你可以不使用模板标识符。

      如果你需要考虑词序,则必须使用模板标识符。

    1. 训练也称作encoding, 是通过crf_learn 程序来完成的。

    2. 训练的命令为:

      1. crf_learn template_file train_file model_file

      其中:

      • template_file:人工编写的模板文件
      • train_file:人工标注的训练文件
      • model_fileCRF++ 生成的模型文件
    3. 训练的输出内容如下:

      ​x

      其中:

      • iter:表示迭代次数
      • terr:表示标记的训练错误率,它等于标记的训练错误数量 / 标记的总数
      • serr:表示sentence 的训练错误率,它等于sentence的训练错误数量 / sentence的总数
      • obj:当前的目标函数值。当目标函数值收敛到某个固定值时,CRF++ 停止迭代。
      • diff:目标函数值的相对变化。它等于当前的目标函数值减去上一个目标函数值。
    4. 常用训练参数:

      • -a CRF-L2 或者 -a CRF-L1:选择训练算法。

        CRF-L2 表示L2 正则化的CRF ,它也是CRF++ 的默认选择。CRF-L1 表示L1 正则化的CRF

      • -c float:设置CRF 的正则化项的系数 ,float 是一个大于0的浮点数,默认为 1.0。

        如果 二、使用 - 图8 较大,则CRF++ 容易陷入过拟合。通过调整该参数,模型可以在欠拟合和过拟合之间取得平衡。

      • -f NUM:设置特征的下限,NUM 是一个整数,默认为 1 。

        如果某个特征(由特征模板生成的)发生的次数小于NUM,则该特征会被忽略。

        当应用于大数据集时,特征的种类可能到达上百万,此时设置一个较大的NUM 会过滤掉大部分低频特征,提高模型的计算效率。

      • -p NUM:设置线程数量,NUM 是一个整数。

        如果是多核CPU,则可以通过多线程来加速训练。NUM 表示线程的数量。

      • -t:同时生成文本格式的模型,用于调试。

      • -e float:设置停止条件的阈值,float 是一个大于0的浮点数,默认为 1.00.0001。

      • -v:显示版本并退出程序。

      • -m NUM:设置LBFGS 的最大迭代次数,NUM 是一个整数,默认为 10K 。

    5. Margin-infused relaxed algorithm:MIRA 是一种超保守在线算法, 在分类、排序、预测等应用领域取得不错成绩。

      通过参数 -a MIRA 来选择MIRA 算法。

      • 输出:

        1. CRF++: Yet Another CRF Tool Kit
        2. Copyright(C) 2005 Taku Kudo, All rights reserved.
        3. reading training data: 100.. 200.. 300.. 400.. 500.. 600.. 700.. 800..
        4. Done! 1.92 s
        5. Number of sentences: 823
        6. Number of features: 1075862
        7. Number of thread(s): 1
        8. Freq: 1
        9. eta: 0.00010
        10. C: 1.00000
        11. shrinking size: 20
        12. Algorithm: MIRA
        13. iter=0 terr=0.11381 serr=0.74605 act=823 uact=0 obj=24.13498 kkt=28.00000
        14. iter=1 terr=0.04710 serr=0.49818 act=823 uact=0 obj=35.42289 kkt=7.60929
        15. ...

        其中:

        • iter,terr,serr:意义与前面CRF 相同

        • actworking set 中,active 的样本的数量

        • uact:对偶参数达到软边界的上界 的样本的数量。

          如果为0,则表明给定的训练样本是线性可分的。

        • obj:当前的目标函数值 二、使用 - 图9

        • kkt:最大的kkt 违反值。当它为 0.0 时,训练结束。

      • 参数:

        • -c float:设置软边界的参数 ,float 是一个大于0的浮点数。

          如果 二、使用 - 图10 较大,则CRF++ 容易陷入过拟合。通过调整该参数,模型可以在欠拟合和过拟合之间取得平衡。

        • -H NUM:设置shrinking size

          当一个训练sentence 未能应用于更新参数向量NUM 次时,认为该sentence 不再对训练有用。此时CRF++ 会删除该sentence

          shrinking size 较小时,会在早期发生收缩。这会大大减少训练时间。

          但是不建议使用太小的shrinking size ,因为训练结束时,MIRA 会再次尝试所有的训练样本,以了解是否所有KKT 条件得到满足。shrinking size 条小会增加重新检查的机会。

        • -f NUM-e-t-p-v:意义与前面CRF 相同

    1. 测试也称作decoding, 是通过crf_test 程序来完成的。

    2. 测试的命令为:

      1. crf_test -m model_file test_file1 test_file2 ...

      其中:

      • model_file:由crf_learn 生成的模型文件

      • test_file1,test_file2...:多个测试文件。其格式与训练文件相同。

        它将被crf_test 添加一列(在所有列的最后)预测列

    3. 常用参数:

      • v 系列参数:指定输出的级别,默认为0级,即v0

        级别越高,则输出的内容越多。其中:

        • -v0:仅仅输出预测的标签。如:B
        • -v1:不仅输出预测的标签,还给出该标签的预测概率。如:B/0.997
        • -v2:给出每个候选标签的预测概率。如:I/0.954883 B/0.00477976 I/0.954883 O/0.040337

        注意:v0也可以写作-v 0 。其它也类似。

      • 每个结果之前会给出一行输出:# 结果序号 条件概率