文章目录
- 前言
- 一、数据读取
- 二、文本预处理
- 三、词元化
- 四、构建词表
- 五、截断和填充
- 六、转换为张量
- 七、数据迭代器
- 总结
前言
在深度学习领域,序列到序列(Seq2Seq)模型是一种非常重要的架构,广泛应用于机器翻译、文本摘要和对话生成等任务。在实现 Seq2Seq 模型时,数据的预处理是至关重要的第一步,它直接影响到模型的性能和训练效果。本篇博客将基于 PyTorch 框架,通过一个完整的代码示例,详细讲解如何对“英语-法语”翻译数据集进行预处理,包括数据读取、文本清洗、词元化、词表构建以及数据迭代器的构造。通过阅读本文,你将掌握从原始文本到可用于模型训练的数据张量的完整流程,同时理解每个步骤背后的逻辑和代码实现。
本文的所有代码都来源于附件中的两个文档:一个是 Python 脚本(包含核心函数定义),另一个是 Jupyter Notebook(展示代码的实际运行结果)。我会将这些代码整合到博客中,并辅以文字说明,帮助你逐步理解数据预处理的每一步。
一、数据读取
我们从一个简单的函数 read_data_nmt
开始,它负责读取“英语-法语”数据集文件 fra.txt
。这个文件通常包含多行,每行是一个英语句子和对应的法语句子,用制表符(\t
)分隔。以下是代码实现:
def read_data_nmt():"""载入“英语-法语”数据集返回值:str: 文件内容的完整字符串"""with open('fra.txt', 'r', encoding='utf-8') as f:return f.read()
在 Jupyter Notebook 中,我们可以调用这个函数并查看前几行数据:
import utils_for_dataraw_text = utils_for_data.read_data_nmt()
print(raw_text[:75])
输出结果:
Go. Va !
Hi. Salut !
Run! Cours !
Run! Courez !
Who? Qui ?
Wow! Ça alors !
可以看到,数据集的每一行由英语句子和法语句子组成,中间用制表符分隔。接下来,我们需要对这些原始文本进行预处理。
二、文本预处理
原始文本中可能包含不必要的字符(如不间断空格 \u202f
或非断行空格 \xa0
),而且标点符号与单词之间可能没有空格,这些都会影响后续的分词效果。因此,我们定义了 preprocess_nmt
函数来进行文本清洗:
def preprocess_nmt(text):"""预处理“英语-法语”数据集参数:text (str): 输入的原始文本字符串返回值:str: 处理后的文本字符串"""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 charfor i, char in enumerate(text)]return ''.join(out)
这个函数的主要步骤包括:
- 将特殊空格替换为普通空格,并将文本转换为小写。
- 在标点符号(如
,.!?
)前插入空格,但如果前一个字符已经是空格,则不重复添加。
运行代码并查看效果:
text = utils_for_data.preprocess_nmt(raw_text)
print(text[:80])
输出结果:
go . va !
hi . salut !
run ! cours !
run ! courez !
who ? qui ?
wow ! ça alors !
经过预处理,文本变得更加规范,单词和标点符号之间有了清晰的空格分隔,这为后续的分词奠定了基础。
三、词元化
接下来,我们需要将文本按单词拆分为词元(token),并将英语和法语部分分开。tokenize_nmt
函数实现了这一功能:
def tokenize_nmt(text, num_examples=