1. CRF的三大核心问题概述
一个训练好的概率模型,通常需要回答以下几个基本问题。对于CRF,这三大问题是:
-
概率计算问题:
- 问题描述:给定观测序列 和标签序列 ,计算条件概率 。这个问题本身不太常用,但它的副产品——计算归一化因子 ——却是重中之重(为什么这么说呢?)。此外,计算某些边缘概率,如“序列第 个位置的标签是名词的概率” ,也属于此类问题。
- 核心算法:前向-后向算法 (Forward-Backward Algorithm)。
-
解码问题:
-
问题描述:给定观测序列 ,在所有可能的标签序列中,找到使条件概率 最大的那一条序列 。这通常是我们最关心的应用问题,比如为一句话找到最可能的词性标注序列。
-
核心算法:维特比算法 (Viterbi Algorithm)。
-
-
学习问题:
- 问题描述:给定一个训练数据集(包含观测序列和对应的真实标签序列),学习出模型的参数 。
- 核心算法:通常使用基于梯度的优化算法,如L-BFGS。我们将在后续详细讨论。
本文将聚焦于前两个问题。我们会发现,这两个问题的解决方法都巧妙地运用了动态规划 (Dynamic Programming) 的思想来避免暴力计算。
2. 概率计算问题:前向-后向算法
挑战: 的计算
回顾一下CRF的定义:。要计算这个概率,我们必须先求出归一化因子 。根据定义:
假设句子长度 ,标签种类 (比如,名词、动词、代词、介词、形容词)。那么总的标签序列数量为 ,这是一个天文数字。(是不是让你想起HMM的求解来了?)暴力遍历所有路径来求和是绝对不可行的。
前向算法
前向算法的核心思想是:与其在最后把所有路径的和加起来,不如每向前走一步,就把到达当前节点的所有路径的和计算出来并存起来,供下一步使用。
我们定义前向变量 :
的含义:在观测序列 的条件下,从序列开始到位置 ,且位置 的标签为 的所有部分路径的非归一化概率之和。
这里的“非归一化概率”就是路径上所有势函数的乘积。
前向变量的递推
让我们来推导 是如何计算的。
-
初始化 (t=1): 对于第一个位置,我们定义一个虚拟的起始状态 。那么,到达位置1且标签为 的路径只有一条,其非归一化概率就是势函数 的值。
-
递推 (t > 1): 要计算 ,我们需要考虑所有能够到达“位置 且标签为 ”的路径。这些路径必然是从前一个位置 的某个标签 转移过来的。
对于任意一个前一状态 ,到达它的所有路径的非归一化概率之和已经被我们计算并储存在 中了。从 转移到 的这一小步,其分值为 。
因此,所有经过“ 位置标签为 ”并到达“ 位置标签为 ”的路径的总分就是 。
我们把所有可能的前一状态 的情况都加起来,就得到了 :
这个过程可以用矩阵形式清晰地表示。如果我们把 看作一个行向量 ,把 看作在矩阵形式中定义的转移矩阵,那么:
使用前向变量计算
当我们一路递推到最后一个位置 时,我们就得到了所有终点为 的路径的非归一化概率之和 。把所有可能的终点 的情况加起来,就得到了所有路径的总和,这正是 !
(注:更严谨地,通常会再乘以一个从 到虚拟终止状态 的势函数,这里为简化暂不写出。)
通过这种方式,我们将指数级的计算复杂度降低到了 ,这是完全可以接受的。
后向算法
与前向算法类似,我们也可以从后往前定义后向变量 :
的含义:在观测序列 的条件下,从位置 的标签为 开始,一直到序列结束的所有部分路径的非归一化概率之和。
后向变量的递推
-
初始化 (t=T): 我们定义一个虚拟的终止状态 。
-
递推 (t < T):
矩阵形式为:
结合前向-后向变量计算边缘概率
前向和后向变量结合起来非常强大。例如,我们可以计算在 时刻标签为 的概率 。 任何一条在 时刻经过标签 的完整路径,其非归一化概率必然等于“从开始到 位置标签 的前半段路径”的概率,乘以“从 位置标签 到结尾的后半段路径”的概率。 因此,所有经过 时刻标签 的路径总分是 。 再用全局的 进行归一化,就得到了边缘概率:
(有没有觉得和 5.1 单个状态的概率:很像啊) 同理,我们也可以计算边的边缘概率 ,这在学习算法中至关重要:
3. 解码问题:维特比算法
现在我们来解决最常用的解码问题:找到最优的标签序列 。
一个天真的想法是:我们用前向-后向算法计算出每个位置 最可能的标签 ,然后把它们拼起来。这是错误的! 这样得到的序列很可能不是一个合法的、全局最优的序列。(跟HMM的近似算法一样一样的)例如,可能在 时刻“代词”概率最高,在 时刻“名词”概率最高,但“代词-名词”这个转移本身的概率可能极低。
我们需要一个寻找全局最优路径的算法。这就是维特比算法。
维特比算法 vs. 前向算法
维特比算法的思路和前向算法几乎一模一样,都是动态规划。唯一的区别是:
- 前向算法在递推时,将所有可能路径的得分用
sum加起来。 - 维特比算法在递推时,只保留所有可能路径中得分最高的那条,即用
max操作。
我们定义维特比变量 :
的含义:在观测序列 的条件下,从序列开始到位置 ,且位置 的标签为 的所有部分路径中,得分最高的那条路径的非归一化概率。
同时,我们还需要一个回溯指针 来记录这条最优路径是从前一个时刻的哪个状态转移过来的。
维特比算法的递推
- 初始化 (t=1):
- 递推 (t > 1): 要计算 ,我们考虑所有可能的前一状态 。对于每一个 ,从它转移到 的路径得分是 。我们在所有 中找到使这个值最大的那个: 同时,我们记录下这个最大值是从哪个 来的:
终止与回溯 (Backtracking)
-
终止:当递推到最后一个位置 时,我们找到最终的最优路径得分和终点:
-
回溯:我们已经知道了最优路径的最后一个标签是 。那么,它前一个标签是什么呢?我们只需查找回溯指针:
然后继续往前找:
如此反复,直到找到路径的起点。这样,我们就重建了整条最优路径 。
维特比算法的计算复杂度同样是 ,非常高效。
总结
在本报告中,我们攻克了CRF的两个核心推断问题:
- 概率计算:我们学习了前向-后向算法,它利用动态规划高效地计算归一化因子 以及各个节点和边的边缘概率,为学习算法打下了基础。
- 解码:我们学习了维特比算法,它同样利用动态规划,通过
max操作和回溯指针来高效地找出全局最优的标签序列。
至此,我们已经掌握了如何使用一个训练好的CRF。在后续 条件随机场(CRF)(四):学习算法 中,我们将解答最后一个问题:CRF模型本身是如何从数据中学习出来的?