1
概念
变量W代表一个有m个词的序列,即
则W出现的概率可以表示为
从计算上看,知道一个词出现的概率需要知道其前面所有词的出现概率,这种方法太过复杂,因此这里引入了马尔可夫模型,即当前词的出现概率仅与前面几个词有关。由此产生了N-Gram模型。
N-Gram模型又称为n-1阶马尔可夫模型,指建立一个长度为n字节的窗口在文本上滑动,假定第n个词出现的概率只与前面n-1个词相关,与其他词不相关。整个句子出现的概率即为各个词出现的概率:
当n取的越大,对下个词出现的约束信息越多,模型越准确,但需要的计算量越大。因为当文本中有不同的词|V|个,则所有可能的N-Gram数就有|V|的n次方个。当n取的越小,在训练语料库中出现的次数越多,越具有可靠的统计信息。当n取1,2,3时,N-Gram分别称为uni-gram,bi-gran和tri-gram。常用的是bi-gran和tri-gram,n>=4时很少用。
2
原理
使用N-Gram模型需要通过最大似然估计(MLE)结合语料库计算出每个词出现的概率。当语料库中总词频为N,则有
其中
代表字符串在语料库中出现的次数。由上式可得出每个词在语料库中出现的概率:
3
示例
以bi-gram为例,假定某语料中总词频为15000,句子“我爱北京天安门”中各词累计出现次数为:
我 | 2500 |
---|---|
爱 | 3000 |
北京 | 150 |
天安门 | 50 |
N-Gram出现次数为:
则P(我爱北京天安门)=P(我)P(爱|我)P(北京|爱)P(天安门|北京)=(2500/15000)(2000/2500)(70/3000)(20/150)=0.00041481。
4
典型应用
5
N-Gram划分Python实现
将一句话按照bi-gram的方式进行划分,代码如下:
def create_ngram(input_list, n):
#input_list为待划分的文本
#n为长度
ngram_list = []
if len(input_list) <= n:
ngram_list.append(input_list)
else:
for tmp in zip(*[input_list[i:] for i in range(n)]):
tmp = "".join(tmp)
ngram_list.append(tmp)
return ngram_list
if __name__ == "__main__":
input_list = '我爱北京天安门'
print(create_ngram(input_list,2))
得到的划分结果如下:
['我爱', '爱北', '北京', '京天', '天安', '安门']
6
数据平滑
使用N-Gram时会遇到一个问题,即很多词的组合是语料库中未能出现的,因此这个词的出现概率为0,就会导致整个句子的出现概率为0。在实际应用中这样是不够合理的,因此要通过数据平滑实现所有N-Gram概率和为1,每个N-Gram概率不为0的目的。这里介绍一下最简单的方法——拉普拉斯平滑,这种方法的思想就是让每个N-Gram至少出现1次,所以相应概率公式变为: