# 一、引言

  n-gram 算法通过统计文本中连续 n 个词的序列(或称为 “词组”)出现的频率,为各种 NLP 任务提供了有力的支持。

  N-gram 模型的基本原理是基于马尔可夫假设,在训练 N-gram 模型时使用最大似然估计模型参数 —— 条件概率.

# 二、示例

  例如,对于 “The cow jumps over the moon” 这句话。如果 N=2(称为二元模型),那么 ngram 将为:

the cow
cow jumps
jumps over
over the
the moon

  在这种情况下有 5 个 n 元语法。请注意,从 the->cow 转移到 cow->jumpsJumps->over 等,本质上是向前移动一个单词以生成下一个二元组。

  如果 N=3,则 n 元语法将为:

the cow jumps
cow jumps over
jumps over the
over the moon

  在这种情况下有 4 个 n 元语法。当 N=1 时,被称为一元语法,本质上是句子中的各个单词。当 N=2 时,称为二元组;当 N=3 时,称为三元组。当 N>3 时,这通常被称为多元组等等。

Ngram=X(N1)N_{gram}=X-(N-1)

# 三、n-gram 算法的优缺点

(1)优点

  • 简单易实现:n-gram 算法基于统计原理,实现起来相对简单直观。
  • 通用性强:n-gram 算法可以应用于多种 NLP 任务,具有广泛的适用性。
  • 效果好:在适当的 n 值下,n-gram 算法能够捕捉到文本中的局部统计信息,对于某些任务具有较好的效果。

(2)缺点

  • 数据稀疏性:随着 n 的增加,n-gram 的数量急剧增长,导致很多 n-gram 在文本中只出现一次或根本不出现,这使得频率统计变得不可靠。
  • 上下文信息有限:n-gram 只考虑了固定长度的上下文信息,无法捕捉更复杂的语义关系。对于较长的句子或篇章,n-gram 可能无法充分表达其整体意义。
  • 计算复杂度高:当 n 较大或文本较长时,生成和统计 n-gram 的计算复杂度会显著增加,可能导致性能问题。

# 三、程序实现

import re
def generate_ngrams(text,n):
    # split sentences into tokens
    tokens=re.split("\\s+",text)
    ngrams=[]
    # collect the n-grams
    for i in range(len(tokens)-n+1):
       temp=[tokens[j] for j in range(i,i+n)]
       ngrams.append(" ".join(temp))
    return ngrams
sentence = '_start_ this is ngram _generation_'
my_ngrams = generate_ngrams(sentence.split(), 3)
print([w for w in my_ngrams])

  输出:

['_start_ this is', 'this is ngram', 'is ngram _generation_']

  或者使用 NLTK 包

from nltk import ngrams
sentence = '_start_ this is ngram _generation_'
my_ngrams = ngrams(sentence.split(), 3)
print([w for w in my_ngrams])

  输出:

[('_start_', 'this', 'is'), ('this', 'is', 'ngram'), ('is', 'ngram', '_generation_')]
更新于 阅读次数