当前位置: 首页 > news >正文

N-gram语言模型原理与实战教程

在自然语言处理(NLP)领域,语言模型(Language Model)是评估一句话是否**“通顺”**的基础工具。尤其在早期 NLP 中,N-gram 是非常经典且高效的一类统计语言模型。

什么是 N-gram?

N-gram 是自然语言处理中,将文本按连续的 N 个词(或字符)划分的技术。

  • N=1:Unigram,单个词
  • N=2:Bigram,两个连续词 - 一阶马尔科夫
  • N=3:Trigram,三个连续词 - 二阶马尔科夫

例如句子:“我 爱 自然 语言”,它的 Bigram 是:“我 爱”,“爱 自然”,“自然 语言”。

马尔科夫假设(Markov Assumption)

在自然语言处理中,我们经常需要预测一句话中下一个单词的概率。而为了简化计算复杂度,马尔科夫假设(Markov Assumption) 就应运而生,成为 N-gram 语言模型等传统 NLP 方法的数学基础。

马尔科夫假设指的是:当前状态的概率,只依赖于有限个前置状态,而与更早的历史无关。
简单说,马尔科夫假设就是“当前只看前面有限几个词,不用全历史”,方便快速做语言预测。

数学定义

一句话: P(w_1, w_2, w_3, \ldots, w_n)

马尔科夫假设简化成:

  • 一阶马尔科夫(Bigram): P(w_n | w_1, w_2, \ldots, w_{n-1}) \approx P(w_n | w_{n-1})
  • 二阶马尔科夫(Trigram): P(w_n | w_1, w_2, \ldots, w_{n-1}) \approx P(w_n | w_{n-2}, w_{n-1})

举例说明

原句我 爱 自然 语言 处理
如果用 Bigram 模型计算:

P(我, 爱, 自然, 语言, 处理)
= P(我) \times  P(爱|我) \times  P(自然|爱) \times  P(语言|自然) \times  P(处理|语言)

什么是 N-gram 语言模型?

N-gram 是一种基于统计的方法,通过计算连续 N 个单词组成的子序列出现的概率,来预测下一个单词或评估整个句子。

  • Unigram(一元模型):只看当前词
  • Bigram(二元模型):看当前词和前一个词
  • Trigram(三元模型):看当前词和前两个词

N-gram 语言模型应用场景

场景用途说明
拼写纠错判断词对合法性,检测异常搭配
文本生成基于已有语料预测下一个单词,自动续写句子
语言模型评分计算一句话的概率,判断其通顺程度
分词与文本纠错在中文 NLP 分词、句子切分中辅助作用

Python 实战:N-gram 模型实现

环境准备

import nltk
from nltk.util import ngrams
from nltk.tokenize import word_tokenize
from nltk import FreqDist
from collections import Counter
import randomnltk.download('punkt')

训练预料

text = "我 爱 自然 语言 处理 和 机器 学习  我 爱 美女 也 爱 美食"
tokens = word_tokenize(text)
bigrams = list(ngrams(tokens, 2))
print(f"bigrams:{bigrams}")
fdist = FreqDist(bigrams)
fdist

输出

bigrams:[('我', '爱'), ('爱', '自然'), ('自然', '语言'), ('语言', '处理'), ('处理', '和'), ('和', '机器'), ('机器', '学习'), ('学习', '我'), ('我', '爱'), ('爱', '美女'), ('美女', '也'), ('也', '爱'), ('爱', '美食')]
FreqDist({('我', '爱'): 2, ('爱', '自然'): 1, ('自然', '语言'): 1, ('语言', '处理'): 1, ('处理', '和'): 1, ('和', '机器'): 1, ('机器', '学习'): 1, ('学习', '我'): 1, ('爱', '美女'): 1, ('美女', '也'): 1, ...})

1.拼写纠错案例

# 判断词对是否合理
def is_valid_bigram(w1, w2):return fdist[(w1, w2)] > 0# 📑 Test Case
test_sentences = ["我 爱 自然 语言","自然 学习 机器"
]for sentence in test_sentences:print(f"\n检测句子: {sentence}")test_tokens = word_tokenize(sentence)test_bigrams = list(ngrams(test_tokens, 2))for bigram in test_bigrams:if is_valid_bigram(bigram[0], bigram[1]):print(f"✔️ {bigram} 合法")else:print(f"❌ {bigram} 可疑")

输出

