NLP学习路线图(十六):N-gram模型

一、为何需要语言模型?概率视角下的语言本质

自然语言处理的核心挑战在于让机器“理解”人类语言。这种理解的一个关键方面是处理语言的歧义性、创造性和结构性。语言模型(Language Model, LM)为此提供了一种强大的数学框架:它赋予任何词序列一个概率,用以衡量该序列在真实语言中出现的可能性

1.1 语言模型的核心任务

  • 评估序列合理性:判断一个句子“The cat sat on the mat”是否比“Mat the on sat cat the”更像人话。

  • 预测下一个词:给定上文“I have a dream...”,预测下一个最可能出现的词(如“that”)。

  • 生成连贯文本:基于概率采样,逐步生成新的、语法语义合理的句子。

1.2 统计语言模型的兴起

在早期NLP中,基于规则的方法试图用语法书般的精确规则描述语言,但很快遇到瓶颈:人类语言充满例外、方言和动态变化,规则难以穷尽。统计语言模型应运而生,其核心理念是:

“一个词出现的可能性,可以由它在大量文本数据中出现的频率来估计。”

N-gram模型正是这一理念最直接、最成功的实现之一。


二、N-gram模型:概念与数学基础

2.1 核心定义

  • N-gram:指文本中连续出现的N个词(或符号)单元。例如:

    • Unigram (1-gram): ["the"], ["cat"], ["sat"]

    • Bigram (2-gram): ["the", "cat"], ["cat", "sat"]

    • Trigram (3-gram): ["the", "cat", "sat"]

  • N-gram语言模型:一个基于马尔可夫假设的统计模型,它假设一个词出现的概率仅依赖于它前面的有限个词(通常是N-1个)。这是对现实语言复杂依赖关系的一种简化,但实践证明非常有效。

2.2 数学建模:链式法则与马尔可夫假设

语言模型的目标是为整个词序列W = (w1, w2, ..., wm) 赋予概率P(W)。根据概率的链式法则:
P(W) = P(w1) * P(w2|w1) * P(w3|w1, w2) * ... * P(wm|w1, w2, ..., wm-1)

精确计算P(wm|w1, w2, ..., wm-1)需要知道所有可能的历史组合的概率,这在数据有限时几乎不可能。马尔可夫假设提供了简化方案:假设一个词的概率只依赖于前面有限的k个词。当k = N-1时,我们得到N-gram模型

P(wm|w1, w2, ..., wm-1) ≈ P(wm|wm-N+1, wm-N+2, ..., wm-1)

因此,序列概率近似为:
P(W) ≈ Π P(wi|wi-N+1, ..., wi-1)

2.3 概率估计:最大似然估计(MLE)

模型参数P(wi|wi-N+1, ..., wi-1)如何获得?最直观的方法是在大型训练语料库中计数

P(wi | wi-N+1, ..., wi-1) = Count(wi-N+1, ..., wi-1, wi) / Count(wi-N+1, ..., wi-1)

  • Count(wi-N+1, ..., wi-1, wi):特定N-gram序列在语料中出现的次数。

  • Count(wi-N+1, ..., wi-1):该序列的历史上下文(前N-1个词)出现的次数。

示例: 在语料“the cat sat on the mat”中:

  • P(sat | the cat) = Count(the cat sat) / Count(the cat) = 1 / 1 = 1.0

  • P(mat | on the) = Count(on the mat) / Count(on the) = 1 / 1 = 1.0

三、构建N-gram模型:从数据到应用

3.1 训练流程

  1. 数据收集与预处理:收集大规模、领域相关的文本数据。进行分词、去除标点/数字(可选)、统一大小写、处理OOV词(如替换为<UNK>)。

  2. 计数统计:扫描语料,统计所有1-gram, 2-gram, ..., N-gram的出现频次。通常使用高效的数据结构(如哈希表、前缀树)。

  3. 概率计算:应用MLE公式计算所有条件概率P(wi | context)

  4. 平滑处理(关键!):处理零概率问题(见下一节)。

  5. 模型存储:存储计算好的概率表(通常很大,需优化)。

