P217
1. 词元化
tokenize()将文本行列表(lines)作为输入,列表中的每个元素都是一个序列(如一个文本行)。每个文本序列又被拆分成一个词元列表,词元(token)是文本的基本单位。最后,返回一个由词元列表组成的列表,其中,每个词元都是一个字符串。
def tokenize(lines, token = 'word')
#...
return [line.split() for line in lines]
# otherwise
return [list(line) for line in lines]
2. 词表(vocabulary,vocab)全称是,语料库唯一词元列表。
原因是,词元的类型是字符串,而模型需要的输入是数字,因此这种类型不方便模型使用。
上述词表是个字典(键值对,键唯一且不可变;基于哈希表实现,快速映射和检索;无序),字典类型非常适合词表,将字符串类型的词元(keys)映射到从0开始的数字索引。过程是:
- 将未知词元<unk>,和保留词元reserved_tokens (如填充词元<pad>、序列开始词元<bos>、序列结束词元<eos>)首先放入 唯一词元列表self.idx_to_token 和 唯一词元字典self.token_to_idx (两者是对应的,列表的索引和值 就是字典的值和键);
- 根据唯一词元的出现频率,从高向低排序,为其分配一个数字索引(数字顺序递增);
- 定义一个min_freq(默认为0),很少出现的词元通常被移除,降低复杂性。
定义Vocab类,传入 词元列表组成的列表tokens等
class Vocab: #@save
"""文本词表"""
def __init__(self, tokens=None, min_freq=0, reserved_tokens=None):
使用时光机数据集作为语料库构建词表,打印前几个高频词元及其索引。
vocab = Vocab(tokens)
print(list(vocab.token_to_idx.items())[:10])
## 输出 [('<unk>', 0), ('the', 1), ('i', 2), ('and', 3), ('of', 4), ('a', 5), ('to', 6), ('was', 7), ('in', 8), ('that', 9)]
使用vocab[tokens[i]]可以将每一条词元列表转化成一个数字索引列表。
3. 语料库corpus,全称是语料库词元索引列表
通过列表推导式,形成语料库词元索引列表。
def load_corpus_time_machine(max_tokens=-1)
# ...
# 外层循环 for line in tokens会遍历tokens列表中的每一个子列表(即每行);
# 内层循环 for token in line会遍历每行的每个词元。
corpu = [vocab[token] for line in tokens for token in line]
return corpus, vocab