2.2 编码工具工作流示意
1. 定义字典
文字是一个抽象的概念,不是计算机擅长处理的数据单元,计算机擅长处理的是数字运算,所以需要把抽象的文字转换为数字,让计算机能够做数学运算。
为了把抽象的文字数字化,需要一个字典把文字或者词对应到某个数字。一个示意的字典如下:
#字典 vocab = { '<SOS>': 0, '<EOS>': 1, 'the': 2, 'quick': 3, 'brown': 4, 'fox': 5, 'jumps': 6, 'over': 7, 'a': 8, 'lazy': 9, 'dog': 10, }
注意:这只是一个示意的字典,所以只有11个词,在实际项目中的字典可能会有成千上万个词。
2. 句子预处理
在句子被分词之前,一般会对句子进行一些特殊的操作,例如把太长的句子截短,或在句子中添加首尾标识符等。
在示例字典中,我们注意到除了一般的词之外,还有一些特殊符号,例如<SOS>和<EOS>,它们分别代表一个句子的开头和结束。把这两个特殊符号添加到句子上,代码如下:
#简单编码 sent = 'the quick brown fox jumps over a lazy dog' sent = '<SOS> ' + sent + ' <EOS>' print(sent)
运行结果如下:
<SOS> the quick brown fox jumps over a lazy dog<EOS>
3. 分词
现在句子准备好了,接下来需要把句子分成一个一个的词。对于中文来讲,这是个复杂的问题,但是对于英文来讲这个问题比较容易解决,因为英文有自然的分词方式,即以空格来分词,代码如下:
#英文分词 words = sent.split() print(words)
运行结果如下:
['<SOS>', 'the', 'quick', 'brown', 'fox', 'jumps', 'over', 'a', 'lazy', 'dog', '<EOS>']
可以看到,这个英文的句子已经分成了比较理想的一个一个的单词。
对于中文来讲,分词的问题比较复杂,因为中文所有的字是连在一起写的,不存在一个自然的分隔符号。有很多成熟的工具能够做中文分词,例如jieba分词、LTP分词等,但是在本书中不会使用这些工具,因为HuggingFace的编码工具已经包括了分词这一步工作,由各个模型自行实现,对于调用者来讲这些工作是透明的,不需要关心具体的实现细节。
4. 编码
句子已按要求添加了首尾标识符,并且分割成了一个一个的单词,现在需要把这些抽象的单词映射为数字。因为已经定义好了字典,所以使用字典就可以把每个单词分别地映射为数字,代码如下:
#编码为数字 encode = [vocab[i] for i in words] print(encode)
运行结果如下:
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
以上是一个示例的编码的工作流程,经历了定义字典、句子预处理、分词、编码4个步骤,见表2-1。
表2-1 编码工作的流程示意