语料处理规则:
在机器翻译中,一份好的语料会对翻译模型有很大的提升。但不同的研究人员都有不同的处理规则,本文选用小牛翻译的处理语料的规则方法。
(1)过滤掉单词长度超过100和单个单词字符的长度超过40的句子。
(2)过滤掉源语言和目标语言的长度比大于1/3的句子。
(3)过滤掉包含HTML标签的句子。
(4)过滤掉快速词对齐分数低于-6的句子
(5)标准化标点符号(例如全角转半角)
(6)过滤掉包含对向语料的句子。
##### 考虑到时间复杂度和程序执行的问题,本实验采用批量处理语料。
import jieba
##### 本实验室批量处理文件 #####
src = 'test.en' ### en
tgt = 'test.ch' ### zh
n_src = 'en.en'
n_tgt = 'ch.ch'
batch_size = 20
##### 将文件按批次读取 #####
##### file1(src)/file2(tgt) #####
def fun(file1,file2):
k=0
with open(file1,'r',encoding='utf-8') as fls:
with open(file2,'r',encoding='utf-8') as flt:
fl1 = fls.readlines()
fl2 = flt.readlines()
length = len(fl1)
ave = length//batch_size+1
for i in range(ave):
start = i*batch_size
end = start + batch_size
################################
funf(fl1[start:end],fl2[start:end])
print("从第%d行至第%d行已写入文件!!!!!",start,end)
##### 删除长度超过100和单词/单个单词额长度超过40个字符的句子 #####
def del_len(file1,file2):
def insert_100(seq1):
seq1 = seq1.strip('\n').split(' ')
flag1 = 0
k1 = 0
for word in seq1:
k1 += 1
if k1>=100:
flag1 = 1
else:
pass
return flag1
def insert_40(seq2):
flag2 = 0
seq2 = seq2.strip('\n').split(' ')
for word in seq2:
l = len(word)
if l>=40:
flag2 = 1
else:
pass
return flag2
def address(file):
k = 0 ## 记录行数
flag = 1 ## 标记
temp = []
for line in file:
flag1 = insert_100(line)
flag2 = insert_40(line)
if flag1 == 0 and flag2 == 0 :
flag = 0
temp.append([k,flag])
k+=1
return temp
temp = address(file1)
def fun(file):
lemp = []
num = 0
for line in file:
line = line.strip('\n')
for unit in temp:
if num==unit[0] and unit[1] == 0:
lemp.append(line)
continue
num += 1
return lemp
lemp1 = fun(file1) ## 源语言
lemp2 = fun(file2) ## 目标语言
return lemp1,lemp2
##### 过滤掉包含HTML的句子和重复翻译的句子 #####
##### 其返回值是一个字典 #####
def func(para1,para2):
##### 创建一个字典,{src,tgt} #####
def func1(sr, tg):
dir = {}
for i in range(len(sr) - 1):
dir[sr[i]] = tg[i]
return dir
dir = func1(para1,para2)
##### 删除HTML 标签 #####
### lemp参数是一个字典
def func2(lemp):
dict ={}
for para in lemp.items():
if "html" not in para[0] and "HTML" not in para[0]:
dict[para[0]]=para[1]
return dict
temp = func2(dir)
return temp
##### 删除长度比大于 1/3 的句子 #####
def fund(temp):
dtemp = {}
### 分词
def cut_word(seq):
sq = jieba.cut(seq,cut_all=False)
sq = ' '.join(sq)
return sq
### 计算长度比
def oper(para1,para2):
flag = 0 #### 正常
ave1 = para1/para2
ave2 = para2/para1
if ave1 <= (1/3) or ave2 <= (1/3):
flag = 1
else :
pass
return flag
for pair in temp.items():
pr1 = cut_word(pair[1])
pr2 = pair[0].split(' ')
l1 = len(pr1)
l2 = len(pr2)
flag = oper(l1,l2)
if flag == 0:
dtemp[pr1]=pair[0]
return dtemp
def funf(fl1,fl2):
#fl1,fl2 = fun(src,tgt)
lemp1,lemp2 = del_len(fl1,fl2)
temp1 = func(lemp1,lemp2)
temp = fund(temp1)
with open(n_src,'a',encoding='utf-8') as s1:
with open(n_tgt,'a',encoding='utf-8') as s2:
for l in temp.items():
s1.write(l[0]+'\n')
s2.write(l[1]+'\n')
if __name__ == "__main__":
fun(src,tgt)