N-gram模型的训练以及应用

语言模型

语言模型在实际应用中可以解决非常多的问题,例如判断一个句子的质量:

  • the house is big ! good
  • house big is the ! bad
  • the house is xxl ! worse

可以用于词的排序,比如the house is small优于small the is house;可以用于词的选择,I am going ___ (home/house),其中I am going home优于I am going house,除此之外,还有许多其他用途:

  • 语音识别
  • 机器翻译
  • 字符识别
  • 手写字体识别

概率语言模型

假设词串 W = w 1 , w 2 , . . . , w n W=w_{1},w_{2},...,w_{n} W=w1,w2,...,wn,以p(W)表示该词串可能出现的概率,那么从概率的角度上,
p ( W ) = p ( w 1 , w 2 , . . . , w n ) p(W)=p(w_{1},w_{2},...,w_{n}) p(W)=p(w1,w2,...,wn)
要计算p(W),根据链式法则有:
p ( W ) = p ( w 1 ) p ( w 2 ∣ w 1 ) . . . p ( w n ∣ w 1 , w 2 , . . . , w n − 1 ) p(W)=p(w_{1})p(w_{2}|w_{1})...p(w_{n}|w_{1},w_{2},...,w_{n-1}) p(W)=p(w1)p(w2w1)...p(wnw1,w2,...,wn1)
其中 w 1 , w 2 , . . . , w i − 1 w_{1},w_{2},...,w_{i-1} w1,w2,...,wi1为第i个词的历史词。
例句:likely connects audiences with content
p ( l i k e l y   c o n n e c t s   a u d i e n c e s   w i t h   c o n t e n t ) = p ( l i k e l y ∣ s e n t e n c e   s t a r t ) × p ( c o n n e c t s ∣ l i k e l y ) × p ( a u d i e n c e s ∣ l i k e l y , c o n n e c t s ) × p ( w i t h ∣ l i k e l y , c o n n e c t s , a u d i e n c e ) × p ( c o n t e n t ∣ l i k e l y , c o n n e c t s , a u d i e n c e , w i t h ) p(likely\,connects\,audiences\,with\,content)\\=p(likely|sentence\,start)\\\times p(connects|likely)\\\times p(audiences|likely,connects)\\\times p(with|likely,connects,audience)\\\times p(content|likely, connects, audience, with) p(likelyconnectsaudienceswithcontent)=p(likelysentencestart)×p(connectslikely)×p(audienceslikely,connects)×p(withlikely,connects,audience)×p(contentlikely,connects,audience,with)
那么如何用给定的语料库来训练N-gram语言模型呢?

极大似然估计

最简单的方式就是采用极大似然估计(Maximum Likelihood Estimation, MLE)。
p ( w m ∣ w 1 , w 2 , . . . , w m − 1 ) = C ( w 1 . . . w m − 1 , w m ) C ( w 1 . . . w m − 1 ) C ( w 1 . . . w m − 1 ) = ∑ w j ∈ W C ( w 1 . . . w m − 1 , w j ) p(w_{m}|w_{1},w_{2},...,w_{m-1})=\frac{C(w_{1}...w_{m-1},w_{m})}{C(w_{1}...w_{m-1})}\\ C(w_{1}...w_{m-1})=\sum_{w_{j}\in W}^{}C(w_{1}...w_{m-1},w_{j}) p(wmw1,w2,...,wm1)=C(w1...wm1)C(w1...wm1,wm)C(w1...wm1)=wjWC(w1...wm1,wj)
例如,采用MLE估计:
p ( c o n t e n t ∣ l i k e l y , c o n n e c t s , a u d i e n c e , w i t h ) = C ( l i k e l y   c o n n e c t s   a u d i e n c e s   w i t h   c o n t e n t ) C ( l i k e l y   c o n n e c t s   a u d i e n c e s   w i t h ) p(content|likely, connects, audience, with)\\=\frac{C(likely\,connects\,audiences\,with\,content)}{C(likely\,connects\,audiences\,with)} p(contentlikely,connects,audience,with)=C(likelyconnectsaudienceswith)C(likelyconnectsaudienceswithcontent)
该估计方法依赖于假设:当前词出现的概率依赖于前面的词。然而,如果前面词的个数很大,一方面,语料库中 C ( w 1 , w 2 , . . . , w m ) C(w_{1},w_{2},...,w_{m}) C(w1,w2,...,wm) C ( w 1 , w 2 , . . . , w m − 1 ) C(w_{1},w_{2},...,w_{m-1}) C(w1,w2,...,wm1)极有可能为0,就导致条件概率为0或无法计算。另一方面,随着历史长度的增城,不同历史数目会按指数级增长。
在此基础上,提出一个可行的方案:当前词仅依赖于较短的历史词。
→ p ( c o n t e n t ∣ c o n n e c t s , a u d i e n c e , w i t h ) \rightarrow p(content|connects, audience, with) p(contentconnects,audience,with)

  • 进行如上统计
  • 如果 C ( c o n n e c t s   a u d i e n c e s   w i t h   c o n t e n t ) = 0 C(connects\,audiences\,with\,content)=0 C(connectsaudienceswithcontent)=0

