2 文本预处理
- 将文本作为字符串加载到内存中。
- 将字符串拆分为词元(如单词和字符)。
- 建立一个词表,将拆分的词元映射到数字索引。
- 将文本转换为数字索引序列,方便模型操作。
1 | import collections |
2.1 读取数据集
- 从一个小语料库加载文本,包含30000多个单词
- 将数据集读取到由多条文本行组成的列表中,其中每条文本行都是一个字符串。
1 | #@save |
Downloading ..\data\timemachine.txt from http://d2l-data.s3-accelerate.amazonaws.com/timemachine.txt...
# 文本总行数:3221
the time machine by h g wells
twinkled and his usually pale face was flushed and animated the
2.2 词元化
- 将文本行列表(lines)作为输入,列表中的每个元素是一个文本序列(如一条文本行)
- 每个文本序列又被拆分成一个词元列表,词元(token)是文本的基本单位。
1 | def tokenize(lines, token='word'): #@save |
['the', 'time', 'machine', 'by', 'h', 'g', 'wells']
[]
[]
[]
[]
['i']
[]
[]
['the', 'time', 'traveller', 'for', 'so', 'it', 'will', 'be', 'convenient', 'to', 'speak', 'of', 'him']
['was', 'expounding', 'a', 'recondite', 'matter', 'to', 'us', 'his', 'grey', 'eyes', 'shone', 'and']
['twinkled', 'and', 'his', 'usually', 'pale', 'face', 'was', 'flushed', 'and', 'animated', 'the']
2.3 词表
- 词元的类型是字符串,而模型需要的输入是数字。我们需要构建一个字典,通常也叫做词表(vocabulary),用来将字符串类型的词元映射到从0开始的数字索引中。
- 先将训练集中的所有文档合并在一起,对它们的唯一词元进行统计,得到的统计结果称之为语料(corpus)。然后根据每个唯一词元的出现频率,为其分配一个数字索引。很少出现的词元通常被移除,这可以降低复杂性。语料库中不存在或已删除的任何词元都将映射到一个特定的未知词元“
”。 - 可以选择增加一个列表,用于保存那些被保留的词元,例如:填充词元(“
”);序列开始词元(“ ”);序列结束词元(“ ”)
1 | class Vocab: #@save |
- 用语料库来构建词表,然后打印前几个高频词元及其索引。
1 | vocab = Vocab(tokens) |
[('<unk>', 0), ('the', 1), ('i', 2), ('and', 3), ('of', 4), ('a', 5), ('to', 6), ('was', 7), ('in', 8), ('that', 9)]
- 将每一条文本行转换成一个数字索引列表。
1 | for i in [0, 10]: |
文本: ['the', 'time', 'machine', 'by', 'h', 'g', 'wells']
索引: [1, 19, 50, 40, 2183, 2184, 400]
文本: ['twinkled', 'and', 'his', 'usually', 'pale', 'face', 'was', 'flushed', 'and', 'animated', 'the']
索引: [2186, 3, 25, 1044, 362, 113, 7, 1421, 3, 1045, 1]
2.4 整合所有功能
- 将所有功能打包到load_corpus_time_machine函数中,该函数返回corpus(词元索引列表)和vocab(时光机器语料库的词表)。
- 为了简化训练,使用字符(而不是单词)实现文本词元化;
- 数据集中的每个文本行不一定是一个句子或一个段落,还可能是一个单词,因此返回的corpus仅处理为单个列表,而不是使用多词元列表构成的一个列表。
1 | def load_corpus_time_machine(max_tokens=-1): #@save |
170580 28