语料处理规则:

  在机器翻译中,一份好的语料会对翻译模型有很大的提升。但不同的研究人员都有不同的处理规则,本文选用小牛翻译的处理语料的规则方法。

(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)

01-25 12:48