→ p ( c o n t e n t ∣ a u d i e n c e , w i t h ) \rightarrow p(content|audience, with) p(contentaudience,with)

→ p ( c o n t e n t ∣ w i t h ) \rightarrow p(content|with) p(contentwith)

→ p ( c o n t e n t ) \rightarrow p(content) p(content)

马尔科夫假设

位于某个特定状态的概率取决于前n-1个状态,即n-1阶马尔科夫链

马尔科夫假设应用于语言模型:假设每个词的出现概率只取决于前n-1个词。
p ( w i ∣ w 1 , w 2 , . . . , w i − 1 ) ≈ p ( w i ∣ w i − n + 1 , . . . , w i − 1 ) p(w_{i}|w_{1},w_{2},...,w_{i-1})\approx p(w_{i}|w_{i-n+1},...,w_{i-1}) p(wiw1,w2,...,wi1)p(wiwin+1,...,wi1)
这种语言模型也被称为N-gram模型(n元语法和n元文法)。

N-gram模型

  • 1-gram模型(unigram)
    p ( w 1 , w 2 , . . . , w n ) ≈ p ( w 1 ) p ( w 2 ) p ( w 3 ) . . . p ( w n ) p(w_{1},w_{2},...,w_{n})\approx p(w_{1})p(w_{2})p(w_{3})...p(w_{n}) p(w1,w2,...,wn)p(w1)p(w2)p(w3)...p(wn)
  • 2-gram模型(bigram)
    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(w_{1},w_{2},...,w_{n})\approx p(w_{1})p(w_{2}|w_{1})p(w_{3}|w_{2})...p(w_{n}|w_{n-1}) p(w1,w2,...,wn)p(w1)p(w2w1)p(w3w2)...p(wnwn1)
    (此处 w n − 1 w_{n-1} wn1被称为历史词)
  • 3-gram模型(trigram)
    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(w_{1},w_{2},...,w_{n})\approx 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(w1,w2,...,wn)p(w1)p(w2w1)p(w3w1,w2)...p(wnwn2,wn1)
    由于N-gram模型的马尔科夫假设,其对语言来说是一个“不充分”的模型,因为语言本身是长距离相依的,但却极大程度上满足了语言建模需要。
    如何使用语料库来训练N-gram模型呢?假设经过预处理的语料库document为由语段组成的列表,例如:
document = [
	'欧洲杯大战在即,荷兰葡萄牙面临淘汰将背水一战',
	'金正恩为朝少年团代表安排宴会,学生发誓坚决跟随',
	'证监会:重组中股票异常交易监管将加强',
	'台媒曝岛内大学教授假发票案,涉案教授或达千人',
	'中石油创历史新低,大盘或开启短线下跌空间',
]

代表每句话开头,代表每句话结尾,对语料进行处理,以N作为N-gram模型中的阶数参数,可以得到最终计算时分子列表与分母列表:

for doc in document:
    split_words = [''] + list(doc) + ['']
    # 分子
    [total_grams.append(tuple(split_words[i: i+N])) for i in range(len(split_words)-N+1)]
    # 分母
    [words.append(tuple(split_words[i:i+N-1])) for i in range(len(split_words)-N+2)]

至此基本的N-gram模型就训练成功了,根据实际需求添加功能就可以应用到实际案例中。

3-gram模型预测未出现的字

我们以搜狗实验室的搜狐新闻数据(SogouCS)为原始语料库,其格式如下:


页面URL
页面ID
页面标题
页面内容

注意:content字段去除了HTML标签,保存的是新闻正文文本

利用正则表达式对页面标题以及页面内容进行提取过滤:

file = open(path, 'r', encoding='utf-8').read()
pattern = re.compile(r'(.*?)', re.S)
contents = pattern.findall(file)

根据以上步骤训练出模型后,还有对模型进行改动,让其变成一个预测类模型:

# 分子词频字典
total_word_counter = Counter(total_grams)
# 分母词频字典
word_counter = Counter(words)

由于该3元模型主要预测最后一个字,所以前两个字已知的情况下来求第三个字的出现概率

# key为前两个字加上预测字的词语组合
next_word_prob = total_word_counter[key] / word_counter[key[:N - 1]]

对于每一个key,都有相应的next_word_prob 也就是它出现的概率对应,可以将这对参数作为集合,以key的前两个字为键,以集合为值构成字典,该字典也就是预测模型。
最后,对预测模型字典中的值,即上述对应集合,中的概率next_word_prob进行排序,根据输入的两个字,取出前五的集合对,这也就完成了预测。
N-gram模型的训练以及应用_第1张图片
最后,附上源代码地址:N-gram实现文字预测

你可能感兴趣的:(Python,NLP)