深入解析CBOW模型手算词嵌入步骤:从数学原理到Python实现

1次阅读
没有评论

共计 1799 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

词嵌入作为 NLP 领域的基石技术,能够将离散的词语转化为连续的向量表示,从而捕捉词语间的语义和语法关系。其中 CBOW(Continuous Bag-of-Words)模型因其简单高效的特点,成为词嵌入学习的经典方法。本文将带大家从数学原理到 Python 实现,逐步拆解 CBOW 模型的手算过程。

深入解析 CBOW 模型手算词嵌入步骤:从数学原理到 Python 实现

1. CBOW 模型数学原理

CBOW 模型的核心思想是通过上下文词语预测当前词语。假设我们有一个大小为 $2m$ 的上下文窗口(即左右各 $m$ 个词),模型结构主要分为三层:

  1. 输入层 :将上下文词语的 one-hot 表示 ${x_1, x_2, …, x_C}$($C=2m$)作为输入,每个 $x_i$ 是维度为 $V$ 的向量($V$ 为词汇表大小)

  2. 隐藏层

  3. 通过嵌入矩阵 $W_{V\times N}$($N$ 为嵌入维度)计算平均上下文向量:
    $$h = \frac{1}{C} \sum_{i=1}^C W^T x_i$$
  4. 这里 $h$ 就是我们要学习的词向量表示

  5. 输出层

  6. 使用另一个矩阵 $W’_{N\times V}$ 计算得分:
    $$u = W’^T h$$
  7. 通过 softmax 得到预测概率分布:
    $$y_j = \frac{\exp(u_j)}{\sum_{k=1}^V \exp(u_k)}$$

2. Python 手写实现

下面我们用 NumPy 逐步实现 CBOW 模型的核心计算过程:

import numpy as np

# 参数设置
V = 10000  # 词汇表大小
N = 300    # 嵌入维度
m = 2      # 上下文窗口半宽

# 初始化权重矩阵
W = np.random.rand(V, N) * 0.1  # 输入到隐藏层
W_prime = np.random.rand(N, V) * 0.1  # 隐藏到输出层

# 模拟输入:3 个上下文词的 one-hot
context_words = [256, 512, 1024]  # 词索引
x = np.zeros((len(context_words), V))
for i, idx in enumerate(context_words):
    x[i, idx] = 1

# 前向传播
# 1. 输入层→隐藏层
h = np.mean([W.T.dot(x_i) for x_i in x], axis=0)

# 2. 隐藏层→输出层
u = W_prime.T.dot(h)

y = np.exp(u) / np.sum(np.exp(u))  # softmax

# 梯度检查(示例)target_word = 2048  # 目标词索引
target = np.zeros(V)
target[target_word] = 1

error = y - target
assert error.shape == (V,), "梯度维度不匹配"

3. CBOW vs Skip-gram

虽然两者都是 Word2Vec 的变体,但存在关键差异:

  1. 计算顺序相反
  2. CBOW 用上下文预测中心词
  3. Skip-gram 用中心词预测上下文

  4. 计算复杂度

  5. CBOW 适合高频词(因上下文平均降低了方差)
  6. Skip-gram 适合低频词(每个上下文词单独处理)

  7. 数学表达差异

  8. Skip-gram 的损失函数是多个 softmax 的乘积
  9. CBOW 是单个 softmax 输出

4. 工程实践要点

上下文窗口选择

  • 通用场景:$m=2\sim5$
  • 专业领域:可增大到 $m=10$
  • 动态窗口:随训练轮次线性增加

高频词降采样

对词 $w_i$ 的采样概率:

$$P(w_i) = 1 – \sqrt{\frac{t}{f(w_i)}}$$

其中 $t$ 是阈值(通常 $10^{-5}$)

负采样加速

用以下概率分布采样负例:

$$P_n(w_i) = \frac{f(w_i)^{3/4}}{\sum_{j=1}^V f(w_j)^{3/4}}$$

实现示例:

def negative_sampling(probs, k=5):
    return np.random.choice(len(probs), 
        size=k, 
        p=probs,
        replace=False
    )

5. 常见问题与优化

  1. 稀疏矩阵问题
  2. 使用稀疏矩阵格式存储 one-hot
  3. 仅计算非零索引的嵌入向量

  4. 学习率调整

  5. 初始值通常 0.025
  6. 线性衰减到 0.001

  7. 可视化技巧

  8. 先 TSNE 降维到 2D
  9. 对同类词用相同颜色标记

6. 局限性与思考

尽管 CBOW 简单高效,但仍存在明显局限:

  1. 生僻词处理 :低频词因样本不足导致嵌入质量差
  2. 上下文对称性 :无法区分左右位置信息
  3. 与 BERT 对比
  4. CBOW 是浅层双向模型
  5. BERT 通过 Transformer 捕获深层上下文

最后留给大家思考:在预训练时代,传统词嵌入方法是否还有不可替代的价值?欢迎在评论区分享你的见解。

正文完
 0
评论(没有评论)