NLP学习笔记(十) 分词(下)

本文涉及的产品
NLP 自学习平台,3个模型定制额度 1个月
NLP自然语言处理_基础版,每接口每天50万次
NLP自然语言处理_高级版,每接口累计50万次
简介: NLP学习笔记(十) 分词(下)

前言


大家好,我是半虹,这篇文章来讲分词算法


正文


1  概述


所谓分词就是将文本段落分解成基本语言单位,这里的基本单位也可以称为词元


在上篇文章,我们主要从分词过程的角度出发,介绍了一些不同类型的分词算法


而本篇文章,我们将要从分词结果的角度出发,来介绍一些不同粒度的分词算法



2  按粒度划分


分词算法按照粒度可以分为以下三类:词粒度、字粒度、子词粒度,下面会逐一进行讨论



2.1 词粒度


基于词粒度的分词是最为直观的分词,这与人类理解自然语言的过程是相似的


对于英文来说,句子中的空格是天然的分隔符;对于中文来说,情况则变得更困难


在上篇文章中所介绍的多种分词方法,都属于词粒度分词方法,一个例子如下


例句:he is likely to be unfriendly to me
分词:['he', 'is', 'likely', 'to', 'be', 'unfriendly', 'to', 'me']


基于词粒度的分词有着一些优点:


词粒度的划分能够保留更多的语义信息

但是这种分词方法也有其他缺点:


无论对于中文还是英文,词的数量都是庞大的,因此需要维护一张巨大的词表(vocabulary )

即使拥有着巨大的词表,还是难以避免地遇到在词表中从来没有出现过的生词 (out of vocabulary )

而且特别对于英文来说,模型难以学习到同一个单词的不同形式和变化


2.2 字粒度


基于字粒度的分词是一种极端的分词,此类方法直接将文本分解为最小粒度

对于英文来说,就是将其分解为字母;对于中文来说,就是将其分解为汉字

由于操作简单,此类方法甚至无需建立模型,就按字符划分即可,一个例子如下

例句:he is likely to be unfriendly to me
分词:['h', 'e', 'i', 's', 'l', 'i', 'k', 'e', 'l', 'y', 't', 'o', 'b', 'e', 'u', 'n', 'f', 'r', 'i', 'e', 'n', 'd', 'l', 'y', 't', 'o', 'm', 'e']


基于字粒度的分词优点如下:


词表规模大大较少,这是因为英文字母就只有  26 2626  个,中文常用汉字也只有  3500 35003500  个

极少出现未知词汇,很多常用词都可以由字母或者汉字组合得到


从另一方面来说其缺点如下:


单个字母或者单个汉字并没有包含太多的语义信息

同样的文本会切分更多的词元,使输入的长度增加,从而让模型变得难训练


2.3 子词粒度


不难发现,词粒度和字粒度的优劣是互补的,那会不会有一种折中的方案,能够综合二者的优点呢

答案自然是肯定的,这种方案就是子词粒度,这是目前很多大规模预训练模型所采用的分词方法,

例子如下

例句:he is likely to be unfriendly to me
分词:['he', 'is', 'like', 'ly', 'to', 'be', 'un', 'friend', 'ly', 'to', 'me']

基于子词粒度分词,其核心为:用尽可能小的词表来覆盖尽可能多的词汇


这种方案介于词粒度和字粒度,能很好地平衡 out of vocabulary 的问题


怎么达到此效果呢?关键就是:用词表中的小词元来组成句子中的大词汇,类似于英文中的词缀组合


例如现给定词汇 unfriendly,可将其拆分为以下的词元:un、friend、ly


这些词元本身也是带有语义的,如 un 表示否定、friend  表示友好、ly  表示品质


而且词元之间也能相互组合来构成新词汇,例如,like 和 ly 组合成 likely


这有利于模型学习词汇之间的形式和变化,同时还具有更好的泛化性

image.png

image.png

学习 BPE \text{BPE}BPE 词表的步骤及例子如下:

准备语料库,定义词表大小和迭代次数,假设语料库中只有以下句子:

a tidy tiger tied a tie tighter to tidy her tiny tail

用预分词器将语料库的句子切分为单词,可以用空格或规则切分

拆分单词为字符序列,并且在每个单词的末尾加停止符用以表示结尾,停止符可以是 </w>

统计单词的出现频率,这些单词及其频率构成训练语料:

