中文不像英文有着天然的空格作为分割符,这样就导致如何切分中文句子变成了一个难题。不过有一个相对取巧的方法。可以在不考虑语言意义的情况下进行切词。那就是N-Gram。
N-Gram是一种基于统计语言模型的算法。其基本思想是将文本里面的内容按照字节大小为N的滑动窗口进行切分。形成了长度为N的字节片段序列。
想要研究N-Gram模型。就要先想明白统计语言模型。统计语言模型是NLP的基础模型。其解决问题的数学思想非常值得学习。
统计语言模型
统计语言模型是由单词组成的序列。。然后对于每一句话评定一个概率,如果概率越高。则说明这句话越符合语法。越像人话。
因为是不能直接计算的。我们需要转化一种表达形式,利用条件概率将计算公式改写成:
可以理解为将到同时发生的联合概率,替换成发生的概率,加上发生情况下发生的概率,并以此累加得到的概率。这样就离可计算、可泛化更加接近了一步。
因为一个完整的句子作为统计单位。其可统计的样本数据是非常有限的。所以得到的统计结果缺乏普遍性。如果出现一个不曾在样本数据里面出现的句子的时候,就无法判断其概率了。
只完成条件概率的改写是不够的。像这样的概率计算。在实际应用中意义不大。同时也不容易运算。
实际情况是,在一句话里面一个词是否可能出现。依赖的是他领近的几个词。距离很远的词已经不起什么作用了。
推导出这里。就需要引出马可夫假设,来进一步简化计算公式。
马可夫假设。虽然名字很抽象。但是概念很简单。就是每一个词出现的概率只和它前面的少数几个词有关系。比如说: 一阶马可夫假设,就只考虑前面一个词。
那么具体选择前面多少个词。我们可以设置成参数m。根据取值的不同,可以将计算公式改写成不同的形式。
当m为1的时候。是一个一元模型。Uni-Gram model:
当m=2的时候,是一个二元模型,Bi-Gram model:
当m=3的时候,是一个三元模型,Tri-Gram model:
很容易的发现,当m=N的时候,我们就得到了N-Gram model,这个推导就说明了什么是N-Gram模型。
N-Gram在中文分词中的应用
这时,我们可能会有一个疑问。N-Gram和中文分词有什么联系?
当一段文本数据词典切分存在多种可能的结果的时候。那么如何选择出最优的切分路径。就可以使用N-Gram模型利用统计信息找出一条概率最大的路径。得到最终的分词结果。
以“南京市长江大桥”为例。将其切分为一个有向无环图(DAG)。
在图论中,如果一个有向图从任意顶点出发经过若干条边回到该点。那么这个图是一个有向无环图。简称DAG。
如下图所示:
可能的切分路径有:
- 南京/市/长江/大桥
- 南京/市/长江大桥
- 南京/市长/江/大桥
- 南京市/长江/大桥
- 南京市/长江大桥
- 南京市长/江/大桥
假设是一段文。是上所有可能的切分路径。我们只要能求解出条件概率的最大值。我们就能够得到我们想要的切分路径。
这样的计算公式是无法直接求解的,所以我们需要利用贝叶斯公式将其改写。
贝叶斯公式:
简单的推导过程如下:
可以理解为W,S同时发生的概率除以S发生的概率,就是S情况下W发生的概率,同时W,S同时发生的概率。也可以理解为W发生的概率乘以W发生情况下S发生的概率。
由于P(S)为归一化因子,而P(S|W)恒等于1。因此我们只需要求解P(W)的最大值就好了。这就是我们上面提到的N-Gram模型。
除此之外。我们还可以借鉴N-Gram模型的思想。将中文句子按照N-Gram的切分。
例子:
我爱自然语言处理
当N=1的时候,[我,爱,自,然,语,言,处,理]
当N=2的时候,[我爱,爱自,自然,然语,语言,言处,处理]
当N=3的时候,[我爱自,爱自然,自然语,然语言,语言处,言处理]
其实代码也很简单。下面是一个Python代码实现N-Gram切分函数的划分:
def cut_by_ngram(sentence, min_n, max_n):
rst = []
# 遍历切分长度的范围
for length in range(min_n, min(len(word), max_n) + 1):
# 按照此时切分长度进行切分
for idx in range(0, len(word) - length + 1):
rst.append(word[idx: idx + length])
return rst
通过这个例子不难发现,在N不同的取值范围里,是可以切分出语义正确的词汇,当然这里面也包含了大量的语义错误的噪声词。
但在一些特殊的业务场景里,这样的结果是非常有价值的,如:新词发现、文本挖掘等,下面我结合实际的工作场景,简单为大家说明一下。
假设有这样一个需求:从小说里挖掘出主角的人名。简单的使用分词词典是不可能完成任务的,原因之前的章节介绍过了,这些人名大多都是未登录词。
此时的一种解决方法就是可以利用N-Gram,将二元、三元、四元词都切出来(因为中文名基本都在这样范围内),此时主角的姓名必然会在这些词里面。
接下来,就要看我们如何把它找出来了,这里利用了一个取巧的方法,因为中文人名的姓氏基本都在百家姓里,而百家姓的数据又极其容易从网上获得,这样我们就可以极大的缩小挖掘的范围了。
然后我们再利用TF-IDF的思想,在这个有限的范围里挖掘关键词,而此时得到的TOP1关键词就大概率是主角的人名了。当然实际效果和使用的语料库规模有关,需要人工适当添加一些黑名单过滤噪声词和添加一些不常见的姓氏词补充召回。
TF-IDF是一种用于信息检索与文本挖掘的常用加权技术
总结
N-Gram模型是非常重要的NLP基础模型,很多NLP的任务都是建立在N-Gram模型的基础之上,掌握N-Gram模型对于理解其它很多NLP模型有很大的帮助。
同时N-Gram模型所涉及到的知识点,如:贝叶斯、DAG、马尔可夫等,对于理解一些复杂的机器学习模型也是有很大的帮助作用。
在一些特殊的中文分词场景里,N-Gram切词法,也会产生奇效,甚至得到比深度学习模型更好的结果。