1. 实例背景
假设你有许多小明同学一天内不同时段的照片,从小明提裤子起床到脱裤子睡觉各个时间段都有。现在的任务是对这些照片进行分类。比如有的照片是吃饭,那就给它打上吃饭的标签;有的照片是跑步时拍的,那就打上跑步的标签;有的照片是开会时拍的,那就打上开会的标签。问题来了,你准备怎么干?
一个简单直观的办法就是,不管这些照片之间的时间顺序,想办法训练出一个多元分类器。就是用一些打好标签的照片作为训练数据,训练出一个模型,直接根据照片的特征来分类。例如,如果照片是早上6:00拍的,且画面是黑暗的,那就给它打上睡觉的标签;如果照片上有车,那就给它打上开车的标签。
这样做乍一看可以!但实际上,由于我们忽略了这些照片之间的时间顺序这一重要信息,我们的分类器会有缺陷的。举个例子,假如有一张小明闭着嘴的照片,怎么分类?显然难以直接判断,需要参考闭嘴之前的照片,如果之前的照片显示小明在吃饭,那这个闭嘴的照片很可能是小明在咀嚼食物准备下咽,可以给它打上吃饭的标签;如果之前的照片显示小明在唱歌,那这个闭嘴的照片很可能是小明唱歌瞬间的抓拍,可以给它打上唱歌的标签。
为了让我们的分类器能够有更好的表现,在为一张照片分类时,我们必须将与它相邻的照片的标签信息考虑进来。这——就是条件随机场(CRF)大显身手的地方!
2. 从词性标注问题理解CRF原理
词性标注就是给一个句子中的每个单词注明词性。比如这句话:“Bob drank coffee at Starbucks”,注明每个单词的词性后是这样的:“Bob (名词) drank(动词) coffee(名词) at(介词) Starbucks(名词)”。
下面就用条件随机场来解决这个问题。
以上面的话为例,有5个单词,我们将:(名词,动词,名词,介词,名词)
作为一个标注序列,称为
l
l
l,可选的标注序列有很多种,比如
l
l
l还可以是这样:(名词,动词,动词,介词,名词)
,我们要在这么多的可选标注序列中,挑选出一个最靠谱的作为我们对这句话的标注。
怎么判断一个标注序列靠谱不靠谱呢?
就我们上面展示的两个标注序列来说,第二个显然不如第一个靠谱,因为它把第二、第三个单词都标注成了动词,动词后面接动词,这在一个句子中通常是说不通的。
假如我们给每一个标注序列打分,打分越高代表这个标注序列越靠谱,我们至少可以说,凡是标注中出现了动词后面还是动词的标注序列,要给它负分。
上面所说的动词后面还是动词就是一个特征函数,我们可以定义一个特征函数集合,用这个特征函数集合来为一个标注序列打分,并据此选出最靠谱的标注序列。也就是说,每一个特征函数都可以用来为一个标注序列评分,把集合中所有特征函数对同一个标注序列的评分综合起来,就是这个标注序列最终的评分值。【基本原理】
定义CRF中的特征函数
所谓特征函数,就是这样的函数,它接受四个参数:
-
句子 s s s(就是我们要标注词性的句子)
-
i i i表示句子 s s s中第 i i i个单词
-
l i l_i li表示要评分的标注序列给第 i i i个单词标注的词性
-
l i − 1 l_{i-1} li−1表示要评分的标注序列给第 i − 1 i-1 i−1个单词标注的词性
它的输出值是0或者1,0表示要评分的标注序列不符合这个特征,1表示要评分的标注序列符合这个特征。
Note:这里,我们的特征函数仅仅依靠当前单词的标签和它前面的单词的标签对标注序列进行评判,这样建立的CRF也叫作线性链CRF,这是CRF中的一种简单情况。为简单起见,本文中我们仅考虑线性链CRF。
定义好一组特征函数后,我们要给每个特征函数
f
j
f_j
fj赋予一个权重
λ
j
λ_j
λj。现在,只要有一个句子
s
s
s,有一个标注序列
l
l
l,我们就可以利用前面定义的特征函数集来对
l
l
l评分。
score
(
l
∣
s
)
=
∑
j
=
1
m
∑
i
=
1
n
λ
j
f
j
(
s
,
i
,
l
i
,
l
i
−
1
)
\operatorname{score}(l | s)=\sum_{j=1}^{m} \sum_{i=1}^{n} \lambda_{j} f_{j}\left(s, i, l_{i}, l_{i-1}\right)
score(l∣s)=j=1∑mi=1∑nλjfj(s,i,li,li−1)
上式中有两个求和,外面的求和用来求每一个特征函数 f j f_j fj评分值的和,里面的求和用来求句子中每个位置的单词的的特征值的和。
对这个分数进行指数化和标准化,我们就可以得到标注序列
l
l
l的概率值
p
(
l
∣
s
)
p(l|s)
p(l∣s),如下所示:
p
(
l
∣
s
)
=
exp
[
score
(
l
∣
s
)
]
∑
l
′
exp
[
score
(
l
′
∣
s
)
]
=
exp
[
∑
j
=
1
m
∑
i
=
1
n
λ
j
f
j
(
s
,
i
,
l
i
,
l
i
−
1
)
]
∑
l
′
exp
[
∑
j
=
1
m
∑
i
=
1
n
λ
j
f
j
(
s
,
i
,
l
i
′
,
l
i
−
1
′
)
]
p(l | s)=\frac{\exp [\operatorname{score}(l | s)]}{\sum_{l^{\prime}} \exp \left[\operatorname{score}\left(l^{\prime} | s\right)\right]}=\frac{\exp \left[\sum_{j=1}^{m} \sum_{i=1}^{n} \lambda_{j} f_{j}\left(s, i, l_{i}, l_{i-1}\right)\right]}{\sum_{l^{\prime}} \exp \left[\sum_{j=1}^{m} \sum_{i=1}^{n} \lambda_{j} f_{j}\left(s, i, l_{i}^{\prime}, l_{i-1}^{\prime}\right)\right]}
p(l∣s)=∑l′exp[score(l′∣s)]exp[score(l∣s)]=∑l′exp[∑j=1m∑i=1nλjfj(s,i,li′,li−1′)]exp[∑j=1m∑i=1nλjfj(s,i,li,li−1)]
几个特征函数的例子:
当
l
i
l_i
li是“副词”并且第i个单词以“ly”
结尾时,我们就让
f
1
=
1
f_1 = 1
f1=1,其他情况
f
1
f_1
f1为0。不难想到,f1特征函数的权重
λ
1
λ_1
λ1应当是正的。而且
λ
1
λ_1
λ1越大,表示我们越倾向于采用那些把以“ly”
结尾的单词标注为“副词”的标注序列
f
1
(
s
,
i
,
l
i
,
l
i
−
1
)
=
1
f_{1}\left(s, i, l_{i}, l_{i-1}\right)=1
f1(s,i,li,li−1)=1
如果 i=1,
l
i
l_i
li=动词,并且句子s是以“?”结尾时,
f
2
f_2
f2=1,其他情况
f
2
f_2
f2=0。同样,
λ
2
λ_2
λ2应当是正的,并且λ2越大,表示我们越倾向于采用那些把问句的第一个单词标注为“动词”的标注序列。
f
2
(
s
,
i
,
l
i
,
l
i
−
1
)
=
1
f_{2}\left(s, i, l_{i}, l_{i-1}\right)=1
f2(s,i,li,li−1)=1
小结
为了建一个条件随机场,我们首先要定义一个特征函数集,每个特征函数都以整个句子 s,当前位置
i
i
i,位置
i
i
i 和
i
−
1
i-1
i−1 的标签为输入。然后为每一个特征函数赋予一个权重,然后针对每一个标注序列
l
l
l,对所有的特征函数加权求和,必要的话,可以把求和的值转化为一个概率值。
2.1 CRF与逻辑回归的比较
条件随机场是逻辑回归的序列化版本。逻辑回归是用于分类的对数线性模型,条件随机场是用于序列化标注的对数线性模型。
2.2 CRF与HMM的比较
对于词性标注问题,HMM模型也可以解决。HMM的思路是用生成办法,就是说,在已知要标注的句子s的情况下,去判断生成标注序列
l
l
l的概率,如下所示观测序列和状态序列的联合概率分布为:
p
(
l
,
s
)
=
p
(
l
1
)
∏
i
p
(
l
i
∣
l
i
−
1
)
p
(
w
i
∣
l
i
)
p(l, s)=p\left(l_{1}\right) \prod_{i} p\left(l_{i} | l_{i-1}\right) p\left(w_{i} | l_{i}\right)
p(l,s)=p(l1)i∏p(li∣li−1)p(wi∣li)
p ( l i ∣ l i − 1 ) p(l_i|l_{i-1}) p(li∣li−1)是转移概率,比如, l i − 1 l_{i-1} li−1是介词, l i l_i li 是名词,此时的p表示介词后面的词是名词的概率。
p ( w i ∣ l i ) p(w_i|l_i) p(wi∣li)表示发射概率(emission probability),比如 l i l_i li是名词, w i w_i wi是单词“ball”,此时的p表示在是名词的状态下,是单词“ball”的概率。
CRF比HMM要强大的多,它可以解决所有HMM能够解决的问题,并且还可以解决许多HMM解决不了的问题。事实上,我们可以对上面的HMM模型取对数,就变成下面这样:
log
p
(
l
,
s
)
=
log
p
(
l
0
)
+
∑
i
log
p
(
l
i
∣
l
i
−
1
)
+
∑
i
log
p
(
w
i
∣
l
i
)
\log p(l, s)=\log p\left(l_{0}\right)+\sum_{i} \log p\left(l_{i} | l_{i-1}\right)+\sum_{i} \log p\left(w_{i} | l_{i}\right)
logp(l,s)=logp(l0)+i∑logp(li∣li−1)+i∑logp(wi∣li)
把这个式子与CRF的式子进行比较:
score
(
l
∣
s
)
=
∑
j
=
1
m
∑
i
=
1
n
λ
j
f
j
(
s
,
i
,
l
i
,
l
i
−
1
)
\operatorname{score}(l | s)=\sum_{j=1}^{m} \sum_{i=1}^{n} \lambda_{j} f_{j}\left(s, i, l_{i}, l_{i-1}\right)
score(l∣s)=j=1∑mi=1∑nλjfj(s,i,li,li−1)
不难发现,如果我们把第一个HMM式子中的log形式的概率看做是第二个CRF式子中的特征函数的权重的话,我们会发现,CRF和HMM具有相同的形式。
换句话说,我们可以构造一个CRF,使它与HMM的对数形式相同。怎么构造呢?
对于HMM中的每一个转移概率
p
(
l
i
=
y
∣
l
i
−
1
=
x
)
p(l_i=y|l_{i-1}=x)
p(li=y∣li−1=x),我们可以定义这样的一个特征函数:
f
x
,
y
(
s
,
i
,
l
i
,
l
i
−
1
)
=
1
f_{x, y}\left(s, i, l_{i}, l_{i-1}\right)=1
fx,y(s,i,li,li−1)=1
该特征函数仅当
l
i
=
y
l_i = y
li=y,
l
i
−
1
=
x
l_{i-1}=x
li−1=x时才等于1。这个特征函数的权重如下:
w
x
,
y
=
log
p
(
l
i
=
y
∣
l
i
−
1
=
x
)
w_{x, y}=\log p\left(l_{i}=y | l_{i-1}=x\right)
wx,y=logp(li=y∣li−1=x)
同样的,对于HMM中的每一个发射概率,我们也都可以定义相应的特征函数,并让该特征函数的权重等于HMM中的log形式的发射概率。
CRF要比HMM更加强大,原因主要有两点:
CRF可以定义数量更多,种类更丰富的特征函数。HMM模型天然具有局部性,就是说,在HMM模型中,当前的单词只依赖于当前的标签,当前的标签只依赖于前一个标签。这样的局部性限制了HMM只能定义相应类型的特征函数,我们在上面也看到了。但是CRF却可以着眼于整个句子s定义更具有全局性的特征函数
3. LSTM+CRF
LSTM已经可以胜任序列标注问题了,为每个token预测一个label(LSTM后面接:分类器);而CRF也是一样的,为每个token预测一个label。
他们的预测机理是不同的。CRF是全局范围内统计归一化的条件状态转移概率矩阵,再预测出一条指定的sample的每个token的label;LSTM(RNNs,不区分here)是依靠神经网络的超强非线性拟合能力,在训练时将samples通过复杂到让你窒息的高阶高纬度异度空间的非线性变换,学习出一个模型,然后再预测出一条指定的sample的每个token的label。
然LSTM都OK了,为啥researchers搞一个LSTM+CRF的hybrid model?
a single LSTM预测出来的标注是有问题的,如下:
input: "学习出一个模型,然后再预测出一条指定"
expected output: 学/B 习/E 出/S 一/B 个/E 模/B 型/E ,/S 然/B 后/E 再/E 预/B 测/E ……
real output: 学/B 习/E 出/S 一/B 个/B 模/B 型/E ,/S 然/B 后/B 再/E 预/B 测/E ……
用LSTM,整体的预测accuracy是不错,但是会出现上述的错误:在B之后再来一个B。这个错误在CRF中是不存在的,因为CRF的特征函数的存在就是为了对given序列观察学习各种特征(n-gram,窗口),这些特征就是在限定窗口size下的各种词之间的关系。然后一般都会学到这样的一条规律(特征):B后面接E,不会出现E。这个限定特征会使得CRF的预测结果不出现上述例子的错误。当然了,CRF还能学到更多的限定特征。
把CRF接到LSTM上面,LSTM在timestep上把每一个hiddenstate的tensor输入给CRF,让LSTM负责在CRF的特征限定下,依照新的loss function,学习出一套新的非线性变换空间。
4. HMM vs. MEMM vs. CRF
HMM -> MEMM: HMM模型中存在两个假设:一是输出观察值之间严格独立,二是状态的转移过程中当前状态只与前一状态有关。但实际上序列标注问题不仅和单个词相关,而且和观察序列的长度,单词的上下文,等等相关。MEMM解决了HMM输出独立性假设的问题。因为HMM只限定在了观测与状态之间的依赖,而MEMM引入自定义特征函数,不仅可以表达观测之间的依赖,还可表示当前观测与前后多个状态之间的复杂依赖。
MEMM -> CRF:CRF不仅解决了HMM输出独立性假设的问题,还解决了MEMM的标注偏置问题,MEMM容易陷入局部最优是因为只在局部做归一化,而CRF统计了全局概率,在做归一化时考虑了数据在全局的分布,而不是仅仅在局部归一化,这样就解决了MEMM中的标记偏置的问题。使得序列标注的解码变得最优解。
HMM、MEMM属于有向图,所以考虑了x与y的影响,但没讲x当做整体考虑进去(这点问题应该只有HMM)。CRF属于无向图,没有这种依赖性,克服此问题。