{
    'a </w>': 2,
    't i d y </w>': 2,
    't i g e r </w>': 1,
    't i e d </w>': 1,
    't i e </w>': 1,
    't i g h t e r </w>': 1,
    't o </w>': 1,
    'h e r </w>': 1,
    't i n y </w>': 1,
    't a i l </w>': 1,
}


统计字符的出现频率,这些字符作为初始子词构成词典:

{
    '</w>': 12,
    'a': 3,
    't': 10,
    'i': 8,
    'd': 3,
    'y': 3,
    'g': 2,
    'e': 5,
    'r': 3,
    'h': 2,
    'o': 1,
    'n': 1,
    'l': 1,
}


开始迭代,每次迭代完成以下操作,直至到达预设词表大小或到达迭代次数


统计语料中相邻子词对的出现频率,选取频率最高的子词对合并成新的子词加入词表,并更新词典


每次更新,词典可能出现三种变化:


词典的数量加一,这表明加入了合并后的子词,同时原来的两个子词被保留

词典的数量减一,这表明加入了合并后的子词,同时原来的两个子词被消解

词典的数量不变,这表明加入了合并后的子词,同时原来的两个子词一个被保留、一个被消解


随着迭代的进行,词典大小通常先增后减


第一次迭代如下:统计发现,子词 ti 相邻出现的频率最高,将二者合并进词表,并更新词典

{ # 语料
    'a </w>': 2,
    'ti d y </w>': 2,
    'ti g e r </w>': 1,
    'ti e d </w>': 1,
    'ti e </w>': 1,
    'ti g h t e r </w>': 1,
    't o </w>': 1,
    'h e r </w>': 1,
    'ti n y </w>': 1,
    't a i l </w>': 1,
}


{ # 词典
    '</w>': 12,
    'a': 3,
    't': 3, # [修改]
    'i': 1, # [修改]
    'd': 3,
    'y': 3,
    'g': 2,
    'e': 5,
    'r': 3,
    'h': 2,
    'o': 1,
    'n': 1,
    'l': 1,
    'ti': 7, # [增加]
}
{ # 词表
    'ti',
}

第二次迭代如下:统计发现,子词 y</w> 相邻出现的频率最高,将二者合并进词表,并更新词典

{ # 语料
    'a </w>': 2,
    'ti d y</w>': 2,
    'ti g e r </w>': 1,
    'ti e d </w>': 1,
    'ti e </w>': 1,
    'ti g h t e r </w>': 1,
    't o </w>': 1,
    'h e r </w>': 1,
    'ti n y</w>': 1,
    't a i l </w>': 1,
}


{ # 词典
    '</w>': 9, # [修改]
    'a': 3,
    't': 3,
    'i': 1,
    'd': 3,
    # 'y': 0, # [删减]
    'g': 2,
    'e': 5,
    'r': 3,
    'h': 2,
    'o': 1,
    'n': 1,
    'l': 1,
    'ti': 7,
    'y</w>': 3, # [增加]
}

{ # 词表
    'ti',
    'y</w>',
}

第三次迭代如下:统计发现,子词 er 相邻出现的频率最高,将二者合并进词表,并更新词典

{ # 语料
    'a </w>': 2,
    'ti d y</w>': 2,
    'ti g er </w>': 1,
    'ti e d </w>': 1,
    'ti e </w>': 1,
    'ti g h t er </w>': 1,
    't o </w>': 1,
    'h er </w>': 1,
    'ti n y</w>': 1,
    't a i l </w>': 1,
}


{ # 词典
    '</w>': 9,
    'a': 3,
    't': 3,
    'i': 1,
    'd': 3,
    'g': 2,
    'e': 2, # [修改]
    # 'r': 0, # [删减]
    'h': 2,
    'o': 1,
    'n': 1,
    'l': 1,
    'ti': 7,
    'y</w>': 3,
    'er': 3, # [增加]
}

{ # 词表
    'ti',
    'y</w>',
    'er',
}

第四次迭代如下:统计发现,子词 er</w> 相邻出现的频率最高,将二者合并进词表,并更新词典

{ # 语料
    'a </w>': 2,
    'ti d y</w>': 2,
    'ti g er</w>': 1,
    'ti e d </w>': 1,
    'ti e </w>': 1,
    'ti g h t er</w>': 1,
    't o </w>': 1,
    'h er</w>': 1,
    'ti n y</w>': 1,
    't a i l </w>': 1,
}


