NLP基础(分词):BPE 算法
原文链接:NLP基础(分词):BPE 算法
导读:在自然语言处理(NLP)领域,分词是文本预处理中的一个关键步骤。分词的目的是将文本分解成有意义的单元,以便模型能够更好地理解和处理。传统的分词方法通常基于固定词汇表,如基于单词的分词。然而,这种方法在处理未知单词和稀有单词时存在局限性。为了解决这一问题,BPE算法应运而生。BPE算法是一种基于子词(subword)的分词方法,能够将单词分解成更小的子词单元,从而提高模型的泛化能力和灵活性。
1、算法原理
BPE(Byte Pair Encoding) 算法是一种基于频率的子词分割方法,其核心思想是将单词分解成更小的子词单元,这些子词单元可以是完整的单词、单词的前缀、后缀或中间部分。这种方法在处理未知单词和稀有单词时特别有效,因为它可以将这些单词分解成已知的子词单元,从而提高模型的泛化能力。
2、实现步骤
假设我们有一个训练语料 D,其中每个单词 w 由字符序列 w=c1,c2,…,cn组成。WordPiece 算法的目标是构建一个子词词汇表 V,使得每个单词 w 可以被分割成子词单元 w=v1,v2,…,vm,其中 vi∈V。
step 1 : 初始化词汇表
将所有字符(Unicode)作为初始词汇表的基本单元。
step 2 : 统计字符对频率
对训练语料中的每个单词,统计相邻字符对的出现频率。
step 3 : 合并最频繁字符对
将最频繁的字符对作为一个新单元加入词汇表,并更新训练语料中的分割方式。
其中,cici+1 是在 Vt 中最频繁的字符对。
step 4 : 更新训练语料
重复上述过程,直到词汇表大小达到预设值 ∣V ∣=K。
假设有一个简单的训练语料库,包含以下单词及其频率:
{'hug': 10, 'pug': 5, 'pun': 12, 'bun': 4, 'hugs': 5}
每次迭代的结果示例如下:
3、python实现
下面通过python代码实现上述示例:
得到结果如下:
4、优缺点
优势:通过数据驱动的方式有效平衡词汇表大小与未登录词问题。它能够将罕见词拆解为高频子词组合(如将“hugs”分解为“hug”和“s”),既压缩了词表规模,又提升了模型对未知词汇的泛化能力,尤其适用于形态丰富的语言或需要处理复合词的场景。无需依赖语言学规则的特点,在多语言任务中表现灵活,例如机器翻译中可统一处理不同语言的子词单元。
局限性:由于完全依赖统计频率,合并顺序的敏感性可能导致结果不稳定(如优先合并“u-g”而非“h-u”会生成不同子词),且生成的子词可能缺乏明确的语义解释性(如“ug”单独无意义)。此外,低频字符对的覆盖不足可能导致长尾词汇仍需以原子形式存在,而合并次数的设定依赖人工经验,需反复调参才能达到理想效果。
另外,BPE可以用于中文,但需要针对中文的语言特性进行适配。中文以汉字为基本单位,每个汉字本身具有独立语义,BPE可通过统计高频共现的汉字组合(如“中国”“北京”)生成子词,既能压缩词表规模(如从数万汉字减少到数千子词),又能解决未登录词问题(如将新词“元宇宙”拆解为“元”+“宇宙”)。然而,中文没有天然的空格分隔,BPE需以单字为起点逐步合并,可能产生无意义子词(如“的的”合并为冗余单元)或割裂语义连贯的固定搭配(如“巧克力”被拆为“巧”+“克力”)。实际应用中,BPE常与预分词技术结合,或通过限制子词长度、调整合并优先级来平衡效率与语义完整性,在机器翻译、预训练模型(如中文BERT)等场景中已得到有效验证。
参考文献:
1、Zouhar, V., Meister, C., Gastaldi, J. L., Du, L., Vieira, T., Sachan, M., & Cotterell, R. (2024). A Formal Perspective on Byte-Pair Encoding. arXiv preprint arXiv:2306.16837.
2、Lian, H., et al. (2024). Scaffold-BPE: Enhancing Byte Pair Encoding with Simple and Effective Scaffold Token Removal. arXiv preprint arXiv:2404.17808.
3、Sennrich, R., Haddow, B., & Birch, A. (2015). Neural Machine Translation of Rare Words with Subword Units. arXiv preprint arXiv:1508.07909.
点击原文(NLP基础(分词):BPE 算法)后台回复“BPE”可免费获得上述论文和完整代码