PCFG中inside和outside算法详解

原文链接:

PCFG中inside和outside算法详解 - WeiYang Blog

inside-outside算法是用来预测一棵句法分析树的概率的算法,算法建立在文法是乔姆斯基范式(CFG)的基础之上,CFG的定义见维基百科。一棵句法分析树的potential定义为它包含的产生式的potential乘积,在PCFG中表示概率,在CRF-CFG中表示特征集合的分数。

inside-outside算法需要定义两个变量:

  • alpha (A,i,j) 定义为内部的potential之和,即以 A 为根结点,短语为 {x_{i;j}} 的所有可能的子树的potential之和。
  • eta (A,i,j) 定义为外部的potential之和,即以 A 为根结点,短语为 {x_{1;i - 1}}A{x_{j + 1;n}} 的所有可能的子结构的potential之和。

给定文法CFG,输入字符串 {x_{1;n}},计算inside和outside值。

inside

初始化:
如果 A 	o {x_i} in R ,那么 alpha (A,i,i) = varphi (A 	o {x_i},i,i,i) 。否则就等于0。
其中 varphi (A 	o {x_i},i,i,i) 为potential值。

类似于CKY算法,自底向上计算inside值:
alpha (A,i,j) = sumlimits_{A 	o BC in R} {sumlimits_{k = i}^{j - 1} {varphi (A 	o BC,i,k,j) cdot alpha (B,i,k) cdot alpha (C,k + 1,j)} }

outside

初始化:
eta (S,1,n) = 1 ,其余都等于0。

outside值要分为两部分计算:

v2-ae97fe3e101494c1c29c27dbcc7ffbd9_b.jpg

第一部分是 {B 	o AC} ,如上图所示。

v2-54125b91639928e788c8729f02934d4a_b.jpg

第二部分是 {B 	o CA} ,如上图所示。

和inside相反,通过自顶向下计算outside值:
egin{array}{l}eta (A,i,j) = sumlimits_{B 	o AC in R} {sumlimits_{k = j + 1}^n {varphi (B 	o AC,i,j,k) cdot eta (B,i,k) cdot alpha (C,j + 1,k)} } \ + sumlimits_{B 	o CA in R} {sumlimits_{k = 1}^{i - 1} {varphi (B 	o CA,k,i - 1,j) cdot eta (B,k,j) cdot alpha (C,k,i - 1)} } end{array}

应用

所有可能的句法树potential之和为:
{Z_s} = alpha (S,1,n)
包含产生式 (A 	o BC,i,k,j) 的所有可能句法树potential之和是:
mu (A 	o BC,i,k,j) = varphi (A 	o BC,i,k,j) cdot eta (A,i,j) cdot alpha (B,i,k) cdot alpha (C,k + 1,j)
存在非终结符 A ,且短语是 {x_{i;j}} 的所有可能句法树potential之和是:
mu (A,i,j) = alpha (A,i,j) cdot eta (A,i,j)

PCFG参数估计

参数估计的目的就是为了估计出PCFG的概率 P ,使得所有句子的概率之和最大,采用的是EM迭代法。
首先定义:
varphi (A 	o BC,i,k,j) = P(A 	o BC)
这里 P(A 	o BC) 是随机初始化的,满足归一化条件就行。
对于语料库的每一条句子,可以计算出:
egin{array}{l}count(A 	o BC) = frac { {sumlimits_{i,k,j} {mu (A 	o BC,i,k,j)} }}{ { {Z_s}}}\P(A 	o BC) = frac{ {count(A 	o BC)}}{ {sumlimits_r {count(r)} }}end{array}
然后算出期望,更新概率,迭代就行了。

CRF-CFG参数估计

首先定义:
varphi (A 	o BC,i,k,j) = exp sumlimits_t { {	heta _t}{f_t}(A 	o BC,i,k,j)}
其中 f_t 为特征函数。
那么我们的目的就是训练特征参数 	heta
然后定义似然函数为

L(D;	heta ) = sumlimits_{(t,s) in D} {left( {sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s) - {Z_s}} } } 
ight)} + sumlimits_i {frac{ {	heta _i^2}}{ {2{sigma ^2}}}}

求偏导为

frac{ {partial L(D;	heta )}}{ {partial {	heta _i}}} = sumlimits_{(t,s) in D} {(sumlimits_{r in t} { {f_i}(r,s)} - {E_	heta }[{f_i}|s])} + frac{ { {	heta _i}}}{ { {sigma ^2}}}

这里可能有人看不懂,似然函数和偏导是怎么来的呢?下面我详细写一下过程。

似然函数:

egin{array}{l}L(D;	heta ) = sumlimits_{(t,s) in D} {log frac{ {exp sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } }}{ {sumlimits_{t in T(s)} {exp sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } } }}} + sumlimits_i {frac{ {	heta _i^2}}{ {2{sigma ^2}}}} \ = sumlimits_{(t,s) in D} {left( {sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } - log sumlimits_{t in T(s)} {exp sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } } } 
ight)} + sumlimits_i {frac{ {	heta _i^2}}{ {2{sigma ^2}}}} \ = sumlimits_{(t,s) in D} {left( {sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } - {Z_s}} 
ight)} + sumlimits_i {frac{ {	heta _i^2}}{ {2{sigma ^2}}}} end{array}

所以偏导为:

frac{ {partial L(D;	heta )}}{ {partial {	heta _i}}} = sumlimits_{(t,s) in D} {left( {sumlimits_{r in t} { {f_i}(r,s)} - frac{ {partial left( {log sumlimits_{t in T(s)} {exp sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } } } 
ight)}}{ {partial {	heta _i}}}} 
ight)} + frac{ { {	heta _i}}}{ { {sigma ^2}}}

egin{array}{l}frac{ {partial left( {log sumlimits_{t in T(s)} {exp sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } } } 
ight)}}{ {partial {	heta _i}}}\ = frac{ {sumlimits_{t in T(s)} {left( {left( {exp sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } } 
ight) cdot sumlimits_{r in t} { {f_i}(r,s)} } 
ight)} }}{ {sumlimits_{t in T(s)} {exp sumlimits_{r in t} {sumlimits_i { {	heta _i}{f_i}(r,s)} } } }}\ = {E_	heta }[{f_i}|s]end{array}

所以偏导就是这么来的。

原文地址:https://www.cnblogs.com/godweiyang/p/12203927.html