HuggingFace自然语言处理详解:基于BERT中文模型的任务实战
上QQ阅读APP看书,第一时间看更新

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 编码工作的流程示意