如果你只是想要简单的如何使用CRF++, 建议阅读
http://blog.csdn.net/Felomeng/article/details/4288492 。
这里以一个具体的例子介绍CRF++的一些思想和代码的实现过程。就加入我们想利用CRF++来进行分词。
一. 数据及其格式介绍
Train.data
中 F1 B-NP
华 F2 I-NP
人 F3 B-NP
民 F4 I-NP
共 F5 B-NP
和 F6 M-NP
国 F7 I-NP
国 F8 B-NP
家 F9 I-NP
主 F10 B-NP
席 F11 I-NP
Template:
# Unigram
U00:%x[-2,0]
U01:%x[-1,0]
U02:%x[0,0]
U03:%x[1,0]
U04:%x[2,0]
U05:%x[-1,0]/%x[0,0]
U06:%x[0,0]/%x[1,0]
U12:%x[0,1]
# Bigram
B
根据给定的template 和训练数据,需要得到一个CRF模型。
这里先对数据进行一个简单的介绍,
Train.data:
中 F1 B-NP
华 F2 I-NP
人 F3 B-NP
对于输入的一句话,最基本的单元是一个个的字。所以我们处理的单元是字。我们的任务是判断每个字到底是词首,词中还是词尾。 在训练数据中,我们用B-NP, M_NP, I_NP分别表示词首,词中,词尾。 训练数据的最后一列表示训练集中每个字属于哪一类。 而F1, F2, F3..... 则是表示每个字的其他特征,比如词性,频率等。为了方便,这里假设这一列是词性列。你可以为它任意添加新的特征,这也是CRF的优势之一。但是一般来说,你如果在训练集中定义了新特征,那么你在 template 中必须想办法用上。
Template:
U00:%x[-2,0]
U01:%x[-1,0]
U12:%x[0,1]
表示什么意思,U00代表模板的名字, -2 代表当行,意思是和当前字的位置,-2表示当前字的前面第2个字,比如,当前是“人”,-2代表是“中”。 注:如果当前是第一个字,如“中”,则-1用B-1,-2用B-2 代替。 第二个数字 0 代表训练数据中第几个特征,如这里0代表第一列汉字,1代表 F1,F2,F3这一词性列。则 U00:%x[-2,0]的意思是当前字的前面第二个汉字是什么? U12:%x[0,1]代表当前字的词性是什么?
# Bigram
B
表示的是bigram,这里只有一个,表示只计算相邻的字之间的bigram。
二. 数据在CRF++中的组织结构
中 F1 B-NP
华 F2 I-NP
人 F3 B-NP
民 F4 I-NP
共 F5 B-NP
和 F6 M-NP
国 F7 I-NP
国 F8 B-NP
家 F9 I-NP
主 F10 B-NP
席 F11 I-NP
开始,我们介绍几个概念,
1. 所有汉字的可能类别
这里就是指训练数据中最后一列中的所有的可能值。这里只有3个可能,B-NP, M-NP, I-NP。
2. unigram, bigram
unigram : 指的是template中的由Unigram定义的若干template.
bigram: 指的是template中由Bigram定义的若干template,这里只有一个。
3. 构建如下搜索矩阵
I-NP((Template(1,2,...9))) | I-NP(Template(1,2,...9)) | I-NP... | I-NP... | ||
M-NP((Template(1,2,...9))) | M-NP(Template(1,2,...9)) | M-NP... | M-NP... | ||
B-NP(Template(1,2,...9)) | B-NP(Template(1,2,...9)) | B-NP... | B-NP... | ||
中 | 华 | 人 | 民 |
我们的目标是构建一个模型,利用它解码出来的路径(模型期望)和数据库中标注的期望(经验期望)的差别小于某一个阈值。
4. node 和 path的概念
如上面表格所示,每一个字 底下对应3个node, 如“中”,对应它属于B-NP, M_NP, I_NP三个node. 每个node对应有9个template(根据template模板定义)。计算该node的概率需要用到这些template的值。 两个相邻列之间的node之间可以相互转移,这条转移的路径就是path. 比如从“中” 的3个node都可以转移到“华”的I-NP节点,既有3条路径可以从前面转移到“华”的I-NP节点。 当然这中间有个转移概率,这个转移概率也主要通过template中的bigram来约束。某个node的概率可以由以下公式计算:
S_ij=log[Σlnode=1:3exp(αi-1 +aij)] |
αi-1 就是node cost, aij就是transition cost。
今天看来没时间了,具体程序中如何实现,待续
评论