{ # 词典
    '</w>': 6, # [修改]
    'a': 3,
    't': 3,
    'i': 1,
    'd': 3,
    'g': 2,
    'e': 2,
    'h': 2,
    'o': 1,
    'n': 1,
    'l': 1,
    'ti': 7,
    'y</w>': 3,
    # 'er': 0, # [删减]
    'er</w>': 3, # [新增]
}

{ # 词表
    'ti',
    'y</w>',
    'er',
    'er</w>',
}

最终,上述词表加上基础字符得到最终词表如下

{
    # 上述词表
    'ti',
    'y</w>',
    'er',
    'er</w>',
    # 基础字符
    '</w>',
    'a',
    't',
    'i',
    'd',
    'y',
    'g',
    'e',
    'r',
    'h',
    'o',
    'n',
    'l',
}


应用 BPE \text{BPE}BPE 词表分词的步骤及例子如下:

设子词词表如下:

{
    'ti',
    'y</w>',
    'er',
    'er</w>',
    '</w>',
    'a',
    't',
    'i',
    'd',
    'y',
    'g',
    'e',
    'r',
    'h',
    'o',
    'n',
    'l',
}


且输入句子如下:

tiger is tidy


将子词词表中的子词按照长度从大到小进行排序(若长度相同,则按照上述词典对应词频排序)

{
    'er</w>',
    'ti',
    'y</w>',
    'er',
    '</w>',
    'a',
    't',
    'd',
    'g',
    'e',
    'h',
    'i',
    'o',
    'n',
    'l',
    'r',
    'y',
}


将输入句子预分词,并在每个单词后添加停止符 </w>

['tiger</w>', 'is</w>', 'tidy</w>']


对输入句子的每个单词,遍历排序的词典

若当前子词是这个单词的子字符串,则将其切分并对剩余部分继续匹配

若遍历完词典仍有子字符串无匹配,则将这些子字符串替换成未知标志,例如 <unk>

最终结果如下:

['ti', 'g', 'er</w>', 'i', '<unk>', '</w>', 'ti', 'd', 'y</w>']


上述过程亦可称为编码过程,通常发生在模型的输入部分,旨在将文本分解成词元输入到模型

另外与之对应的是解码过程,通常发生在模型的输出部分,旨在将模型输出的词元还原成文本

具体就是将上述的词元序列直接拼接起来即可,但要注意将 </w> 替换回空格


对应结果如下:

tiger i<unk> tidy


637aea3d266ae77b28d68b85900615d.jpg

image.png


目录
相关文章
|
3月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的应用与性能比较
分词算法在自然语言处理中的应用与性能比较
|
2月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的应用与性能比较
分词算法在自然语言处理中的应用与性能比较
|
2月前
|
机器学习/深度学习 自然语言处理 算法
分词算法在自然语言处理中的基本原理与应用场景
分词算法在自然语言处理中的基本原理与应用场景
|
4月前
|
自然语言处理 算法 Python
【Python自然语言处理】规则分词中正向、反向、双向最大匹配法的讲解及实战(超详细 附源码)
【Python自然语言处理】规则分词中正向、反向、双向最大匹配法的讲解及实战(超详细 附源码)
167 0
|
机器学习/深度学习 数据采集 人工智能
NLP之文本分词综述
NLP之文本分词综述
449 0
|
自然语言处理 Python
【NLP Tool -- NLTK】NLTK进行英文情感分析、分词、分句、词性标注(附代码)
NLP自然语言处理之NLTK工具的使用,进行英文情感分析、分词、分句、词性标注(附代码)
719 0
|
机器学习/深度学习 自然语言处理 算法
NLP学习笔记(九) 分词(上)
NLP学习笔记(九) 分词(上)
63 0
|
机器学习/深度学习 自然语言处理
NLP学习笔记(八) GPT简明介绍 下
NLP学习笔记(八) GPT简明介绍
145 0
|
自然语言处理
NLP学习笔记(八) GPT简明介绍 上
NLP学习笔记(八) GPT简明介绍
136 0
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
AI技术在自然语言处理中的应用
【9月更文挑战第17天】本文主要介绍了AI技术在自然语言处理(NLP)领域的应用,包括文本分类、情感分析、机器翻译和语音识别等方面。通过实例展示了AI技术如何帮助解决NLP中的挑战性问题,并讨论了未来发展趋势。

热门文章

最新文章