IBM Model1
IBM Model 是统计机器翻译中的经典翻译模型
IBM Model1仅考虑了词和词之间的互译概率
记录学习lecture-ibm-model1的过程
学习
- 外来句子, foreign sentence ,长度为
- 英文句子, english sentence ,长度为
- a, alignment 外来句子中的词和英文句子中的词的对应关系,假设英文句子中的对应外来句子中的(相同意思),则对应关系为
- 目标函数,,以给定的外来和英语为条件,找出其alignment
- 参数估计,EM算法
假设是需要将外来句子翻译成英文句子
目标函数
pdf中先给出了一个公式
一开始看,懵了,怎么突然来这么一个公式,这公式什么意思
很多地方都是直接这样一个公式都不知道为什么,也不知道什么是什么,增加了小白我学习的难度,唉,泪啊
目标是要翻译成英文句子,那么每个英文单词有其对应的外文单词
, a_1 表示第1个英文单词对应的外文句子中对应单词的位置,每个值的范围为
从0开始的原因是因为,万一有个英文词找不到对应的外文词,比如语气词之类的,可以在外文句前加个NULL
使得外文句长为
英文单词有个,所以有个对应关系 相当于给定翻译成的概率,可以看这篇
对于pdf中的图
la翻译成the的可能性为0.7
masion翻译成house的可能性为0.8
那么第一种情况是这两者同时翻译根据贝叶斯定理
那么需要计算
根据pdf
因为英文单词有个,所以a的对应有个
所以第二个等式中每一个表示每个外文单词翻译到第i个英文单词的概率和,然后再乘起来然后等式可以继续化下去
然后在看第二个等式到第三个等式
拿上面翻译的例子推了下,嗯,是正确的
可以按照写的式子
然后有了目标式子
则第一种对应关系
计算正确
到这里,目标函数的推导应该差不多了
参数估计
接着是这么一个公式,这公式又是啥?
查了一些资料
是训练数据中,外语单词f与英文单词e正确匹配的概率
表示不同的外文词f翻译成词e的概率和
表示在句子e中的期望次数
表示在句子e中的期望次数
表示词f到词e的个数(好吧,不懂)举个例子
初始情况下,一个外语单词对所有英语单词的翻译的可能性是相同的
假设中文为外语f,需要翻译成英语e。免得把一些符号搞晕
然后按照公式推了下,拍的图片可能有点糊,但不影响
忘记写c(e)了。在语料1,a1的情况下, c(a)就相当于分母
然后继续计算下去,虽然不知道这些公式是怎么来的,但概率矩阵也的确按照理想的变化在变化
代码
伪代码
python 代码
# 语料库
corpus = [[['一本','书'],['a','book']],[['一本', '杂志'],['a', 'magazine']]]
# 设置英文外文词汇表
english_vocab = []
foreign_vocab = []
for sp in corpus:
for fw in sp[0]:
foreign_vocab.append(fw)
for ew in sp[1]:
english_vocab.append(ew)
english_words = sorted(list(set(english_vocab)), key=lambda s:s.lower())
foreign_words = sorted(list(set(foreign_vocab)), key=lambda s:s.lower())
print('English words:\n', english_vocab)
print('Foreign words:\n', foreign_vocab)
# 给定e,f句子和t,计算p(e|f)
def probability_e_f(e, f, t, epsilon=1):
l_e = len(e)
l_f = len(f)
p_e_f = 1
for ew in e:
t_ej_f = 0
for fw in f:
t_ej_f += t[fw][ew]
p_e_f = t_ej_f * p_e_f
p_e_f = p_e_f * epsilon / ((l_f+1)**l_e)
return p_e_f
# 输入语料库计算perplexity
def perplexity(corpus, t, epsilon=1):
log2pp = 0
for sp in corpus:
prob = probability_e_f(sp[1], sp[0], t)
log2pp += math.log(prob, 2)
pp = 2.0 **(-log2pp)
return pp
t = {} # 用来保存不同外文单词翻译成不同英文单词的概率
init_val = 1.0/len(english_words) # 初始情况下,一个外文单词翻译成不同英文单词的概率是相同的
for fw in foreign_words:
for ew in english_words:
if fw not in t:
t[fw] = {}
t[fw][ew] = init_val
print('\nInit t ')
for fw in t:
print('Foreign word: ', fw)
sorted_list = sorted(t[fw].items(), key=lambda x:x[1], reverse=True)
for (ew, p) in sorted_list:
print('prob to %s \tis %f'%(ew, p))
print('')
num_epochs = 10
s_total = {}
perplexities = []
for epoch in range(num_epochs):
print("--------epoch % s--------" % (epoch + 1))
perplexities.append(perplexity(corpus, t))
count = {}
total = {}
for fw in foreign_words:
total[fw] = 0.0
for ew in english_words:
if fw not in count:
count[fw] = {}
count[fw][ew] = 0.0
for sp in corpus:
# s_total[a]相当于上面手工推演中的t(a|一本)+t(a|书)
# s_total也就相当于c(e)
for ew in sp[1]:
s_total[ew] = 0.0
for fw in sp[0]:
s_total[ew] += t[fw][ew]
# 此时计算出的count[一本][a]相当于c(a|一本),在不同语料中继续相加相同对应的概率
# total[一本]相当于一本翻译成不同英文词的概率和
# 还要考虑不同语料,主要用于t概率矩阵的归一化
for ew in sp[1]:
for fw in sp[0]:
count[fw][ew] += t[fw][ew] / s_total[ew]
total[fw] += t[fw][ew] / s_total[ew]
# 概率的归一化,使得一个外文单词翻译成不同英文单词的概率和为1
for fw in foreign_words:
for ew in english_words:
t[fw][ew] = count[fw][ew] / total[fw]
for fw in t:
print('foreign word: ', fw)
sorted_list = sorted(t[fw].items(), key=lambda x:x[1], reverse=True)
for (ew, p) in sorted_list:
print('prob to %s \tis %f'%(ew, p))
print('')
plt.plot(perplexities) # 需要matplotlib库
嗯~ ,貌似这样就完成了model1
按照代码我又推了一遍,很好的符合了上面手推的过程
至于那些个公式是怎么来的,不知道
听从pdf的指示(我是小白)
至于如何衡量模型,那么就是困惑度 perplexity
pdf中给出了公式 ,并且写在了代码中
参考资料
- lecture-ibm-model1
- mt2
- https://zhuanlan.zhihu.com/p/72160554
- http://blog.sina.com.cn/s/blog_6335d3b00100w4ch.html
- https://zhuanlan.zhihu.com/p/72640549
- 应该还有一些,忘记保存了