3.2 解码与应用:预测与生成

  • 下一个词预测:给定上下文(wi-N+1, ..., wi-1),查找概率P(w | wi-N+1, ..., wi-1)最大的词w

  • 序列概率评估:利用链式法则计算整个序列的概率(通常取对数避免下溢)。

  • 文本生成

    1. 给定起始词(或<S>标记)。

    2. 基于当前上下文(最后N-1个词),根据概率分布P(w | context)采样下一个词。

    3. 将采样词加入序列,更新上下文。

    4. 重复步骤2-3,直到生成结束标记</S>或达到长度限制。

四、挑战与对策:平滑技术详解

MLE估计的最大问题是数据稀疏性:语料库再大,也无法覆盖所有可能的N-gram组合。未在训练集中出现的N-gram(零频问题)会直接导致概率为零,进而使整个序列的概率为零,这显然不合理。平滑(Smoothing) 技术通过“劫富济贫”来解决此问题。

4.1 核心思想

  • 为所有可能的N-gram(即使未出现)分配非零概率。

  • 从高频N-gram的概率中“借”一小部分,分配给低频或零频N-gram。

  • 确保所有概率之和为1。

4.2 常用平滑方法

  1. 加一平滑(拉普拉斯平滑)

    • 最简单直观。

    • 公式:P(wi | wi-N+1, ..., wi-1) = (Count(wi-N+1, ..., wi-1, wi) + 1) / (Count(wi-N+1, ..., wi-1) + V)

    • V:词汇表大小。

    • 优点:实现简单。

    • 缺点:对高频N-gram概率削减过多;对于大N或大V,分配的概率太小,效果常不理想。

  2. 加K平滑(Lidstone平滑)

    • 加一平滑的推广,加一个小的常数k(0 < k < 1)。

    • 公式:P = (Count + k) / (Count_Context + k * V)

    • 通过调整k可以在偏差和方差间取得平衡。

  3. 古德-图灵估计(Good-Turing)

    • 更智能的平滑。核心思想:用观察到的出现r次的N-gram数量,来估计出现r次的事物的总概率质量,并将其分配给未出现(r=0)的事物

    • 计算调整频次:r* = (r+1) * N(r+1) / N(r),其中N(r)是出现r次的N-gram类型数。

    • 将频次为0的N-gram概率估计为:P = N(1) / NN是总token数)。

    • 优点:理论基础坚实,效果较好。

    • 缺点:计算复杂,需统计所有频次N(r);对于高频r,N(r)可能为0或不稳定。

  4. 回退(Backoff)

    • 核心思想:如果一个高阶N-gram(如trigram)没有数据,就“回退”到低阶N-gram(如bigram或unigram)的估计。

    • 条件:通常仅在Count(HighOrderNgram) = 0时触发回退。

    • 概率分配:高阶概率为0时,使用低阶概率乘以一个回退权重αα < 1),以确保总概率质量守恒。

    • 公式(以trigram回退到bigram为例):

      P(wi | wi-2, wi-1) = {Count(wi-2, wi-1, wi) / Count(wi-2, wi-1)   if Count(wi-2, wi-1, wi) > 0α(wi-2, wi-1) * P(wi | wi-1)               otherwise
      }
    • 权重计算α需要精心设计,保证在wi-2, wi-1条件下,所有词的概率和为1。

  5. 插值(Interpolation)

    • 核心思想:无论高阶N-gram是否存在数据,总是将不同阶(unigram, bigram, trigram, ...)的估计混合起来。

    • 公式(以trigram插值为例):
      P(wi | wi-2, wi-1) = λ1 * P(wi) + λ2 * P(wi | wi-1) + λ3 * P(wi | wi-2, wi-1)

    • 约束λ1 + λ2 + λ3 = 1λi >= 0

    • 优点:更鲁棒,即使高阶gram有数据,低阶gram也能提供有价值信息,防止过拟合。

    • 权重学习λ参数通常通过在留存数据集(held-out data)上优化模型困惑度(Perplexity)来学习。

  6. Kneser-Ney平滑

    • 被广泛认为是效果最佳的N-gram平滑方法之一,结合了回退和绝对折扣的思想。

    • 核心创新(主要在unigram概率上):

      • 延续概率(Continuation Probability):低阶模型(如unigram)不再仅基于词频,而是考虑一个词出现在不同上下文类型中的多样性

      • 公式(以bigram Kneser-Ney为例):

        P_KN(wi | wi-1) = max(Count(wi-1, wi) - D, 0) / Count(wi-1)  + λ(wi-1) * P_Continuation(wi)
        P_Continuation(wi) = |{v: Count(v, wi) > 0}| / |{(u, v): Count(u, v) > 0}|
      • D:折扣常数(通常0.75左右)。

      • λ(wi-1):归一化因子,保证概率和为1。

      • P_Continuation(wi):衡量wi作为新上下文“接续词”的能力。想象“Francisco”在“San Francisco”中频率高,但单独作为接续词能力弱(主要接在“San”后);而“cup”则可能出现在“coffee cup”, “world cup”等多种上下文中,其P_Continuation较高。

    • 优点:显著提高了对低频词和未知上下文的建模能力。

    • 变种:Modified Kneser-Ney (MKN) 使用多个折扣值(对不同频次)。

