Intro to CRF Chinese Word Segmentation
How to handle this problem
朋友送给你一卷胶卷底片,这些底片上标着拍摄日期,但是底片有一些磨损了,都只能看到一些局部影像,底片都是关于四个不同的拍摄对象,A、B、C、D,现在需要把这些底片做一个分类。如果只用底片自身当作信息,可能会丢失信息,因为连续的两张底片很可能是相关的,如果前一张底片是A,那么后一张底片没有明显的特征去做分辨的时候,后一张底片是A的概率会更大一点,说到这,你可能会想到Hidden Markov Model。
About CRF
CRF(Conditional Random Field),经常被用于一些结构化的预测,例如Sequence Labeling、computer visiion、DNA recognition等等。CRF会保留一定窗口内的上下文信息,很多NLP任务例如word segmentation、NER、POS tagging等序列标注的问题都能用到CRF。
CRF对于上下文信息的保留,会使用一些特征函数:
s
表示一整个句子i
表示当前词的位置l<i-1>
表示上一个词的labell<i>
表示当前词的label
举个简单的例子:
我
要
去
五
道
口
地
铁
站
S
S
S
B
M
E
B
M
E
对于五
字,f(s,i,l<i-1>,l<i>)
表示:
如果当前字是五
、label是B
,并且上个词是去
、label是S
, 那么f = 1
,否则f = 0
这样可以构造很多个特征函数,这些特征函数构成了vector<x>
,对于给定的训练集,只需要做简单的逻辑回归就可以了。
Chinese Word Segment Using CRF
以CRF++,Chinese Tree Bank 8.0来具体感受一下,建议看一看CRF++的源码感受一下具体的实现细节,当然还有很多其他的CRF实现的库,各个语言都有。
可以看看train.csv
,你会发现数据会被打上四种Label,B
M
E
S
,分别表示Begin
Middle
End
Segment
外 B
商 E
投 B
资 E
企 B
业 E
在 S
中 B
国 E
提 B
供 E
一 B
千 M
七 M
百 M
万 E
个 S
就 B
业 E
机 B
我们还是以我想去五道口地铁站
为例子,以下是crfpp的template文件
# Unigram
U00:%x[-2,0]
U01:%x[-1,0]
U02:%x[0,0]
U03:%x[1,0]
U04:%x[2,0]
U05:%x[-2,0]/%x[-1,0]/%x[0,0]
U06:%x[-1,0]/%x[0,0]/%x[1,0]
U07:%x[0,0]/%x[1,0]/%x[2,0]
U08:%x[-1,0]/%x[0,0]
U09:%x[0,0]/%x[1,0]
# Bigram
B
crfpp最多支持窗口大小为8,不过实际使用时窗口大小为2就会有很多参数了。
我 想 去 五道口 地铁站
S S S B M E B M E
先说一下Unigram
,其中%x[row, col]
表示训练数据里的具体位置,还是以五
为例子:
U00:%x[-2,0]
表示如果当前词是五
、label为B
,上上个词是要
、label是S
,则特征U00:要
取值1,否则0U09:%x[0,0]/%x[1,0]
表示如果当前词是五
、label为B
,下个词是道
、label是M
,则特征U09:五/道
取值1,否则0- 其他
Unigram
特征可以以统一方式去自动生成
所以,Unigram
多有特征数为L x N
,其中N
遍历完整个配置文件后生成的总唯一特征数,L
为输出分类个数。
对于Bigram
,在template文件里仅仅以B
表示,还是以五
为例子,以B[x<i>][y<i>][x<j>][y<j>]
表示bigram特征:
B[去][S][五][B] = 1
B[去][S][五][S] = 0
B[去][S][五][M] = 0
B[去][S][五][E] = 0
B[去][B][五][B] = 0
B[去][B][五][S] = 0
B[去][B][五][M] = 0
B[去][B][五][E] = 0
B[去][M][五][B] = 0
B[去][M][五][S] = 0
B[去][M][五][M] = 0
B[去][M][五][E] = 0
B[去][E][五][B] = 0
B[去][E][五][S] = 0
B[去][E][五][M] = 0
B[去][E][五][E] = 0
所以对于Bigram
来说,会有L x L x N
个特征,最终模型参数个数为L x L x N + L x N
个,取模板特征数越多,则模型参数也会爆发式增长,这样也会影响效果。
我们以CRF++为例子,源码见https://github.com/thelostpeace/crfpp
#安装
./configure prefix=你的安装目录
make
make install
#训练
crf_learn -p 12 -t template train.tsv model
会生成一个model.txt的文件,里面含有特征和参数描述
CRF++: Yet Another CRF Tool Kit
Copyright (C) 2005-2013 Taku Kudo, All rights reserved.
reading training data: 100.. 200.. 300.. 400.. 500.. 600.. 700.. 800.. 900.. 1000.. 1100.. 1200.. 1300.. 1400.. 1500.. 1600.. 1700.. 1800.. 1900.. 2000.. 2100.. 2200.. 2300.. 2400.. 2500.. 2600.. 2700.. 2800.. 2900.. 3000.. 3100.. 3200.. 3300.. 3400.. 3500.. 3600.. 3700.. 3800.. 3900.. 4000.. 4100.. 4200.. 4300.. 4400.. 4500.. 4600.. 4700.. 4800.. 4900.. 5000.. 5100.. 5200.. 5300.. 5400.. 5500.. 5600.. 5700.. 5800.. 5900.. 6000.. 6100.. 6200.. 6300.. 6400.. 6500.. 6600.. 6700.. 6800.. 6900.. 7000.. 7100.. 7200.. 7300.. 7400.. 7500.. 7600.. 7700.. 7800.. 7900.. 8000.. 8100.. 8200.. 8300.. 8400.. 8500.. 8600.. 8700.. 8800.. 8900.. 9000.. 9100.. 9200.. 9300.. 9400.. 9500.. 9600.. 9700.. 9800.. 9900.. 10000.. 10100.. 10200.. 10300.. 10400.. 10500.. 10600.. 10700.. 10800.. 10900.. 11000.. 11100.. 11200.. 11300.. 11400.. 11500.. 11600.. 11700.. 11800.. 11900.. 12000.. 12100.. 12200.. 12300.. 12400.. 12500.. 12600.. 12700.. 12800.. 12900.. 13000.. 13100.. 13200.. 13300.. 13400.. 13500.. 13600.. 13700.. 13800.. 13900.. 14000.. 14100.. 14200.. 14300.. 14400.. 14500.. 14600.. 14700.. 14800.. 14900.. 15000.. 15100.. 15200.. 15300.. 15400.. 15500.. 15600.. 15700.. 15800.. 15900.. 16000.. 16100.. 16200.. 16300.. 16400.. 16500.. 16600.. 16700.. 16800.. 16900.. 17000.. 17100.. 17200.. 17300.. 17400.. 17500.. 17600.. 17700.. 17800.. 17900.. 18000.. 18100.. 18200.. 18300.. 18400.. 18500.. 18600.. 18700.. 18800.. 18900.. 19000.. 19100.. 19200.. 19300.. 19400.. 19500.. 19600.. 19700.. 19800.. 19900.. 20000.. 20100.. 20200.. 20300.. 20400.. 20500.. 20600.. 20700.. 20800.. 20900.. 21000.. 21100.. 21200.. 21300.. 21400.. 21500.. 21600.. 21700.. 21800.. 21900.. 22000.. 22100.. 22200.. 22300.. 22400.. 22500.. 22600.. 22700.. 22800.. 22900.. 23000.. 23100.. 23200.. 23300.. 23400.. 23500.. 23600.. 23700.. 23800.. 23900.. 24000.. 24100.. 24200.. 24300.. 24400.. 24500.. 24600.. 24700.. 24800.. 24900.. 25000.. 25100.. 25200.. 25300.. 25400.. 25500.. 25600.. 25700.. 25800.. 25900.. 26000.. 26100.. 26200.. 26300.. 26400.. 26500.. 26600.. 26700.. 26800.. 26900.. 27000.. 27100.. 27200.. 27300.. 27400.. 27500.. 27600.. 27700.. 27800.. 27900.. 28000.. 28100.. 28200.. 28300.. 28400.. 28500.. 28600.. 28700.. 28800.. 28900.. 29000.. 29100.. 29200.. 29300.. 29400.. 29500.. 29600.. 29700.. 29800.. 29900.. 30000.. 30100.. 30200.. 30300.. 30400.. 30500.. 30600.. 30700.. 30800.. 30900.. 31000.. 31100.. 31200.. 31300.. 31400.. 31500.. 31600.. 31700.. 31800.. 31900.. 32000.. 32100.. 32200.. 32300.. 32400.. 32500.. 32600.. 32700.. 32800.. 32900.. 33000.. 33100.. 33200.. 33300.. 33400.. 33500.. 33600.. 33700.. 33800.. 33900.. 34000.. 34100.. 34200.. 34300.. 34400.. 34500.. 34600.. 34700.. 34800.. 34900.. 35000.. 35100.. 35200.. 35300.. 35400.. 35500.. 35600.. 35700.. 35800.. 35900.. 36000.. 36100.. 36200.. 36300.. 36400.. 36500.. 36600.. 36700.. 36800.. 36900.. 37000.. 37100.. 37200.. 37300.. 37400.. 37500.. 37600.. 37700.. 37800.. 37900.. 38000.. 38100.. 38200.. 38300.. 38400.. 38500.. 38600.. 38700.. 38800.. 38900.. 39000.. 39100.. 39200.. 39300.. 39400.. 39500.. 39600.. 39700.. 39800.. 39900.. 40000.. 40100.. 40200.. 40300.. 40400.. 40500.. 40600.. 40700.. 40800.. 40900.. 41000.. 41100.. 41200.. 41300.. 41400.. 41500.. 41600.. 41700.. 41800.. 41900.. 42000.. 42100.. 42200.. 42300.. 42400.. 42500.. 42600.. 42700.. 42800.. 42900.. 43000.. 43100.. 43200.. 43300.. 43400.. 43500.. 43600.. 43700.. 43800.. 43900.. 44000.. 44100.. 44200.. 44300.. 44400.. 44500.. 44600.. 44700.. 44800.. 44900.. 45000.. 45100.. 45200.. 45300.. 45400.. 45500.. 45600.. 45700.. 45800.. 45900.. 46000.. 46100.. 46200.. 46300.. 46400.. 46500.. 46600.. 46700.. 46800.. 46900.. 47000.. 47100.. 47200.. 47300.. 47400.. 47500.. 47600.. 47700.. 47800.. 47900.. 48000.. 48100.. 48200.. 48300.. 48400.. 48500.. 48600.. 48700.. 48800.. 48900.. 49000.. 49100.. 49200.. 49300.. 49400.. 49500.. 49600.. 49700.. 49800.. 49900.. 50000.. 50100.. 50200.. 50300.. 50400.. 50500.. 50600.. 50700.. 50800.. 50900.. 51000.. 51100.. 51200.. 51300.. 51400.. 51500.. 51600.. 51700.. 51800.. 51900.. 52000.. 52100.. 52200.. 52300.. 52400.. 52500.. 52600.. 52700.. 52800.. 52900.. 53000.. 53100.. 53200.. 53300.. 53400.. 53500.. 53600.. 53700.. 53800.. 53900.. 54000.. 54100.. 54200.. 54300.. 54400.. 54500.. 54600.. 54700.. 54800.. 54900.. 55000.. 55100.. 55200.. 55300.. 55400.. 55500.. 55600.. 55700.. 55800..
Done!26.12 s
Number of sentences: 55823
Number of features: 14692008
Number of thread(s): 32
Freq: 1
eta: 0.00010
C: 1.00000
shrinking size: 20
iter=0 terr=0.69007 serr=1.00000 act=14692008 obj=2814917.83426 diff=1.00000
iter=1 terr=0.42122 serr=0.97143 act=14692008 obj=2203735.06593 diff=0.21712
iter=2 terr=0.38646 serr=0.96996 act=14692008 obj=1272186.58497 diff=0.42271
#test
crf_test -m model test.tsv >test.predict
./crf_eval.py
total: 303506
right: 290856
acc: 0.958320428591
准确率能到95.8%,优化效果可以调整特征模板,或者改源码加一些手动特征,然后调调参。
A Simple Chinese Word Segment Server
以上文描述的方法,以Thrift为RPC写了一个简易的中文分词的Server,见
https://github.com/thelostpeace/word_seg
TreeHole
虽然CRF能够保存一定的上下文信息,但是所保存的信息取决于其窗口大小,还是有一定的局限性的,后续我会考虑用BiLSTM + CRF的方式或者其他结合RNN的方式去做一个实现。
现在我们已经讲完了wordembedding和中文分词,你可以用中文wiki百科和其他语料训练一个通用性的wordembedding,用作其他NLP任务的一个基础组件,你也有了一个中文分词服务,对于一个对话系统来说,你已经走完了ASR之后的第一步,下一步是NER和tagging,但是不知道下一次更新是什么时候了,得看我的学习进展了,毕竟我只是一个NLP业余新手~
reference
- https://medium.com/ml2vec/overview-of-conditional-random-fields-68a2a20fa541
- https://www.cs.cmu.edu/~tom/mlbook/NBayesLogReg.pdf
- http://homepages.inf.ed.ac.uk/csutton/publications/crftut-fnt.pdf
- https://prateekvjoshi.com/2013/02/23/why-do-we-need-conditional-random-fields/
- https://prateekvjoshi.com/2013/02/23/what-are-conditional-random-fields/
- http://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/
- http://www.lsi.upc.edu/~aquattoni/AllMyPapers/crf_tutorial_talk.pdf