检测句子: 我 爱 自然 语言
✔️ ('我', '爱') 合法
✔️ ('爱', '自然') 合法
✔️ ('自然', '语言') 合法检测句子: 自然 学习 机器
❌ ('自然', '学习') 可疑
❌ ('学习', '机器') 可疑

2.文本生成案例

构建 Bigram 词典

# 构建 Bigram 词典
model = {}
for w1, w2 in bigrams:if w1 in model:model[w1].append(w2)else:model[w1] = [w2]
model

输出

{'我': ['爱', '爱'],'爱': ['自然', '美女', '美食'],'自然': ['语言'],'语言': ['处理'],'处理': ['和'],'和': ['机器'],'机器': ['学习'],'学习': ['我'],'美女': ['也'],'也': ['爱']}

生成句子

# 生成句子(长度为6个词)
def generate_sentence(start_word, length=6):result = [start_word]for _ in range(length - 1):next_words = model.get(result[-1])if not next_words:breaknext_word = random.choice(next_words)result.append(next_word)return ' '.join(result)# 📑 Test Case
print("\n📌 文本生成示例:")
print(generate_sentence("我"))
print(generate_sentence("语言"))

输出

📌 文本生成示例:
我 爱 自然 语言 处理 和
语言 处理 和 机器 学习 我

3.语言模型评分案例

w2

from collections import Counter
# Bigram + Unigram 频率表
bigram_counts = Counter(bigrams)
bigram_counts

输出

Counter({('我', '爱'): 2,('爱', '自然'): 1,('自然', '语言'): 1,('语言', '处理'): 1,('处理', '和'): 1,('和', '机器'): 1,('机器', '学习'): 1,('学习', '我'): 1,('爱', '美女'): 1,('美女', '也'): 1,('也', '爱'): 1,('爱', '美食'): 1})

w1

unigram_counts = Counter(tokens) # 单个词,
unigram_counts

输出

Counter({'爱': 3,'我': 2,'自然': 1,'语言': 1,'处理': 1,'和': 1,'机器': 1,'学习': 1,'美女': 1,'也': 1,'美食': 1})

计算句子概率

# 计算 P(w2|w1)
def bigram_prob(w1, w2):return bigram_counts[(w1, w2)] / unigram_counts[w1] if unigram_counts[w1] > 0 else 0# 计算句子概率
def sentence_prob(sentence):tokens = word_tokenize(sentence)sentence_bigrams = list(ngrams(tokens, 2))prob = 1.0for w1, w2 in sentence_bigrams:p = bigram_prob(w1, w2)if p == 0:prob *= 1e-6  # 平滑处理,表示一个接近0的值else:prob *= preturn prob# 📑 Test Case
test_sentences = ["我 爱 自然 语言","自然 学习 机器","机器 学习"
]print("\n📌 句子概率评分:")
for sentence in test_sentences:print(f"'{sentence}' 概率: {sentence_prob(sentence)}")

输出

📌 句子概率评分:
'我 爱 自然 语言' 概率: 0.3333333333333333
'自然 学习 机器' 概率: 1e-12
'机器 学习' 概率: 1.0

相关文章:

  • Issac Lab安装
  • java I/O
  • SQLSERVER数据库表分区学习(未在项目上使用)
  • 地信GIS专业关于学习、考研、就业方面的一些问题答疑
  • HCIP-AI培养计划,成为新时代AI解决方案架构高级工程师
  • 【Dify学习笔记】:dify通过ollama加载DeepSeek-R1-32B模型无法加载!终于解决了!!
  • DL00786-基于RTDETR的水稻病害检测含完整数据集
  • C++函数封装和绑定
  • JWT了解
  • 有了CodeBuddy,10分钟上线MBTI测试网站
  • PiliPlus 非常好用的开源软件第三方B站哔哩哔哩 v1.1.3.35
  • upload-labs通关笔记-第18关文件上传之条件竞争
  • 文件操作和IO-3 文件内容的读写
  • QScrollArea内容增加后自动跳到底部
  • Python生成物理引擎的简单知识图谱
  • JavaScript 垃圾回收与内存泄漏
  • JavaScript中从原数组中删除某个元素
  • STM32 CAN CANAerospace
  • 使用 Docker 搭建 PyWPS 2.0 服务全流程详解
  • matIo库及.mat数据格式介绍
  • 合肥餐饮网站建设/seo是什么意思为什么要做seo
  • 网站用户维度/做个网站需要多少钱
  • 阿里云做企业网站/聊城优化seo
  • 营销网站建设苏州/推广普通话手抄报句子
  • 汕头百姓网交友/seo网站优化
  • 导航网站cms/公众号引流推广平台