下表总结了主要平滑方法的比较:

平滑方法核心思想优点缺点适用场景
加一(拉普拉斯)所有计数+1实现极其简单高频项概率削减过多,效果常不佳教学示例,快速原型
加K平滑所有计数 + k (0<k<1)比加一灵活,可调参数k值选择需经验或优化,高频项仍被削对简单加一的改进
古德-图灵用出现r次类型数估计r*概率理论基础好,对零频项估计合理计算复杂,高频估计不稳定需要较好理论基础的中小模型
回退高阶无数据时回退到低阶直觉清晰,实现相对直接权重设计复杂,仅高阶缺失时才用低阶资源受限,需显式回退逻辑
插值混合不同阶模型,加权平均更鲁棒,充分利用各级信息需学习权重参数,计算开销稍大追求最佳效果的通用场景
Kneser-Ney折扣+回退+独特接续概率公认效果最好实现最复杂,计算开销最大对性能要求高的生产系统

五、N-gram模型的应用场景

尽管相对“传统”,N-gram模型凭借其高效、简单和可解释性,在众多场景中仍有一席之地,或作为更复杂系统的组件:

  1. 文本输入法

    • 核心应用!基于用户输入的前几个词(或拼音音节),预测下一个最可能的候选词。

    • Bigram/Trigram模型在此任务上非常高效且有效。

    • 例如:输入“wo xiang”,模型基于“我想”的历史,高概率预测“吃”、“要”、“买”等词。

  2. 拼写检查与语法纠错

    • 检测低概率词序列。句子“I are a student”中“I are”的bigram概率会极低,触发错误警报。

    • 结合词典和混淆集,用于建议纠正(如“are”-> “am”)。

  3. 语音识别

    • 声学模型识别出多个可能的词序列候选。

    • 语言模型(通常是trigram或更高阶)用于评估哪个词序列在语言上更“合理”,对识别结果进行重排序。如“recognize speech” vs. “wreck a nice beach”。

  4. 机器翻译(早期统计机器翻译SMT)

    • SMT的核心组件之一(与翻译模型配合)。用于评估翻译输出的目标语言流畅度。

    • 生成的目标语言句子概率越高,通常意味着越流畅自然。

  5. 信息检索

    • 查询扩展:利用同文档/相关文档中的高频共现词(N-gram)扩展用户原始查询。

    • 文档排序:部分早期模型(如查询似然模型)将文档视为语言模型生成查询的概率源,N-gram是其基础。

    • 相关性反馈:根据相关文档中的显著N-gram调整查询。

  6. 文本分类与情感分析

    • 将N-gram(特别是unigram和bigram)作为强大的文本特征。

    • 分类器(如Naive Bayes, SVM)学习不同类别(如体育/财经/娱乐;正面/负面)下N-gram特征的分布差异。

    • 例如:“暴跌”、“涨停”、“市盈率”等bigram在财经类中概率高;“进球”、“射门”、“点球”在体育类中概率高。

  7. 生物信息学(DNA/蛋白质序列分析)

    • 将生物序列(A/T/C/G 或 氨基酸)视为“文本”。

    • N-gram模型用于识别保守序列模式、基因预测、序列比对等。

 

