文本分词是自然语言处理中的一项基础但是很重要的任务。我们从分词的任务、挑战来进行介绍。
文本分词任务 | 文本分词挑战 |
---|---|
将文本以单词为基本单元进行划分 | 单词歧义 |
如何解决歧义呢?有许多算法被提出来用以解决这个问题,分别从中文分词和英文分词两个方面进行梳理与介绍。
分词类型 | 解决歧义的算法 | 算法举例 | 弊端 |
---|---|---|---|
中文分词 | 基于匹配的分词,采用固定的匹配规则对输入文本进行分词 | 正向最大匹配、逆向最大匹配(错误率低于正向最大匹配) | 有些分词并不一定准确,且依赖预先准备的词表 |
英文分词 | 空格分词 | 正则或者空格分割 | 比如小数点、专有名词中有空格,且依赖预先准备的词表 |
逆向最大匹配的代码实现:
上述的方法均依赖于预先设定的词表。有没有不依赖于预先设定的词表呢?有,叫字节对编码(Byte Pair Encoder, BPE),下面我们简要介绍下这种分词方法。
第一步,找到常见的可以组成单词的子字符串,又称子词。
第二步,将每个词用这些子词来表示。最基本的子词就是所有字符的集合,如{a, b, …, z, A, B, …, Z}。
第三步,BPE算法在训练文本中统计所有相邻子词出现的次数,选出出现次数最多的一对子词(s1, s2)。将这一对子词合并成新的子词加入集合,这称为一次合并(merge)操作,而原来的两个子词仍然保留在集合中。若干次合并之后,得到常见的子词集合。
第四步,对于一个新词,可以按照之前的合并顺序得到新词的BPE表示。而从BPE表示变回原词可以按照合并的反向顺序实现。
说了半天,感觉有点懵逼,我也有点懵逼,举个例子:
假设现在有训练文本如下:
//训练文本
wonder ponder toner
然后按照子词划分,比如,按照每个字符来进行划分,得到子词如下:
//按照当前子词分
w o n d e r
p o n d e r
t o n e r
统计相邻子词出现的次数,e r出现了三次,出现次数最多,因此组成新的子词er放入到子词的集合中。
w o n d er
p o n d er
t o n er
统计相邻子词出现的次数,o n出现了三次,出现次数最多,因此组成新的子词on放入到子词的集合中。
w on d er
p on d er
t on er
统计相邻子词出现的次数,on d出现了2次,出现次数最多,因此组成新的子词ond放入到子词的集合中。
w ond er
p ond er
t on er
合并3次以后,子词集合为{a, b, c, …z, er, on, ond}。
万事万物有利必有弊,接下来,对BPE算法做一个优缺点的总结。
整体上,BPE优缺点如下表所示:
优点 | 缺点 |
---|---|
1、由于BPE中的子词表里含有所有单个字符,所以任何单词都可以分拆成BPE的子词,即没有OOV问题 | 1、在不同训练文本上可能得到不一样的子词表,使得对应的模型无法对接 |
2、BPE可以通过调整合并次数来动态控制词表的大小 | 2、BPE生成的子词是完全基于频率的,可能并不符合语言中词根的划分 |
在实际工程应用上,BPE有应用么?有,BERT就是其中最成功的应用之一,别告诉我BERT你没听过。。。
这里有个通常意义上的应用常识:
-如果需要生成自然语言(比如,生成阅读理解问题的答案文本),一般推荐使用BPE等不依赖于词表的分词方法
-如果任务不涉及文本生成(比如,在文章中找到答案),可以使用既有词表,例如GloVe或者Word2Vec等。
谈到Word2Vec,就不得不提到词向量这个概念,接下来我们讨论词向量这个名词。
直观来看,模型需要的是数值化的特征,对于文本来说,一般为词语或者短句(文章可以看成一个个短句组成的)。那么,就面临一个问题,如何把这些文本数值化表达。
通常情况下,数值化表达有独热编码和分布式表示。
所谓独热编码就是做one-hot,其表示原理是将每个单词映射到字典的一个位置,然后该位置用数字1表示。
举个例子,
假设词典有[‘上海’, ‘黄浦江’, ‘上’, ‘绿意’, ‘缤纷’],那么对于绿意一词的词向量就可以用[0,0,0,1,0]来表示。
优缺点列表如下:
优点 | 缺点 |
---|---|
1、词典确定后编码规则就确定了,不需要多余的计算 | 1、随着词典的扩大,独热编码产生的向量长度也会随之增加,后续处理复杂度增加 |
2、可以解决编码长度不一的问题,所有单词,均由统一长度的向量进行表示 | 2、没有解决语义问题 |
词和短语的分布式介绍可以参考词在向量空间中的表达这篇论文,典型的分布式编码就是word2vec。
word2vec计算单词分布式表示的原理是利用单词的上下文相关性,即一个单词的意义和它在预料中出现位置附近的单词含义是有关联的,即skip-gram模型。(这里以skip-gram模型举例)
提到一个模型,我们通常从三个维度来分析这个模型:目标函数、优化方法和模型结构。对于skip-gram模型来说,我们也从这三个方向着手来进行剖析这个模型。
skip-gram的目标函数是给定一个中心词w,最大化周边的单词出现的概率。
如果用数学公式来表达,如何表达呢?参考word2vec论文[1],给出如下表达式:
在上述的论文公式(2)中,需要采用softmax来进行计算。但是softmax的分母需要对字典中的所有词计算分数,这样就会造成计算量很大,效率十分低下。因此,论文中采用负采样的方法来提高效率。
word2vec中
负采样
Ref:
1、word2vec论文