WordPiece 算法

WordPiece 也是一种子词构建算法,我们在中文语料中使用的 BertTokenizer 就是使用这种分词算法,从这一点来看,WordPiece 算法要比 BPE 算法更加适合中文语料的分词场景。

class BertTokenizer(PreTrainedTokenizer):
    Construct a BERT tokenizer. Based on WordPiece.

BPE 和 WordPiece 都是子词构建算法,他们两个最大的区别是做子词合并时,BPE 是寻找合并之后频数最高的两个子词进行合并,而 WordPiece 计算步骤如下:

https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf

分词的目标就是最大化训练数据的似然函数:

下图公式中,A 和 B 为待合并的两个子词:

示例代码:

import tokenizers.pre_tokenizers
from tokenizers import Tokenizer
from tokenizers.models import WordPiece
from tokenizers.trainers import WordPieceTrainer
from tokenizers.pre_tokenizers import WhitespaceSplit


def test():
    document = ['我爱吃烤鸭'] * 5 + ['我也爱喝啤酒']
    print(document)

    # 指定分词器使用 BPE 算法模型,并设置特殊 UNK 标记
    tokenizer = Tokenizer(model=WordPiece())
    # 设置单词的分割方式
    tokenizer.pre_tokenizer = WhitespaceSplit()
    # 构建训练器
    trainer = WordPieceTrainer(vocab_size=20)
    # 开始训练
    tokenizer.train_from_iterator(document, trainer)
    # 保存分词器
    tokenizer.save('./tokenizer.json')


if __name__ == '__main__':
    test()

分词结果:

  "vocab": {
    "也": 0,
    "吃": 1,
    "啤": 2,
    "喝": 3,
    "我": 4,
    "烤": 5,
    "爱": 6,
    "酒": 7,
    "鸭": 8,
    "##也": 9,
    "##爱": 10,
    "##喝": 11,
    "##啤": 12,
    "##酒": 13,
    "##吃": 14,
    "##烤": 15,
    "##鸭": 16,
    "我爱": 17,
    "##吃烤": 18,
    "我爱吃烤": 19
  }

未经允许不得转载:一亩三分地 » WordPiece 算法
评论 (0)

1 + 9 =