六、N-gram的局限性与现代NLP中的演变

6.1 固有局限性

  1. 数据稀疏性:核心挑战,催生了平滑技术,但问题无法根除。长尾N-gram难以准确建模。

  2. 上下文窗口有限(马尔可夫假设):只能捕捉局部依赖(N-1词),无法建模长距离依赖(如主谓一致跨越从句)。例如:“The keys to the cabinet are on the table” vs. “The key to the cabinets is...”。

  3. 缺乏语义理解:基于共现统计,无法真正理解词义、语义角色、逻辑关系。无法处理同义(“buy/purchase”)、反义(“hot/cold”)或隐喻。

  4. 维度灾难:N增大时,可能的N-gram组合数量呈指数级增长(O(V^N)),导致存储和统计需求爆炸。实践中N很少超过5。

  5. 领域依赖性:在特定领域语料上训练的N-gram模型,移植到其他领域效果会显著下降(词汇、表达方式不同)。

6.2 现代NLP中的传承与演变

尽管有局限,N-gram的思想并未消亡,而是以不同形式融入现代NLP:

  1. 神经语言模型的基础

    • Bengio在2003年提出的前馈神经网络语言模型是神经语言模型的先驱。它使用词嵌入表示词,并通过神经网络学习P(wi | wi-1, ..., wi-n+1)。它突破了离散表示和手工特征的局限,但仍基于固定窗口(N-gram)上下文。这直接启发了后来的RNN/LSTM/Transformer。

  2. 子词单元(Subword Units)

    • 现代模型(如BERT, GPT)普遍采用Byte Pair Encoding (BPE), WordPiece, Unigram LM等算法将词分割为更小的子词单元(如"un", "##able", "ization")。

    • 这些子词单元本身可以看作是一种动态的、数据驱动的“N-gram”或字符组合,有效缓解了OOV问题和数据稀疏性,同时允许模型学习词素级别的规律。

  3. Transformer中的局部注意力(有时)

    • 虽然Transformer的自注意力机制原则上可以捕获任意长距离依赖,但为了提高效率或引入归纳偏置,有时会使用受限(窗口)注意力。例如:

      • 局部窗口注意力:只关注当前位置前后固定窗口内的词(如邻居100个词),这本质上是在学习一种软化的、基于上下文的N-gram模型

      • 稀疏注意力模式(如Longformer, BigBird):包含局部窗口注意力作为其模式的一部分。

    • 这些设计表明,局部依赖关系(N-gram的核心)在语言中仍然至关重要,并且高效捕获它们仍然有价值

  4. 特征工程的基石

    • 在深度学习模型中,N-gram特征(尤其是unigram, bigram)仍然常被作为输入特征或与神经网络的输出拼接,为模型提供显式的、强局部信号。例如,在文本分类或简单序列标注任务中,N-gram特征结合神经网络能取得很好效果。

  5. 轻量级解决方案与基线

    • 在资源受限(如嵌入式设备、低延迟场景)或数据量不大的任务中,平滑良好的N-gram模型因其极高的效率、低计算开销和易于部署的特点,仍然是可行的选择

    • 它也是评估更复杂模型进步的重要基线。如果一个强大的神经模型在某个任务上无法显著超越精心调优的N-gram模型,可能意味着任务本身特性或模型设计存在问题。

