n-gram

n-gram

基本原理

N-gram是一种简单的语言模型,在一些NLP任务中,我们需要判断一句话出现的概率是多少,即这句话是不是符合人的说话习惯,这时就可以利用到N-gram。例如在搜索引擎中输入一个词语,下面会出现多个扩展词条,这种功能其实就可以通过N-gram实现。

N-gram的数据模型很简单,就一条数学表达式:

p(s)=p(w1,w2,...,wT)=p(w1)p(w2w1)p(w3w1,w2)...p(wtw1,w2,...,w(T1))p(s) = p(w_1, w_2, ..., w_T) = p(w_1)p(w_2|w_1)p(w_3|w_1,w_2)...p(w_t|w_1,w_2,...,w_(T-1))

这个概率公式的意义为:第一次词确认后,看后面的词在前面词出现的情况下出现的概率。

例如,句子 燕子没有你我可怎么活啊,分词后 燕子 没有你 我可 怎么活

那么这整句话出现的概率:p(燕子,没有你,我可,怎么活) = p(燕子)p(没有你|燕子)p(我可|燕子,没有你)p(怎么活|燕子,没有你,我可)

  • p(燕子)表示燕子这个词在语料库中出现的概率;
  • p(没有你|燕子)表示在燕子后出现没有你的概率;
  • 以此类推...

把这些概率一次相乘就是整句话出现的概率,然后按照用户输入的词条,取出语料库中概率的topk个词条就可以实现扩展词条的功能。

p(s)=p(w1,w2,...,wT)=i=1Tp(wiContexti)p(s) = p(w_1,w_2,...,w_T) = \sum_{i=1}^{T}p(w_i|Context_i)

其中ContextContext就是词语的上下文,例如我可ContextContext就是:燕子、没有你

而N-gram假设一个词的之和前N个词相关,即马尔可夫模型的思想。

向量表示

N-Gram是一种基于统计语言模型的算法。它的基本思想是将文本里面的内容按照字节进行大小为N的滑动窗口操作,形成了长度是N的字节片段序列。

每一个字节片段称为gram,对所有gram的出现频度进行统计,并且按照事先设定好的阈值进行过滤,形成关键gram列表,也就是这个文本的向量特征空间,列表中的每一种gram就是一个特征向量维度。

例子
比如我们现在使用单元Unigram二元的Bi-gram三元的Tri-gram模型来进行特征提取。

我们的训练样本为:

  1. 我去了北京天安门
  2. 我是中国人

那么我们对每一个样本进行单元Unigram、二元的Bi-gram和三元的Tri-gram模型提取。

  1. 单元Unigram
    我去了北京天安门 => /我/去了/北京/天安门/
    我是中国人 => /我/是/中国人/

  2. 二元Bi-gram
    我去了北京天安门 => /我 去了/去了 北京/北京 天安门/
    我是中国人 => /我 是/是 中国人/

  3. 三元Tri-gram
    我去了北京天安门 => /我 去了 北京/去了 北京 天安门/
    我是中国人 => /我 是 中国人/

那么从上面可以得出,我们的特征向量包含我在训练数据中利用单元Unigram,二元Bi-gram,以及三元Tri-gram抽取出的不同特征,组成我的特征向量维度。

然后以后对应一句话,直接进行Unigram,Bi-gram,Tri-gram进行抽取特征,出现哪个特征,就统计它的频数,最后填在特征向量中即可。

比如上面的特征向量我列举一下顺序如:

我、是、中国人、去了、北京、天安门、我 是、是 中国人、我 去了、去了 北京、北京 天安门、我 去了 北京、去了 北京 天安门、 我 是 中国人。

抽取特征过程

那么对于一句话我是中国人进行N-gram特征抽取的方法是:

  1. 单元Unigram来说
    我是中国人 => /我/是/中国人/

  2. 二元Bi-gram
    我是中国人 => /我 是/是 中国人/

  3. 三元Tri-gram
    我是中国人 => /我 是 中国人/

于是我们就在出现的词语维度赋值为1,其余没有出现过的特征赋值为0,相当于one-hot特征,得到特征向量:[1,1,1,0,0,0,1,1,0,0,0,0,0,0,1],得到的这个特征向量就是我们使用N-gram提取特征方法提取出来的特征。

总结

如果我们使用N-gram提取特征,使用unigram,bigram,trigram提取特征的情况,在词汇表大小为VV的时候,特征向量维度长度为[V(unigram)+V2(bigram)+V3(trigram)][V(unigram)+V^2(bigram)+V^3(trigram)]