主要通过看这篇文章对CRF分词才有一点理解,下面是链接http://www.52nlp.cn/%E5%88%9D%E5%AD%A6%E8%80%85%E6%8A%A5%E9%81%933-crf-%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D%E8%A7%A3%E7%A0%81%E8%BF%87%E7%A8%8B%E7%90%86%E8%A7%A3
CRF与HMM在分词上是相通的,都用的是维特比算法,那么两者的区别又是什么呢,在我看来是两者最大的区别在于CRF考虑到上下文信息,而HMM没有考虑上下文信息(我的博客中有写HMM是如何实现分词的) 我的理解是CRF是利用特征模板来考虑上下文信息,只是将HMM中的发射概率变成了特征模板中的概率
下面也和HMM一样通过列子进行讲解(参考上面链接内容):
民 主 是 普 世 价 值
B B B B B B B
O O O O O O O
M M M M M M M
E E E E E E E
Viterbe解码就是在以上由标记组成的 数组中 搜索一条 最优的路径。(考虑每个字的每个标注)
对于每一个字的每一个标记,我们都要计算是该标记的分数(相当与概率大小,只不过这里的分数可能大于1,所以不能再叫概率),这个分数由三部分组成,它本身的一元特征权重W(根据特征模板去确定,我认为是对应到HMM的发射概率,改动就在这里,是联系上下文的关键),前面一个字标记的分数PreScore(前一个字的状态概率,和HMM一样),前面一个字标记到当前标记转移特征权重TransW(状态转移概率和HMM一样)
这里我们用的特征模板是U00:%x[-1,0]/%x[0,0]; U01:%x[0,0];U02:%x[0,0]/%x[1,0]
- 计算第一个字的各个状态分数(score),对于,‘民’来说,我们要算 在B,O,M,E所有状态下的Score,因为是第一字,所以前一个字的状态分数和状态转移都是0,就不用计算,只需要计算自己的一元特征的权重:
对于标记,B,我们计算它的Score,记为S1B=W1B=w(null,民,B)+w(民,B)+w(民,B,主) //这些特征的意思是: (null,民,B),当前字为 ‘民’标记为B,前面一个字为空,(民,B):当前字为‘民’,标记为B,(民,B,主):当前字为’民’,标记为B,当前字的后一个字为‘主’。特征的权重都是在训练时得到的。(注:以下的计算因为都取了对数,所以是加法,其实是三个部分分数相乘,但是由于加法会减少计算量,所以取了对数)
对于标记,O,S1O=W1O=w(null,民,O)+w(民,O)+w(民,O,主)
对于标记,M,S1M=W1M=w(null,民,M)+w(民,M)+w(民,M,主)
对于标记,E,S1E=W1E=w(null,民,E)+w(民,E)+w(民,E,主)
也就是每个字的每个状态都要考虑
2.对于第二个字’主’,首先要计算的是每个标记的 一元权重W2B,W2O,W2M,W2E(这就是上下文的体现).
W2B=w(民,主,B)+w(主,B)+w(民主,B,是)
W2M=w(民,主,M)+w(主,M)+w(民主,M,是)
W2O=w(民,主,O)+w(主,O)+w(民主,O,是)
W2E=w(民,主,E)+w(主,E)+w(民主,E,是)
对于B,到达该标记的最大分数为:S2B=Max((v(BB)+S1B),(v(OB)+S1O),(v(MB)+S1M),(v(EB)+S1E))+W2B,其中v(BB)等为B到B的