结语:历久弥新的N-gram

N-gram模型,作为统计语言模型的典范,以其简洁、高效和强大的可解释性,在NLP发展史上写下了浓墨重彩的一笔。它教会我们:

  1. 概率是处理语言不确定性的有力工具

  2. 局部上下文蕴含巨大信息

  3. 数据驱动是解决复杂语言问题的有效途径

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/83357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML 中 class 属性介绍、用法

1、&#x1f516; 什么是 class class 是 HTML 元素的一个核心属性&#xff0c;用来为元素指定一个或多个类名。它在网页开发中承担三大作用&#xff1a; &#x1f3a8; 连接样式&#xff08;CSS&#xff09;&#xff1a;让元素应用预定义的视觉效果⚙️ 绑定行为&#xff08…

MybatisPlus(含自定义SQL、@RequiredArgsConstructor、静态工具类Db)

大家在日常开发中应该能发现&#xff0c;单表的CRUD功能代码重复度很高&#xff0c;也没有什么难度。而这部分代码量往往比较大&#xff0c;开发起来比较费时。 因此&#xff0c;目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…

信贷风控规则策略累计增益lift测算

在大数据风控业务实践过程中&#xff0c;目前业内主要还是采用规则叠加的办法做策略&#xff0c;但是会遇到一些问题&#xff1a; 1.我们有10条规则&#xff0c;我上了前7条后&#xff0c;后面3条的绝对风险增益是多少&#xff1f; 2.我的规则之间应该做排序吗&#xff0c;最重…

Python窗体编程技术详解

文章目录 1. Tkinter简介示例代码优势劣势 2. PyQt/PySide简介示例代码(PyQt5)优势劣势 3. wxPython简介示例代码优势劣势 4. Kivy简介示例代码优势劣势 5. PySimpleGUI简介示例代码优势劣势 技术对比总结选择建议 Python提供了多种实现图形用户界面(GUI)编程的技术&#xff0c…

Linux 操作系统安装及基本使用

Linux 操作系统安装及基本使用 在信息技术飞速发展的今天&#xff0c;Linux 操作系统凭借其开源、高性能、稳定性强等优势&#xff0c;在服务器、云计算、嵌入式等领域占据着重要地位。本文将详细介绍如何在 VMware 虚拟机下安装 Linux 系统&#xff08;以 CentOS 为例&#x…

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术 一、引言 在科学计算和数据分析中&#xff0c;函数与方程的可视化是理解数学关系和物理现象的重要工具。本文基于Python的Tkinter和Matplotlib库&#xff0c;实现一个功能完善的函数与方程可视化工具&#xff…

【MySQL基础】库的操作:创建、删除与管理数据库

MySQL学习&#xff1a; https://blog.csdn.net/2301_80220607/category_12971838.html?spm1001.2014.3001.5482 前言&#xff1a; 在上一篇我们已经讲解了数据库的基本内容&#xff0c;相信大家对数据库已经有了一些自己的理解&#xff0c;从这篇开始我们就开始正式进入如何…

Linux服务器系统配置初始化脚本

服务器系统配置初始化脚本 #!/bin/bash set -euo pipefail # 安全设置&#xff1a;遇错退出、未定义变量报错、管道错误处理# 设置时区并同步时间 timedatectl set-timezone Asia/Shanghai >/dev/null || ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime# 安装c…

Milvus单机模式安装和试用

1.安装ollama的package包&#xff1b; # install package pip install -U langchain-ollama2.我们直接使用ChatOllama实例化模型&#xff0c;并通过invoke进行调用&#xff1b; from langchain_ollama import ChatOllamallm ChatOllama(model"deepseek-r1") messa…

秒出PPT正式改名秒出AI,开启AI赋能新体验!

在现代办公环境中&#xff0c;借助智能工具提升工作效率已经成为趋势。秒出AI作为一款集AI PPT制作、动画、巨幕、视频、设计以及智能简历功能于一体的综合办公平台&#xff0c;为用户提供一站式智能内容生成解决方案&#xff0c;极大地简化了内容创作流程。 1. AI驱动的一键P…

Rust 学习笔记:发布一个 crate 到 crates.io

Rust 学习笔记&#xff1a;发布一个 crate 到 crates.io Rust 学习笔记&#xff1a;发布一个 crate 到 crates.io提供有用的文档注释常用标题文档注释作为测试注释所包含的项目 使用 pub use 导出一个方便的公共 API设置 crates.io 账户添加 metadata 到一个新的 crate发布到 c…

C++输入与输出技术详解

文章目录 引言一、C标准输入输出流1.1 cin与cout1.2 cerr与clog 二、C风格输入输出函数2.1 scanf与printf2.2 fgets与puts 三、输入输出优化四、总结 引言 在C编程中&#xff0c;输入与输出&#xff08;I/O&#xff09;操作是程序与用户、文件或其他系统组件交互的核心环节。C…

安全编码与AI接口权限控制

安全编码与AI接口权限控制 在AI系统中,模型服务的开放接口往往涉及敏感数据、核心算法与算力资源,如果缺乏有效的安全编码与权限控制机制,极易引发数据泄露、滥用调用或非法操作等问题。本节将从“接口安全策略”“权限验证流程”“Token管控机制”“多租户身份隔离”四个方…

redis五种数据结构详解(java实现对应的案例)

一、简述 Redis是一款高性能的键值对存储数据库&#xff0c;它支持五种基本数据类型&#xff0c;分别是字符串(String)、列表(List)、哈希(Hash)、集合(Set)、有序集合(Sorted Set)。 二、五种基本数据类型 2.1 字符串(String) String是Redis最基本的类型&#xff0c;一个key对…

大数据-273 Spark MLib - 基础介绍 机器学习算法 决策树 分类原则 分类原理 基尼系数 熵

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大模型篇章已经开始&#xff01; 目前已经更新到了第 22 篇&#xff1a;大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…

第十一章 Java基础-继承

文章目录 1.继承来源2.继承特点3.子类能继承父类中哪些内容1.继承来源 是为了解决代码的重复冗余。

Axure项目实战:驾驶舱(数据一张图)制作教程

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 视频展示(本文第三部分含所有echarts示例JS代码,可复制使用): Axure项目实战:驾驶舱(数据一张图…

针对Python开发的工具推荐及分析,涵盖集成开发环境(IDE)、轻量级工具、在线开发平台、代码管理工具等)

以下是针对Python开发的工具推荐及全面分析&#xff0c;涵盖集成开发环境&#xff08;IDE&#xff09;、轻量级工具、在线开发平台、代码管理工具等&#xff0c;结合不同场景和需求进行分类说明&#xff1a; 目录 一、集成开发环境&#xff08;IDE&#xff09; 1. PyCharm 2…

不使用绑定的方法

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 初始设置 A 控件的宽度 ControlA.Width ControlB.Width / 2; // 监听 B 控件的 SizeChanged 事件 ControlB.SizeChanged (sender, e) > { ControlA.Width ControlB.Actual…

DDR5 ECC详细原理介绍与基于协议讲解

本文篇幅较长,涉及背景原理介绍方便大家理解其运作方式 以及 基于DDR5协议具体展开介绍。 背景原理介绍 上图参考:DDR 内存中的 ECC 写入操作时,On-die ECC的工作过程如下: SoC将需要写入到Memory中的数据发送给控制器控制器将需要写入的数据直接发送给DRAM芯片在DDR5 DR…