本文是在Niutrans论坛中的系列教程中总结出来的。
预处理的结果是生成双语分词之后的文件,该步需要注意的是对规则短语,比如数字、日期、网址等,进行泛化处理。可以用正则方法或者其它方法。注意日期中的点和外文人名中的点和网址中的点和句末标点要区分开来,数字和日期也要区分开来。
其中变化比较大的,比较难处理的,应该是中文的日期,因为它的格式比较多变。从文本中抽取出来中文日期时间(或者更进一步的转化成标准的时间格式),有一个办法,就是用trie树进行抽取,相较于写一大堆翻乱的正则表达式而言,它具有逻辑清晰,扩展简单,代码复杂度低的优点。具体算法过程会在后续的文章中详细解说。就SMT的具体功能而言,在这一步其实只要把稍微规则的时间格式,比如2014-11-7,13:15这类的格式泛化出来就可以了;像诸如【三月8号下午6点半】【后天晚上7点】这类的,没必要也泛化出来,其中包含的数字泛化出来即可,对结果的准确性影响不大。
在泛化之后的双语中(特指不同种语言,比如中英文),最好检查一下泛化的一致性,比如在中文中有多少个数字,英文中也要有对应的数目,时间日期网址等的个数也要相等。
而在文白双语中,因为古文的语法语义跟现在有出入,可以不做处理。这一步可以弱化甚至不做。即只需要简单的分词即可,古文的分词方法也需要斟酌,在实践中我们采取的是一元分词,即一字一词。
词对齐阶段使用GIZA++进行单向对齐(实现了IBM model 1~5,具体算法我也在学习中),然后结合两个单向对齐结果,利用对称算法生成最终的对齐结果。
对称算法大概是这样的,先根据两个结果生成一个矩阵。$M_{ij}$保存对齐结果:1)i与j双向对齐;2)i对齐j;3)j对齐i;4)i与j没有对齐。
1,把所有的1)节点加入结果集;
2,检查结果集的每个节点的前后左右邻居,有孤立无主的(即只与它相邻的2或者3情况),吸附过去;
3,剩下的孤立的2)或者3)也加入结果集。
完毕。图就不画了。
第二步词对齐结果生成一个bit矩阵,1代表对齐,2代表不对齐,其基本单位是第一步分词后的单个词。
该步可算是广义的词对齐,其单位是第二步的对此词对,基于生成的bit矩阵。目标是抽取出双语中的短语对。
短语对需要满足一致性要求。所谓一致性,可简单概括为封闭性和非空性。封闭性指的是短语中包含的词汇的对齐方必在另一个短语中,不外漏;非空性指短语对中至少含有一对单词是对齐了的。
在满足一致性要求下,给出短语对大长度,即可找出所有满足一致性要求的短语对。算法如下:
若要找出长度为len的短语对,对bit矩阵以len为窗口大小水平滑动,逐个check窗口中的短语对是否满足一致性要求,check的标准是窗口框定的集合中没有外部邻居即可。若遇到某列全0,以上列非零列所在行为行。
上一步抽取出来满足一致性的短语对,这一步对短语对的概率进行估计,用极大似然估计,公式大概如下(第一次用mathjax书写公式,看看效果):
\[ p\left(f|e\right)=\frac{count\left(e,f\right)}{count\left(e\right)}\]
这是短语翻译概率,出来两个概率。另外还有双向词汇化翻译概率,再出来两个概率。共4个概率。
这一步根据上一步的结果对短语进行调序,用到了语言模型。