本文为罗周杨原创,转载请注明作者和出处。
斯坦福经典NLP教程Speech and Language Processing中N-Grams读书笔记。
给一系列的词语计算概率的模型叫做语言模型(Language Models),其中,n-gram是最简单的一种。一个n-gram
就是一个长度为N
的词语组成的序列:
N=2
,则是2-gram
(bigram)N=3
,则是3-gram
(trigram)
一个简单的例子
有一个任务,要计算,即给定历史计算的概率。假设,我们要计算下一个词the
的概率,即:
一个可行的方式是:在一个很大的语料库中,统计出现的次数,然后统计的次数,后者除以前者,即:
这种方式在很多情况下可行。但是某些情况下仍然会有以下问题:
- 有些词语在预料中出现次数为0。
相似的问题还出现在:如果我们想知道整个序列的联合概率,例如,那我们就可以将问题转化为:“在所有5个词语的序列中,its water is so transparent
出现了几次?”
为了解决这个问题,我们需要更好地方式来估计基于的概率,或者整个序列的概率。
我们把一个长度为N
的序列表示为,简单表示成,那么:
上面的链式法则(chain rule)表面了联合概率和条件概率之间的联系。
但是上面的连乘也带来问题:
- 对于很长的序列,计算量很大
- 如果其中任何一项概率为0,那么整个联合概率变为0
N-Grams
n-gram并不是计算某个词基于整个历史的概率,而是用少数几个历史词语来替代整个历史。
对于bigram模型,我们只计算即可,也就是说,退化成了,即:
这个单词的概率只基于前面若干个个单词假设叫做马尔科夫假设(Markov assumption)。
因此,对于通常的n-gram模型,下一个单词基于前面所有词的条件概率,可以简化为:
回到bigram模型,我们整个序列的联合概率,可以简化成:
那么我们怎么估计这些bigram或者n-gram的概率呢?一个直观的方法就是最大似然估计(maximum likelihood estimation or MLE)。
具体的做法是,选一个预料,进行计数,然后进行归一化。
还是以bigram为例,
分母是所有以开头的词语的总数,也就是所,可以简化为**出现的次数**!即:
在实际的处理中,我们通常会给每一个句子加上开始标记和结束标记,例如<s>
和</s>
。
<s>
是为了让第一个词语有上下文,</s>
是为了制造一个更加真实的概率分布。
We need the end-symbol to make the bigram grammer a true probability distribution. Without an end-symbol, the sentence probabilities for all sentences of given length would sum to one.
实际操作的问题和技巧
还有一些实际上的问题和处理方法。
在N
比较大的n-gram模型中,比如4-gram或者5-gram,对于句子前面的几个单词,我们没有足够长的历史词,那么我们的做法就是制造几个伪词。
例如,在3-gram中,对于句子I love cake.
,我们首先处理成<s>I love cake.</s>
,那么对于第一个词的条件概率
P(I|<s><s>)
。
还有就是,我们通常使用 对数概率(log probability) 而不是上面所说的概率,因为对数概率带来两个好处:
- 取对数可以把连乘转换成累加,可以加速计算
- 可以防止数值溢出
评估语言模型
在数据集的划分上,通常的做法是把训练集分成以下三部分:
- .
- |-data_set
- |----training_set(80%)
- |----dev_set (10%)
- |----test_set (10%)
- 复制代码
其中,训练集用来训练模型,验证集用来调整模型的参数,测试集用来评估模型的性能。
一个常用的评估方式就是困惑度(perplexity)。
对于一个测试集,困惑度计算如下:
根据链式法则,有
特别地,对于bigram,上式可以简化为
联系我
- 微信: luozhouyang0528
- 邮箱: stupidme.me.lzy@gmail.com
- 公众号: stupidmedotme