语言模型用于预测单词序列的概率并生成连贯的文本。这些模型被广泛应用于各种场景,包括聊天机器人、翻译器等。然而,构建语言模型的一个主要挑战在于,如何处理训练数据中未见事件导致的零概率问题。平滑技术应运而生,正是为了解决这一问题,确保模型在遇到前所未见的单词时依然能做出准确的预测。
在本文中,我们将重点探讨两种高级平滑技术:Witten-Bell 平滑和 Jelinek-Mercer 平滑。
理解语言模型
大语言模型旨在理解和生成类人文本。它们通过计算单词序列的概率来预测句子中的下一个词。这些模型通常在海量文本语料库上进行训练,从而掌握语言的模式和结构。
像 AI 应用中使用的那些大语言模型,通常采用深度学习架构,如循环神经网络 (RNNs) 和 Transformers。这些模型能够捕捉长距离依赖关系和复杂的语言模式,使其在广泛的自然语言处理(NLP)任务中非常有效。
> 前置知识: 语言模型中的加性平滑技术
平滑技术在大语言模型中至关重要,用于解决未见单词的零概率问题。这些技术通过调整概率分布,确保即使是未见事件也具有非零概率。通过这种方式,它们显著提升了大语言模型的性能。
1. Witten-Bell 平滑
Witten-Bell 平滑是一种用于统计语言建模的技术,旨在估计未见事件的概率,特别是在自然语言处理(NLP)中的 n-gram 语境下。该方法由 Ian H. Witten 和 Timothy C. Bell 于 1991 年提出,是他们在数据压缩研究工作的一部分。
#### Witten-Bell 平滑是如何工作的?
- Witten-Bell 平滑基于在最大似然估计(MLE)和回退估计之间进行插值的思想。它假设遇到未见事件的概率与目前观察到的唯一事件的数量成正比。
- 未见事件的概率是使用训练数据中观察到的唯一 n-gram 的计数来估计的。其核心思想是:如果某个特定语境已经产生了许多不同的 n-gram,那么它也很可能会产生新的、未见过的 n-gram。
- n-gram 的平滑概率计算公式如下:P(wn | w{n-1}, \dots, w1) = \frac{C(w1, \dots, wn)}{C(w1, \dots, w{n-1}) + N(w1, \dots, w_{n-1})}
- 在这里:
- C(w1, \dots, wn) 是 n-gram (w1, \dots, wn) 的计数。
- C(w1, \dots, w{n-1}) 是 (n-1)-gram 前缀的计数。
- N(w1, \dots, w{n-1}) 是紧跟在 (n-1)-gram 前缀后的唯一单词的数量。
Witten-Bell 平滑在处理稀疏数据方面特别有效,这在 NLP 任务中很常见。它通过同时考虑数据中出现的频率和可能延续的多样性来平滑概率分布。
现在,让我们通过以下步骤来实现这一技术:
- 导入所需函数:从 INLINECODEdea41d0c 模块导入 INLINECODE4a83f8b5 函数。
- 定义类:创建一个名为
WittenBellSmoothing的类,它包括: - 将 INLINECODE977e9d42(一元语法)和 INLINECODEcc878b57(二元语法)初始化为默认字典。
- 设置一个计数器变量用于统计一元语法的总数。
- 模型训练:使用示例文本语料库训练模型:
- 将每个句子拆分为标记(tokens)。
- 根据这些标记更新一元语法和二元语法的计数。
- 定义概率计算函数:在类中实现一个名为
bigram_prob的函数,使用 Witten-Bell 平滑技术计算二元语法的概率。 - 创建并使用类对象:
- 定义一个示例文本语料库。
- 创建
WittenBellSmoothing类的一个对象。 - 调用
bigram_prob函数来计算二元语法 ‘the cat’ 的概率。
Python
“
from collections import defaultdict
class WittenBellSmoothing:
def init(self, corpus):
self.unigrams = defaultdict(int)
self.bigrams = defaultdict(int)
self.total_unigrams = 0
self.train(corpus)
def train(self, corpus):
for sentence in corpus:
tokens = sentence.split()
for i in range(len(tokens)):
self.unigrams[tokens[i]] += 1
self.total_unigrams += 1
if i > 0:
self.bigrams[(tokens[i