主题模型LDA教程:n-gram N元模型和nltk应用

文章目录

        • N-Gram 模型
        • 原理
          • 概率估计
        • nltk使用n-gram

N-Gram 模型

N-Gram(N元模型)是自然语言处理中一个非常重要的概念。N-gram模型也是一种语言模型,是一种生成式模型。

假定文本中的每个词 w i w_{i} wi和前面 N − 1 N-1 N1 个词有关,而与更前面的词无关。这种假设被称为N-1阶马尔可夫假设,对应的语言模型称为N元模型。习惯上,1-gramunigram2-gram称为bigram(也被称为一阶马尔可夫链),3-gramtrigram(也被称为二阶马尔可夫链)。还有four-gram、five-gram等,不过大于n>5的应用很少见。常用的是 Bi-gram (N = 2)Tri-gram (N = 3),一般已经够用了。

用于构建语言模型的文本称为训练语料(training corpus)。对于n元语法模型,使用的训练语料的规模一般要有几百万个词。语料库的选取也十分重要,如果训练语料和模型应用的领域相脱节,那么模型的效果通常要大打折扣。

原理

N-gram的第一个特点是某个词的出现依赖于其他若干个词,第二个特点是我们获得的信息越多,预测越准确。

假设句子S是由词序列 w 1 , w 2 , w 3 . . . w n w_1,w_2,w_3...w_n w1,w2,w3...wn组成,用公式表示N-Gram语言模型如下(每一个单词 w i ​ w_i​ wi都要依赖于从第一个单词 w 1 w_1 w1到它之前一个单词 w i − 1 w_{i−1} wi1​的影响):
P ( S ) = P ( w 1 , w 2 , … , w n ) = P ( w 1 ) P ( w 2 ∣ w 1 ) P ( w 3 ∣ w 1 , w 2 ) … P ( w n ∣ w 1 , w 2 , … , w n − 1 ) P(S) = P(w_1, w_2, …,w_n ) = P(w_1)P(w_2 |w_1)P(w_3|w_1,w_2)…P(w_n|w_1,w_2,…,w_{n-1}) P(S)=P(w1,w2,,wn)=P(w1)P(w2w1)P(w3w1,w2)P(wnw1,w2,,wn1)

  • N-gram的不足
    参数空间过大:当n过大时, P ( w n ∣ w 1 , w 2 , … , w n − 1 ) P(w_n|w_1,w_2,…,w_{n-1}) P(wnw1,w2,,wn1)达到字典级别大小,占据极大的存储空间,并且数据稀疏严重。

引入马尔科夫假设(Markov Assumption):一个词的出现仅与它之前的若干个词有关。通常取1或者2。
此时 Bi-gram
P ( S ) = P ( w 1 , w 2 , … , w n ) = P ( w 1 ) P ( w 2 ∣ w 1 ) P ( w 3 ∣ w 2 ) … P ( w n ∣ w n − 1 ) P(S) = P(w_1, w_2, …,w_n ) = P(w_1)P(w_2 |w_1)P(w_3|w_2)…P(w_n|w_{n-1}) P(S)=P(w1,w2,,wn)=P(w1)P(w2w1)P(w3w2)P(wnwn1)
Tri-gram:
P ( S ) = P ( w 1 , w 2 , … , w n ) = P ( w 1 ) P ( w 2 ∣ w 1 ) P ( w 3 ∣ w 1 , w 2 ) … P ( w n ∣ w n − 2 , w n − 1 ) P(S) = P(w_1, w_2, …,w_n ) = P(w_1)P(w_2 |w_1)P(w_3|w_1,w_2)…P(w_n|w_{n-2},w_{n-1}) P(S)=P(w1,w2,,wn)=P(w1)P(w2w1)P(w3w1,w2)P(wnwn2,wn1)

概率估计

根据大数定律,只要统计量足够,频率就无限接近概率。
P ( w n ∣ w n − 1 ) = P ( w n , w n − 1 ) P ( w n − 1 ) = C ( w n , w n − 1 ) C ( w n − 1 ) P(w_n|w_{n-1}) = \frac{P(w_n, w_{n-1})}{P(w_{n-1})} = \frac{C(w_n, w_{n-1})}{C(w_{n-1})} P(wnwn1)=P(wn1)P(wn,wn1)=C(wn1)C(wn,wn1)
P ( w n ∣ w n − 2 , w n − 1 ) = C ( w n , w n − 2 , w n − 1 ) C ( w n − 2 , w n − 1 ) P(w_n|w_{n-2},w_{n-1}) = \frac{C(w_n,w_{n-2},w_{n-1})}{C(w_{n-2},w_{n-1})} P(wnwn2,wn1)=C(wn2,wn1)C(wn,wn2,wn1)

nltk使用n-gram

nltk是一个用于英文自然语言处理NLPpython包,它提供了ngrams的实现方式。
如果我们想要进行中文ngrams模型,需要使用jieba等库首先进行中文分词。

from nltk import ngrams,bigrams,trigrams
import re 
import jieba 

text = '我喜欢吃苹果,他不喜欢吃香蕉。'

tokens = jieba.lcut(text)

tokens = [x for x in tokens if x and x not in '-\s.,;!?,。?!;、']

tokens

['我', '喜欢', '吃', '苹果', '他', '不', '喜欢', '吃', '香蕉']
ngramsres = [u' '.join(w) for w in ngrams(tokens, 2)]

ngramsres

['我 喜欢', '喜欢 吃', '吃 苹果', '苹果 他', '他 不', '不 喜欢', '喜欢 吃', '吃 香蕉']

nltk还提供了bigrams和trigrams等常见的n-gram模型的实现方式。

ngramsres = [w for w in bigrams(tokens)]

ngramsres

[('我', '喜欢'),
 ('喜欢', '吃'),
 ('吃', '苹果'),
 ('苹果', '他'),
 ('他', '不'),
 ('不', '喜欢'),
 ('喜欢', '吃'),
 ('吃', '香蕉')]

实际上n-gram模型实现方式很简单,在考虑语序的情况下,每一个n-gram子块内部是有顺序的。只需要按次遍历就可以实现,在nltk内部是通过迭代器的方式实现的,防止整个词汇字典过大时内存不足。

你可能感兴趣的:(自然语言处理nlp,easyui,前端,javascript,LDA,ngram,nltk,nlp)