机器翻译之数据处理

目录

1.导包

2.读取本地数据

3.定义函数:数据预处理

4.定义函数:词元化

5.统计每句话的长度的分布情况

[6. 获取词汇表](#6. 获取词汇表)

[7. 截断或者填充文本序列](#7. 截断或者填充文本序列)

8.将机器翻译的文本序列转换成小批量tensor

9.加载数据

10.知识点个人理解


1.导包

python 复制代码
#导包
import os
import torch
import dltools

2.读取本地数据

python 复制代码
#读取本地数据
with open('./fra-eng/fra.txt', 'r', encoding='utf-8') as f:
    raw_text = f.read()  #一次读取所有数据

print(raw_text[:75])
复制代码
Go.	Va !
Hi.	Salut !
Run!	Cours !
Run!	Courez !
Who?	Qui ?
Wow!	Ça alors !

3.定义函数:数据预处理

python 复制代码
#数据预处理
def preprocess_nmt(text):
    #判断标点符号前面是否有空格
    def no_space(char, prev_char):
        return char in set(',.!?') and prev_char != ' '
    
    #替换识别不了的字符,替换不正常显示的空格,将大写字母变成小写
    text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()
    #在单词和标点之间插入空格
    out = [' '+ char  if i>0 and no_space(char, text[i-1]) else char for i, char in enumerate(text)]
    return ''.join(out)  #合并out

#测试:数据预处理
text = preprocess_nmt(raw_text)
print(text[:80])
复制代码
go .	va !
hi .	salut !
run !	cours !
run !	courez !
who ?	qui ?
wow !	ça alors !

4.定义函数:词元化

python 复制代码
#定义函数:词元化
def tokenize_nmt(text, num_examples=None):
    """
    text:传入的数据文本
    num_examples=None:样本数量为空,判断数据集中剩余的数据量是否满足一批所取的数据量
    """
    source, target = [], []
    #以换行符号\n划分每一行
    for i, line in enumerate(text.split('\n')):
        #if num_examples  表示不是空,相当于 if num_examples != None
        if num_examples and i > num_examples:
            break
            
        #从每一行数据中 以空格键tab分割数据
        parts = line.split('\t')  #将英文与对应的法语分割开
        if len(parts) == 2:  #单词文本与标点符号两个元素
            source.append(parts[0].split(' ')) #用空格分割开单词文本与标点符号两个元素
            target.append(parts[1].split(' '))
            
    return source, target

#测试词元化代码
source, target = tokenize_nmt(text)
source[:6], target[:6]
复制代码
([['go', '.'],
  ['hi', '.'],
  ['run', '!'],
  ['run', '!'],
  ['who', '?'],
  ['wow', '!']],
 [['va', '!'],
  ['salut', '!'],
  ['cours', '!'],
  ['courez', '!'],
  ['qui', '?'],
  ['ça', 'alors', '!']])

5.统计每句话的长度的分布情况

python 复制代码
#统计每句话的长度的分布情况
def show_list_len_pair_hist(legend, xlabel, ylabel, xlist, ylist):
    dltools.set_figsize()  #创建一个适当的画布
    _,_,patches = dltools.plt.hist([[len(l) for l in xlist], [len(l) for l in ylist]])
    dltools.plt.xlabel(xlabel) #添加x标签
    dltools.plt.ylabel(ylabel)  #添加y标签
    for patch in patches[1].patches:  #为patches[1]的柱体添加斜线
        patch.set_hatch('/')
        
    dltools.plt.legend(legend) #添加标注
    
#测试代码:统计每句话的长度的分布情况
show_list_len_pair_hist(['source', 'target'], '# tokens per sequence', 'count', source, target)

6. 获取词汇表

python 复制代码
#获取词汇表
src_vocab = dltools.Vocab(source, min_freq=2, reserved_tokens=['<pad>', '<bos>', '<eos>'])
len(src_vocab)

10012

7. 截断或者填充文本序列

python 复制代码
def truncate_pad(line, num_steps, padding_token):
    """
    line:传入的数据
    num_steps:子序列长度
    padding_token:需要填充的词元
    """
    if len(line) > num_steps:
        return line[:num_steps]  #太长就截断
    #太短就补充
    return line + [padding_token] * (num_steps - len(line))  #填充

#测试
#source[0]表示英文单词
truncate_pad(src_vocab[source[0]], 10, src_vocab['<pad>'])

[47, 4, 1, 1, 1, 1, 1, 1, 1, 1]

8.将机器翻译的文本序列转换成小批量tensor

python 复制代码
def build_array_nmt(lines, vocab, num_steps):
    #通过vocab拿到line的索引
    lines = [vocab[l] for l in lines]
    #每个序列结束之后+一个'eos'
    lines = [l + [vocab['eos']] for l in lines]
    #对每一行文本 截断或者填充文本序列,再转化为tensor
    array = torch.tensor([truncate_pad(l, num_steps, vocab['<pad>']) for l in lines])
    #获取有效长度
    valid_len = (array != vocab['<pad>']).type(torch.int32).sum(1)
    return array, valid_len

9.加载数据

python 复制代码
def load_data_nmt(batch_size, num_steps, num_examples=600):
    # 需要返回数据集的迭代器和词表
    text = preprocess_nmt(raw_text)
    source, target = tokenize_nmt(text, num_examples)
    src_vocab = dltools.Vocab(source, min_freq=2, reserved_tokens=['<pad>', '<bos>', '<eos>'])
    tgt_vocab = dltools.Vocab(target, min_freq=2, reserved_tokens=['<pad>', '<bos>', '<eos>'])
    
    src_array, src_valid_len = build_array_nmt(source, src_vocab, num_steps)
    tgt_array, tgt_valid_len = build_array_nmt(target, tgt_vocab, num_steps)
    data_arrays = (src_array, src_valid_len, tgt_array, tgt_valid_len)
    data_iter = dltools.load_array(data_arrays, batch_size)
    return data_iter, src_vocab, tgt_vocab
python 复制代码
#测试代码
train_iter, src_vocab, tgt_vocab = load_data_nmt(batch_size=2, num_steps=8)


for X, X_valid_len, Y, Y_valid_len in train_iter:
    print('X:', X.type(torch.int32))
    print('X的有效长度:', X_valid_len)
    print('Y:', Y.type(torch.int32))
    print('Y的有效长度:',Y_valid_len)
    break
复制代码
X: tensor([[17, 20,  4,  0,  1,  1,  1,  1],
        [ 7, 84,  4,  0,  1,  1,  1,  1]], dtype=torch.int32)
X的有效长度: tensor([4, 4])
Y: tensor([[ 11,  61, 144,   4,   0,   1,   1,   1],
        [  6,  33,  17,   4,   0,   1,   1,   1]], dtype=torch.int32)
Y的有效长度: tensor([5, 5])

10.知识点个人理解

相关推荐
桑榆肖物3 分钟前
将 .NET Aspire 添加到现有应用:前端 JavaScript 项目处理
前端·javascript·.net
Eric.Lee20214 分钟前
数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall
人工智能·目标检测·计算机视觉
清流君5 分钟前
【运动规划】移动机器人运动规划与轨迹优化全解析 | 经典算法总结
人工智能·笔记·算法·机器人·自动驾驶·运动规划
Wh1teR0se2 小时前
[极客大挑战 2019]Secret File--详细解析
前端·web安全·网络安全
枫哥和java2 小时前
python serializer, model drf通过序列化器, 模型获取mysql 一张表某个字段数据库现存的最大值
数据库·python·mysql
ZhaiMou3 小时前
HTML5拖拽API学习 托拽排序和可托拽课程表
前端·javascript·学习·html5
无忧无虑Coding4 小时前
pyinstall 打包Django程序
后端·python·django
code_shenbing6 小时前
跨平台WPF框架Avalonia教程 三
前端·microsoft·ui·c#·wpf·跨平台·界面设计
ad禥思妙想6 小时前
如何运行python脚本
开发语言·python
威威猫的栗子6 小时前
用 Python 与 Turtle 创作属于你的“冰墩墩”!
开发语言·python·turtle