【NLP learning】Tokenizer分词技术概述

【NLP learning】Tokenizer分词技术概述

目录



极简方法——空格分词(Space)

通过空格进行分词是最简单的分词方法,但是仅对英文而言,对于中文则可以使用逐字拆分进行分词

实现代码如下:

s = "very long corpus..."
words = s.split(" ")  # Split over space
vocabulary = dict(enumerate(set(words)))  # Map storing the word to it's corresponding id

【NLP learning】Tokenizer分词技术概述
优劣之处:如果词汇量少,这种方法可能效果不错,因为词典将存储给定语料中的每个单词(或特殊标记)。但是,像“cat”和“cats”这样的单词变体不会共享id(即标识符),即使它们的语义非常接近。

预训练模型的分词方法——子词分解/子标记(Subtokens)

为了避免上述分词问题,如今的预训练语言模型的字典都采用了下图的子词方法进行分词和id化,子词/子标记扩展了上面的分词策略,进一步将一个单词分解为从数据中学习到的语言逻辑的子成分。

举例而言,如“cat”和“cats”这两个单词,cats的分词结果为 [cat,##s]。其中前缀**“##”**表示初始输入的子标记。这种分词方法可以在英语语料库中提取子标记,如“##ing”、“##ed”等。
【NLP learning】Tokenizer分词技术概述
优劣之处:这种利用“片段”组成的子标记分词方法总体上减少了词汇表的大小,并可以做到一定程度的词汇相似度,如“cat”和“cats”将有一定的联系。但不足的是,由于一个token将可能被分解为多个子token,模型的输入序列长度将会增加,产生输入序列长度的非线性复杂度的问题。

在所有的分词算法中,HuggingFace团队强调了基于Transformer的SOTA模型中所使用的分词算法:

基于给定语料的BPE实现代码如下:
命令行:pip install tokenizers

from tokenizers import Tokenizer
from tokenizers.decoders import ByteLevel as ByteLevelDecoder
from tokenizers.models import BPE
from tokenizers.normalizers import Lowercase, NFKC, Sequence
from tokenizers.pre_tokenizers import ByteLevel
from tokenizers.trainers import BpeTrainer

'''BPE'''
tokenizer = Tokenizer(BPE())
tokenizer.normalizer = Sequence([
    NFKC(),
    Lowercase()
])
tokenizer.pre_tokenizer = ByteLevel()
tokenizer.decoder = ByteLevelDecoder()

trainer = BpeTrainer(vocab_size=25000, show_progress=True, initial_alphabet=ByteLevel.alphabet())
tokenizer.train(trainer, ["big.txt"])
print("Trained vocab size: {}".format(tokenizer.get_vocab_size()))

tokenizer.model.save('.')

tokenizer.model = BPE('vocab.json', 'merges.txt')
encoding = tokenizer.encode("This is a simple input to be tokenized")

print("Encoded string: {}".format(encoding.tokens))

decoded = tokenizer.decode(encoding.ids)
print("Decoded string: {}".format(decoded))

实验效果如下
【NLP learning】Tokenizer分词技术概述
补充:即使基于中文的预训练模型,大部分我们看到的分词结果都是逐字进行分词,但对于中文也是有子标记的,如下图的bert_base_chinese的词汇表中的一部分中文子标记。
【NLP learning】Tokenizer分词技术概述
最后再来让我们学习一下SOTA的分词方法:BPE分词算法

BPE分词算法

BPE,(byte pair encoder)字节对编码,主要目的是为了数据压缩

简单例子解释:
【NLP learning】Tokenizer分词技术概述
训练过程:
注:整个训练过程以两个字符(或两个字符组)为拆分或组合的基本单位
  首先,根据语料进行以字符为单位的拆分,然后按照字符对进行组合,并对所有组合的结果根据出现的频率进行排序,形成一份codec文件,排在第一位的是出现频率最高的子词,如下图的"e </w>",其中表示这个e是作为单词结尾的字符
【NLP learning】Tokenizer分词技术概述
  之后,以where单词为例,具体过程如下图所示,按照两个字符进行拆分,然后查找上述的codec文件,逐对合并,优先合并出现频率靠前的字符对,如下图的85 319 9 15 1表示在该字符对在codec文件中的频率排名。
【NLP learning】Tokenizer分词技术概述

图片来源及参考:

01-training-tokenizers.ipynb

Byte pair encoding

一分钟搞懂的算法之BPE算法

bpe分词算法的原理以及在机器翻译中的应用

上一篇:文本分类(ALBert+BiLSTM)


下一篇:转载———大数据:网络爬虫的post请求、get请求的区别