▶ 语言模型
计算词序列出现的概率 | p ( W ) = p ( w 1 , w 2 , w 3 . . . w n ) p(W) = p(w_1,w_2,w_3...w_n) p(W)=p(w1,w2,w3...wn) |
给定一个词序列,下一个词出现的概率 | p ( w 5 | w 4 , w 3 , w 2 , w 1 ) p(w_5|w_4,w_3,w_2,w_1) p(w5|w4,w3,w2,w1) |
▶ p(W)的计算
p ( 明 天 , 太 阳 , 从 , 西 边 , 升 起 ) p(明天,太阳,从,西边,升起) p(明天,太阳,从,西边,升起)
使用chain-rule规则计算这个词序列(其实就是个句子!)的概率
p(明天,太阳,从,西边,升起) = p(明天) p(太阳|明天) p(从|明天,太阳) p(西边|明天,太阳,从) p(升起|明天,太阳,从,西边)
仔细端详一下chain-rule规则,会发现它在实现时存在明显的弊端:
比如,如何求出p(升起|明天,太阳,从,西边)
?
这是因为组合太多,样本太少——“明天太阳从”这种特定组合串太难找了!
Markov假设可以对上面的链的计算进行简化:
p ( w 1 w 2 . . . w n ) = ∏ i = 1 n p ( w i ∣ w 1 w 2 . . . w i − 1 ) p(w_1w_2...w_n)=\prod_{i=1}^{n}{p(w_i|w_1w_2...w_{i-1})} p(w1w2...wn)=∏i=1np(wi∣w1w2...wi−1)
近似可看为:
p ( w i ∣ w 1 w 2 . . . w i − 1 ) = p ( w i ∣ w i − k w i − k + 1 . . . w i − 1 ) p(w_i|w_1w_2...w_{i-1})=p(w_i|w_{i-k}w_{i-k+1}...w_{i-1}) p(wi∣w1w2...wi−1)=p(wi∣wi−kwi−k+1...wi−1),k为固定值
简化: p(升起|明天,太阳,从,西边) = p(升起|从,西边)
甚至: p(升起|明天,太阳,从,西边) = p(升起|西边)
看了上面的例子其实不难理解,什么是马尔可夫(Markov)假设:
假设在一段文本中,第N个词的出现只与前面n-1个词相关,而与其他任何词都不相关。基于这样一种假设,可以评估文本中每一个词出现的概率,整句的概率就是各个词出现概率的乘积。
n-gram是基于统计的,基于马尔可夫假设的。它的基本思想是将文本里面的内容按照字节进行大小为n的滑动窗口操作。
通俗地说,其实在写这个链子的时候,条件概率的分母固定为1个,2个,3个…,甚至0个(下面会讲)
还是接着上面的例子:
p(明天,太阳,从,西边,升起) =p(太阳) p(从) p(西边) p(升起)
p(明天,太阳,从,西边,升起) = p(太阳|明天) p(从|太阳) p(西边|从) p(升起|西边)
p(明天,太阳,从,西边,升起) = p(从|明天,太阳) p(西边|太阳,从) p(升起|从,西边)
自上而下分别是:
一元模型(unigram model)
二元模型(bigram model)
三元模型(trigram model)
…
n元模型(N-gram model)
关于n-gram模型的理解:
也叫加一平滑(add-one smoothing),可以顾名思义:
p ( w n ∣ w n − 1 ) = C ( w n − 1 , w n ) + 1 C ( w n − 1 ) + V p(w_n|w_{n-1})=\frac{C(w_{n-1},w_n)+1}{C(w_{n-1})+V} p(wn∣wn−1)=C(wn−1)+VC(wn−1,wn)+1 (其中v是词语集合(Set)的长度)【★】
# nltk库提供了直接生成N-gram的方法
# 以布朗语料库的单词(token)为例,尝试使用它
from nltk.corpus import brown
from nltk.util import ngrams
token = []
for each in brown.categories():
token.append(brown.words(categories = each))
unigram = ngrams(token, 1)
bigram = ngrams(token, 2)
# emmmm...简单无脑,而且好用 >_<