IBM model是统计机器翻译中的经典翻译模型,也是基于词的统计机器翻译系统的基础。IBM翻译模型共有5个复杂度依次递增的统计翻译模型,IBM model1是其中最简单的模型,也是其他模型进行计算的基础。IBM模型1仅仅考虑词对词的互译概率,模型2引入了词的位置变化概率,而模型3加入一个词翻译成多个词的概率。
为翻译模型建模
假设任意一个英语句子e和法语句子f,定义f翻译成e的概率为P(e|f),于是将f翻译成e的问题则变成求解
根据噪声信道模型,统计机器翻译要寻找e使得满足公式(1)。
IBM模型注意到翻译模型中的一个隐含变量信息,及即句子中词语的对位信息:对齐A。于是有:
假设英文串e的长度为l,记做。法语串f的长度为m,记做。则对齐a可以由一串包含有个值的位置信息记录,表示法语句子中单词对应英语句子单词的位置。,每个值的取值范围为。因此,
具体的证明参考http://luowei828.blog.163.com/blog/static/31031204201123010316963/
该公式可以理解为:根据英文句子生成一个法语句子以及对齐过程。首先根据英文句子选择法语句子长度,其次选择第一个法语词串的链接位置,然后根据英语句子、法语句子长度、法语句子第一个词对应英语句子的位置选择法语句子的第一个词(比较拗口-_-!)。由此类推,则可以生成整个法语句子。
引出IBM模型1
IBM模型1对公式(3)进行化简,并做出如下假设:
1)假设P(m|e)与目标语言e和源语言长度m无关。
带入(3)中可得
由于每个对齐变量的取值范围均为 ,则(2)可改写为
在引入拉格朗日因子后,求解翻译概率极大值问题转换为求辅助函数在无限定条件下的极大值问题。辅助函数的形式为
上式对t(f|e)求偏导,得
令(7)为0,则有
借助(4)式,则(8)式可改写为
实际训练数据往往由一系列的翻译对组成,如。因此等式(11)变为
公式(5)的右侧部分可以进行化简,具体方法解释参见[Brown, 2003]。根据模型1的特点,可得
于是,公式(5)则改写为
将上式带入(8)求偏导,得到
其中,表示翻译对f在句子f中的count数。同理,表示翻译对e在句子e中的count数。
IBM模型的EM算法
利用公式(12)和(15)即可完成对参数t(f|e)的估计。具体方法如下:
1) 选择的t(f|e)的初始概率。
b) 为每个在句子中的单词f,利用公式(12)计算得到新的t(f|e)。
4)重复2)、3)步骤,直到t(f|e)趋于期望值。
GIZA++实现了IBM模型1~5的所有代码,在生成源语言与目标语言之间翻译概率的同时,也产生相应的副产品——“词对齐”。这个副产品成为各种统计机器翻译系统的基石,直到今天,大部分系统仍然首先使用GIZA++对大量平行语料进行词对齐。在阿拉伯语、中文等语言与印欧语系语言的对齐中错误率仍然很高。特别是中文,错误率常常达到30%以上。
这里主要对GIZA++开源代码中的IBM model1实现部分进行总结,同时对词对齐技术进行简单的介绍。
GIZA++中的IBM model1源代码解析
通过对GIZA++开源代码进行剥离,仅仅保留IBM model1相关部分的代码。则训练部分的核心代码为
double StartTraining(int& result) { //开始训练对齐……
读取中英文词汇表 //eTrainVcbList.readVocabList();
读取中英文平行语料信息
新建辞典
构造IBM model1
EM算法迭代
生成词对齐信息
输出计算结果
}
其中,EM算法迭代是整个训练过程的核心代码。在介绍算法迭代源码之前,首先对IBM模型1的数据结构进行简单的介绍。
IBM model1主要数据结构
class model1 : public report_info{
public:
string efFilename;
vcbList& Elist ;
vcbList& Flist ;
float eTotalWCount ; // size of source copus in number of words
float fTotalWCount ; // size of target corpus in number of words
int noEnglishWords;
int noFrenchWords;
tmodel
Vector
Vector
public:
void initialize_table_uniformly();
int em_with_tricks();
private:
void em_loop();
};
模型1最重要(应该是唯一)的参数就是词汇的翻译概率,其数据保存在tmodel类中。tmodel类的核心数据为hash_map ef。
hash_map的每个单元可以简单表示为
struct{
WordIndex;
WordIndex;
Prob;
Count;
}
即源语言、目标语言词汇ID,二者的翻译概率以及同现count数目。
其它诸如vcbList表示词汇列表信息,而Vector
IBM model1核心算法
int em_with_tricks(int noIterations, bool seedModel1, Dictionary& dictionary, bool useDict)
em_with_tricks()是整个迭代算法的核心部分。输入变量noIterations表示循环迭代次数,默认值为5;seedModel1还不是很清楚;useDict表示是否加入词典。该函数的代码部分主要包括
int em_with_tricks(){
for(int it = 1; it <= noIterations; it++){
初始化对齐信息 //initAL();
em迭代 //em_loop();
归一化条件概率 // tTable.normalizeTable(Elist, Flist);
}
}
在每次循环过程中,均会调用em_loop()函数,对读入的每一个句子对,根据tTable中的prob值,计算在这个句子对中,互为翻译对出现的count数目,进而改变tTable中的count值。当所有句子对读完后,根据count改变prob信息,从而完成一次循环。
void em_loop(int it, Perplexity& perp, sentenceHandler& sHandler1, bool seedModel1,
bool dump_alignment, const char* alignfile, Dictionary& dict, bool useDict, Perplexity& viterbi_perp, bool test)
em_loop()在每次循环的过程中均会被调用,一次迭代过程在em_loop()中实现。it表示迭代次数id,perp表示概率信息,viterbi_perp表示viterbi概率。函数的主要实现部分包括
void em_loop(){
while(sHandler1.getNextSentence(sent)){ //获得句子对信息
for(j=1; j <= m; j++){
//entries that map fs to all possible ei in this sentence.
if (it == 1 && !seedModel1){
第一次迭代则获得默认的初始概率
}
else{
for((i=0),(sPtrCachePtr=&sPtrCache[0]); i <= l; i++,sPtrCachePtr++){
修改对应的翻译概率,并记录最优概率对应的位置
}
}
记录最优概率位置并计算交叉熵
cross_entropy += log(denom); //这里的log是以e为底
for(i=0, (sPtrCachePtr=&sPtrCache[0]); i <= l; i++,sPtrCachePtr++){
统计翻译对增加的count数目
}
}
增加prep以及viterbi_perp困惑度因子
计算句子的词对齐
}
}
以上是