Skip to content

N-Gram模型

从 1970 年以后人们意识到不能基于规则,得基于统计这个时间节点开始,就出现了很多语言模型。

基本介绍

N-Gram模型诞生于 1950s–1960s,最早由香农(Claude Shannon)在信息论中提出,用于语言的概率建模,香农在 1951 年的论文中提出,使用 1-gram、2-gram 等方法估计英文文本的概率。前面的 N 是一个数字,表示你每次要看几个词,例如:

该模型基于马尔可夫假设。

马尔可夫假设:一个词出现的概率,依赖于它前面的 N-1 个词,而不是整个句子历史。

(厨房)妈妈说:“帮我拿一下冰箱里面的....”

在你的大脑中,就会自动的去预测下一个词。

不会弹出下面的词:

工作原理

这里我们以 Bigram(2-Gram):会看前面的一个词。

假设我们有这样一个“语料库”,我们用这些数据来训练模型:

“我 爱 吃 苹果”
“我 爱 吃 香蕉”
“我 喜欢 吃 苹果”

Bigram 模型会根据一个词统计下一个词出现的概率,这里我们可以数一数所有词对:

前一个词下一个词次数
2 次
喜欢1 次
2 次
喜欢1 次
苹果2 次
香蕉1 次

根据这个词的组合,就可以去预测一个词的下一个词,比如:

所以:

如果你看到“我 爱 吃”,那下一个词大概率是“苹果”!

代码实践

jieba 是 python 里面用于对中文分词的一个库。

“我喜欢吃苹果”

我、喜欢、吃、苹果

import jieba # 导入 jieba 中文分词库
# 导入 defaultdict 和 Counter,用于构建频率统计表
from collections import defaultdict, Counter
# 示例语料库(注意:这些是连续的中文句子,没有空格)
corpus = [
"我喜欢吃苹果",
"我喜欢吃香蕉",
"她喜欢吃葡萄",
"他不喜欢吃香蕉",
"他喜欢吃苹果",
"她喜欢吃草莓"
]
# 1. 构建 Bigram 统计表,格式为 bigrams[前一个词][下一个词] = 出现次数
bigrams = defaultdict(Counter) # 自动初始化嵌套结构,避免手动判断键是否存在
# 遍历每一句话
for sentence in corpus:
words = list(jieba.cut(sentence)) # 使用 jieba 对句子进行分词,返回词列表
# 构建二元组(Bigram):每两个连续词之间的搭配
for i in range(len(words) - 1):
w1, w2 = words[i], words[i + 1] # 当前词和下一个词
bigrams[w1][w2] += 1 # 出现一次就 +1
# 2. 将频率转换成概率,构建 Bigram 概率模型
bigram_probs = {} # 最终保存的是 P(w2 | w1) 的概率表
# 遍历所有前词(w1)
for w1 in bigrams:
total = sum(bigrams[w1].values()) # w1 后面出现所有词的总次数
# 计算每一个 w2 的条件概率:P(w2 | w1) = 频率 / 总数
bigram_probs[w1] = {
w2: count / total for w2, count in bigrams[w1].items()
}
# 3. 定义一个函数:输入一个词,预测它后面最可能出现的词(按概率从大到小排序)
def predict_next_word(word):
if word not in bigram_probs:
return "未知(没有数据)" # 如果这个词从未出现在训练语料中
# 按照概率从高到低排序返回
sorted_probs = sorted(
bigram_probs[word].items(), key=lambda x: x[1], reverse=True
)
return sorted_probs
# 4. 打印所有 Bigram 的条件概率
print("=== Bigram 概率 ===")
for w1 in bigram_probs:
for w2 in bigram_probs[w1]:
prob = bigram_probs[w1][w2]
print(f"P({w2} | {w1}) = {prob:.2f}") # 输出形如:P(吃 | 喜欢) = 1.00
# 5. 测试预测某些词后面最可能出现的词
print("\n=== 预测示例 ===")
for test_word in ["", "", "喜欢", "苹果"]:
print(f"{test_word}{predict_next_word(test_word)}")

N-Gram 虽然比较简陋,但是它确确实实是基于统计语言建模的起点。

N-Gram模型缺陷

  1. 语境短视:只看前 N-1个词,无法理解长距离词性的依赖。
    • “我昨天见到一个朋友,他说他非常喜欢编程。”
  2. 无法泛化:只能记住见过的词语组合,对没有见过的组合无能为力。
    • 语料库:我爱吃西瓜(没有葡萄这个词)
    • 永远不可能出现:我爱吃葡萄 这种组合
  3. 不具备语义理解能力
    • 无法判断:喜欢 和 爱 这两个词,词性是相似
    • 也不能区分:“我打了他”和“他打了我”

总结一句话:只会记录词语搭配,不会理解语言。

适用于早期的简单的文本处理任务。


-EOF-