1 分词粒度
1.1 词粒度 word
英文天生空格分开词汇,中文可以使用jieba分词工具
优点:
- 词的边界和含义得到保留
缺点:
- 词粒度的词表由于长尾效应可能会非常大,包含很多的稀有词,存储和训练的成本都很高,并且稀有词往往很难学好
- OOV(out of vocabulary)问题,对于词表之外的词无能为力
- 无法处理单词的形态关系和词缀关系,同一个词的不同形态,语义相近,完全当做不同的单词不仅增加了训练成本,而且无法很好的捕捉这些单词之间的关系;同时,也无法学习词缀在不同单词之间的泛化
1.2 字符粒度 char
OOV问题迎刃而解
优点:
- 词表极小,比如26个英文字母可以组合出所有词,5000多个中文常用字基本也能组合出足够的词汇,再加上一些常用字符
缺点:
- 无法承载丰富的语义
- 序列长度增长,带来计算成本的增长
1.3 子词粒度 subword
粒度介于char和word之间,基本思想为常用词应该保持原状,生僻词应该拆分成子词以共享token压缩空间
优点:可以较好的平衡词表大小与语义表达能力,比如OOV问题可以通过subword的组合来解决;三种主流的Subword分词算法,分别是BPE,WordPiece和Unigram Language Model,下面会主要介绍子词粒度的几种方法
2 分词算法
2.1 Byte Pair Encoding(BPE)
论文:Neural Machine Translation of Rare Words with Subword Units
核心思想:从一个基础小词表开始,通过不断合并最高频的连续token对来产生新的token,和WordPiece不同的地方在于,WordPiece判断合并的指标是互信息,而它是频率
具体做法:
- 输入训练语料和期望词表大小V
- 准备基础词表:比如英文中26个字母加上各种符号,并初始化ID
- 基于基础词表将准备的语料拆分为最小单元
- 在语料上统计单词内相邻单元对的频率,选择频率最高的单元对进行合并
- 重复第3步直到达到预先设定的subword词表大小或下一个最高频率为1
优点:可以有效地平衡词汇表大小和编码步数(编码句子所需的token数量,与词表大小和粒度有关)
缺点:基于贪婪和确定的符号替换,不能提供带概率的多个分词结果(这是相对于ULM而言的);解码的时候面临歧义问题(比如对于同一个句子"Hello World",分词结果可能不同"Hell/o/world"或者"He/llo/world")
2.2 Byte-level BPE(BBPE)
论文:Neural Machine Translation with Byte-Level Subwords
核心思想: 将BPE从字符级别扩展到字节级别,来自噪声文本或字符丰富的语言(如日语和中文)的稀有字符可能会不必要地占用词汇表并限制其紧凑性
具体做法: 基础词表使用256的字节集,UTF-8编码
优点:效果与BPE相当,但是词表大小大为减小,可以在多语言之间通过字节级别的子词实现更好的共享
缺点:编码序列时,长度可能会略长于BPE,计算成本更高。由byte解码时可能会遇到歧义,需要通过上下文信息和动态规划来进行解码,保证输出有效的句子
以下是对BPE和BBPE的效果的对比:

2.3 WordPiece
论文:Fast WordPiece Tokenization
核心思想: 与BPE类似,也是从一个基础小词表出发,通过不断合并来产生最终的词表。主要的差别在于,BPE按频率来选择合并的token对,而wordpiece按token间的互信息来进行合并
优点:可以较好的平衡词表大小和OOV问题
缺点:可能会产生一些不太合理的子词或者说错误的切分;对拼写错误非常敏感;对前缀的支持不够好;一种解决方案是:将复合词拆开、将前缀也拆开
2.4 Unigram Language Model(ULM)
核心思想: 初始化一个大词表,然后通过unigram 语言模型计算删除不同subword造成的损失来代表subword的重要性,保留loss较大或者说重要性较高的subword,ULM会倾向于保留那些以较高频率出现在很多句子的分词结果中的子词,因为这些子词如果被删除,其损失会很大
过程示例:
- 初始化大词表: 左侧是corpus以及对应出现的次数,右侧是构建出的词表。这里的构建采用任何方式都行,如BPE,但要注意两点:所有的单个字符(如h,u,g)必须出现在词表当中;构建出的词表必须要能cover当前的corpus,不然下一步计算概率就会失败

- 挑选最大似然的分词结果:此处拿hug举例,hug在当前词表中可以暴力枚举有4种分词方法:h,u,g,hu,g,h,ug,hug,其中前3种都在词汇表中,第四种hug不在。可以计算出最大的那个概率1.11e-02

- 对所有corpus都进行如下计算,之后求弄个加权求和,作为Loss

- 精简词汇表:从上图的结果可以看到,其中有部分token是没有使用的,分别是ug, pu, hu, lu, du, bu。理论上这几个词删除后不会影响分词结果。但由于token被删除后,会影响其他token的概率计算(因为基数从180个减少了),所以还得逐个尝试一下删除token后的真实Loss是多少。下图是删除各个单词后Loss的情况,bu对应的Loss最小,故删除bu:
2.5 对比
wordpiece和BPE的对比: 都是走的合并的思路,将语料拆分成最小单元(英文中26个字母加上各种符号,这些作为初始词表)然后进行合并,词表从小到大;核心区别就在于wordpiece是按token间的互信息来进行合并而BPE是按照token一同出现的频率来合并的
wordpiece和ULM的对比: 都使用语言模型来挑选子词;区别在于前者词表由小到大,而后者词表由大到小,先初始化一个大词表,根据评估准则不断丢弃词表,直到满足限定条件。ULM算法考虑了句子的不同分词可能,因而能够输出带概率的多个分词结果