--- title: 静态词向量:Word2Vec 与 GloVe 的数学体系 draft: false tags: - Word2Vec - GloVe - 词嵌入 - NLP - 静态表示 --- # 静态词向量:Word2Vec 与 GloVe 的数学体系 --- ## 一、从独热编码到分布式表示 ### 1.1 独热编码的问题 **独热编码(One-Hot Encoding)**: 设词表大小为 $|V|$,词 $w_i$ 的独热向量为: $$\mathbf{e}_i = [0, 0, \ldots, 1, \ldots, 0] \in \mathbb{R}^{|V|} \tag{1.1}$$ 其中第 $i$ 个位置为 1,其余为 0。 **问题**: 1. **维度灾难**:词表通常数万到数十万,维度过高 2. **语义鸿沟**:所有词的正交基表示无法捕捉语义相似性 3. **分布稀疏**:只有一个非零元素,计算效率低 **核心问题**:独热编码假设所有词都是独立的,丢失了词之间的语义关系。 ### 1.2 分布式表示的核心思想 **分布式表示(Distributed Representation)**: 每个词的语义不是由单一维度表示,而是**分布在多个维度上**。 **关键洞察**: > 语义相似的词应该具有相似的向量表示。 **数学表示**: 设词 $w$ 的嵌入向量为 $\mathbf{v}_w \in \mathbb{R}^d$,其中 $d \ll |V|$。 相似性度量: $$\text{sim}(w_i, w_j) = \frac{\mathbf{v}_{w_i}^\top \mathbf{v}_{w_j}}{\|\mathbf{v}_{w_i}\| \cdot \|\mathbf{v}_{w_j}\|} \tag{1.2}$$ 这是余弦相似度,取值在 $[-1, 1]$ 之间。 ### 1.3 分布假说 **分布假说(Distributional Hypothesis)**(Harris, 1954): > 出现在相似上下文中的词具有相似的语义。 **经典表述**: - "You shall know a word by the company it keeps"(Firth, 1957) **数学化**: 设 $c(w)$ 是词 $w$ 的上下文表示。如果两个词 $w_i$ 和 $w_j$ 的上下文分布 $P(c|w_i)$ 和 $P(c|w_j)$ 相似,则 $w_i$ 和 $w_j$ 的语义相似。 **这构成了所有词向量学习算法的理论基础**。 --- ## 二、Word2Vec:跳字模型与连续词袋 ### 2.1 语言模型基础 **语言模型**: 给定词序列 $w_1, w_2, \ldots, w_T$,语言模型学习联合概率分布: $$P(w_1, w_2, \ldots, w_T) = \prod_{t=1}^T P(w_t | w_1, \ldots, w_{t-1}) \tag{2.1}$$ **n-gram 模型**: 近似为: $$P(w_t | w_{t-1}, \ldots, w_{t-n+1}) \tag{2.2}$$ **问题**:n-gram 模型需要存储所有 n-gram 的频率,且无法处理长距离依赖。 ### 2.2 Skip-gram 模型 **核心思想**(Mikolov et al., 2013): > 使用中心词预测上下文词。如果两个词的上下文相似,它们的向量就相似。 **数学定义**: 设中心词为 $w_t$,上下文(窗口大小为 $c$)为: $$\text{context}(w_t) = \{w_{t-c}, \ldots, w_{t-1}, w_{t+1}, \ldots, w_{t+c}\} \tag{2.3}$$ Skip-gram 的目标是最大化: $$\mathcal{L} = \sum_{t=1}^T \sum_{-c \leq j \leq c, j \neq 0} \log P(w_{t+j} | w_t) \tag{2.4}$$ **条件概率定义**(softmax 形式): $$P(w_O | w_I) = \frac{\exp(\mathbf{v}_{w_O}^{\top (O)} \mathbf{v}_{w_I}^{(I)})}{\sum_{w=1}^{|V|} \exp(\mathbf{v}_w^{\top (O)} \mathbf{v}_{w_I}^{(I)})} \tag{2.5}$$ **Word2Vec 的双向量机制**:每个词 $w$ 有两个向量——输入向量 $\mathbf{v}_w^{(I)}$(用于作为中心词时)和输出向量 $\mathbf{v}_w^{(O)}$(用于作为上下文词时)。这在 Skip-gram 中尤为重要,因为中心词和上下文词的向量在公式中使用的是不同向量。 ### 2.3 Skip-gram 的概率推导 **问题**:标准 softmax 的分母需要遍历整个词表($|V| \approx 10^5$),计算代价极高。 **解决方案**:负采样(Negative Sampling) **负采样目标**: 对于每个正样本 $(w_I, w_O)$(中心词-上下文词对),采样 $k$ 个负样本 $\{w_{O_i^-}\}_{i=1}^k$。 **定义(负采样损失)**: $$\mathcal{L}_{\mathrm{SGNS}} = -\sum_{(w_I, w_O)} \left[ \log \sigma(\mathbf{v}_{w_O}^{\top (O)} \mathbf{v}_{w_I}^{(I)}) + \sum_{i=1}^k \mathbb{E}_{w_i^- \sim P_n} \log \sigma(-\mathbf{v}_{w_i^-}^{\top (O)} \mathbf{v}_{w_I}^{(I)}) \right] \tag{2.6}$$ 其中 $\sigma(x) = \frac{1}{1 + e^{-x}}$ 是 sigmoid 函数,$P_n$ 是负采样分布(通常为 unigram 分布的 3/4 次幂)。负采样分布设计为 $P_n(w) \propto f(w)^{3/4}$,其中 $f(w)$ 是词 $w$ 的频率。这个 3/4 次幂设计是为了**降低高频词的采样概率,同时适度提升低频词的采样机会**,比简单使用频率分布效果更好。 ### 2.4 连续词袋(CBOW)模型 **核心思想**: > 使用上下文预测中心词。与 Skip-gram 相反。 **数学定义**: $$\mathcal{L} = \sum_{t=1}^T \log P(w_t | w_{t-c}, \ldots, w_{t-1}, w_{t+1}, \ldots, w_{t+c}) \tag{2.8}$$ **条件概率**: $$P(w_O | \text{context}) = \frac{\exp(\bar{\mathbf{v}}^\top \mathbf{v}_{w_O})}{\sum_{w=1}^{|V|} \exp(\bar{\mathbf{v}}^\top \mathbf{v}_w)} \tag{2.9}$$ 其中 $\bar{\mathbf{v}}$ 是上下文的平均向量: $$\bar{\mathbf{v}} = \frac{1}{2c} \sum_{-c \leq j \leq c, j \neq 0} \mathbf{v}_{w_j} \tag{2.10}$$ ### 2.5 Skip-gram 与 CBOW 的对比 | 维度 | Skip-gram | CBOW | |------|---------|------| | **方向** | 中心词 $\rightarrow$ 上下文 | 上下文 $\rightarrow$ 中心词 | | **适合场景** | 稀有词/小数据集 | 常见词/大数据集 | | **训练速度** | 较慢(每个中心词对应多个样本) | 较快(每个位置只生成一个样本) | | **对低频词的处理** | 更好(每个词都是学习目标) | 较差(上下文平均会平滑掉稀有词的信号,这使得 CBOW 对低频词的学习效果不如 Skip-gram) | ### 2.6 训练目标详解 **Skip-gram 的完整目标函数**: $$\mathcal{J}(\theta) = \frac{1}{T} \sum_{t=1}^T \sum_{-c \leq j \leq c, j \neq 0} \log \frac{\exp(\mathbf{v}_{w_{t+j}}^{\top (O)} \mathbf{v}_{w_t}^{(I)})}{\sum_{w=1}^{|V|} \exp(\mathbf{v}_w^{\top (O)} \mathbf{v}_{w_t}^{(I)})} \tag{2.11}$$ **使用负采样近似后**: 对于每个训练对 $(w_t, w_{t+j})$: 1. 计算正样本分数:$\mathbf{v}_{w_{t+j}}^{\top (O)} \mathbf{v}_{w_t}^{(I)}$ 2. 采样 $k$ 个负样本 $w_i^-$ 3. 最小化损失: $$\log \sigma(\mathbf{v}_{w_{t+j}}^{\top (O)} \mathbf{v}_{w_t}^{(I)}) + \sum_{i=1}^k \log \sigma(-\mathbf{v}_{w_i^-}^{\top (O)} \mathbf{v}_{w_t}^{(I)}) \tag{2.12}$$ ### 2.7 Word2Vec 的层级 Softmax **层级 Softmax**(另一加速方案): 将词表组织为霍夫曼树(最优二叉树),叶节点是词。霍夫曼树的构建规则:根据词频($f_w$)创建,叶节点的路径长度与词频成反比——高频词路径短,低频词路径长。到达每个词的路径长度约为 $O(\log |V|)$。 **定义(层级 Softmax 概率)**: 词 $w$ 的概率等于从根节点到叶节点路径上每个节点的 sigmoid 决策概率的乘积。每次决策使用一个辅助向量 $\mathbf{v}_n$。路径长度约为 $O(\log |V|)$,因此复杂度从 $O(|V|)$ 降到 $O(\log |V|)$。 --- ## 三、GloVe:全局共现统计 ### 3.1 GloVe 的核心思想 **GloVe**(Pennington et al., 2014)的全称是 **Global Vectors for Word Representation**。 **核心洞察**: > 将词向量的学习建立在**全局共现矩阵**上,而不是像 Word2Vec 那样只依赖局部上下文。 **数学定义**: 设 $X \in \mathbb{R}^{|V| \times |V|}$ 是**共现矩阵**,其中 $X_{ij}$ 表示词 $i$ 和词 $j$ 在语料库中共同出现的次数。 **目标**: 学习词向量 $\mathbf{v}_i, \mathbf{\hat{v}}_j$,使得: $$\mathbf{v}_i^\top \mathbf{\hat{v}}_j \approx \log(X_{ij}) \tag{3.1}$$ ### 3.2 共现矩阵的构建 **定义(窗口共现)**: 给定窗口大小 $c$,对于语料库中的每个位置 $t$,更新: $$X_{w_t, w_{t+j}} += \frac{1}{|j|} \quad \text{for } j \in \{-c, \ldots, -1, 1, \ldots, c\} \tag{3.2}$$ **距离衰减加权**: 远处的词贡献较小的权重: $$\text{weight}(j) = \frac{1}{|j|} \tag{3.3}$$ **定义(全局共现向量)**: $$X_i = \sum_{j} X_{ij} \tag{3.4}$$ 这是词 $i$ 与所有其他词的共现总和。 ### 3.3 GloVe 的损失函数 **初步损失函数**: $$\mathcal{L} = \sum_{i,j} f(X_{ij}) \left( \mathbf{v}_i^\top \mathbf{\hat{v}}_j + b_i + \hat{b}_j - \log X_{ij} \right)^2 \tag{3.5}$$ 其中 $b_i, \hat{b}_j$ 是偏置项。 **设计 $f(X_{ij})$ 的动机**: 1. **停止过度学习高频词**:当 $X_{ij}$ 很大时,不应该让这个共现主导损失 2. **处理零共现**:$X_{ij} = 0$ 时,$\log X_{ij}$ 是 $-\infty$,但这不应该有无限大的损失 **定义(断点加权函数)**: $$f(x) = \begin{cases} (x / x_{\max})^\alpha & \text{if } x < x_{\max} \\ 1 & \text{otherwise} \end{cases} \tag{3.6}$$ 推荐配置:$x_{\max} = 100$,$\alpha = 3/4$。 **这个函数确保**: - 对于罕见的共现($x$ 很小),$f(x)$ 接近 0,但不为 0 - 对于常见的共现,$f(x) = 1$(截断饱和) - 中等频率的共现有适当的权重 ### 3.4 GloVe 与 Word2Vec 的对比 | 维度 | Word2Vec | GloVe | |------|---------|-------| | **训练数据** | 局部窗口 | 全局共现矩阵 | | **计算复杂度** | $O(T \cdot c \cdot k)$ | $O(|V|^2)$(矩阵分解) | | **目标函数** | 条件对数似然 | 最小二乘回归(对数共现) | | **表示** | 两个矩阵(输入/输出向量) | 通常使用 $\mathbf{v}_i$ 与 $\mathbf{\hat{v}}_j$ 的融合向量 $\frac{\mathbf{v}_i + \mathbf{\hat{v}}_j}{2}$ | **GloVe 双向对称性**:共现矩阵 $X$ 是对称的,即 $X_{ij} = X_{ji}$。这意味着词 $i$ 对词 $j$ 的共现次数与词 $j$ 对词 $i$ 的共现次数相同。在训练完成后,通常使用 $(\mathbf{v}_i + \mathbf{\hat{v}}_j)/2$ 进行推理,以利用双向信息。 | **稀疏性处理** | 负采样隐式处理 | 需要特殊处理零共现 | ### 3.5 GloVe 的数学推导 **从矩阵分解角度**: 共现矩阵 $X$ 的对数形式可以分解为: $$\log X \approx U \Sigma V^\top \tag{3.7}$$ 取前 $d$ 个奇异值: $$\log X \approx U_d \Sigma_d V_d^\top \tag{3.8}$$ **这等价于**: 令 $\mathbf{v}_i = U_d(i,:) \sqrt{\Sigma_d}$,$\mathbf{\hat{v}}_j = V_d(j,:)^\top \sqrt{\Sigma_d}$,则: $$\mathbf{v}_i^\top \mathbf{\hat{v}}_j \approx (\log X)_{ij} \tag{3.9}$$ **GloVe 的创新**:不直接做 SVD(计算量 $O(|V|^3)$),而是使用 SGD 直接优化。 ### 3.6 共现概率与语义相似性 **定义(共现比率)**: $$P_{ij} = \frac{X_{ik}}{X_jk} = \frac{P(k|i)}{P(k|j)} \quad \text{for any } k \tag{3.10}$$ **语义解释**: - 当 $P_{ij} \gg 1$ 时,词 $i$ 比词 $j$ 更常与 $k$ 共现 - 当 $P_{ij} \ll 1$ 时,情况相反 - 当 $P_{ij} \approx 1$ 时,$i$ 和 $j$ 与 $k$ 的共现关系相似 **GloVe 捕捉这个比率**: 通过学习使得: $$\mathbf{v}_i^\top \mathbf{\hat{v}}_j + b_i + \hat{b}_j \approx \log X_{ij} \tag{3.11}$$ 可以验证这等价于: $$\mathbf{v}_i^\top \mathbf{\hat{v}}_j \approx \log \frac{X_{ik}}{X_{jk}} \quad \text{(for appropriate } k) \tag{3.12}$$ --- ## 四、训练过程与实现细节 ### 4.1 Word2Vec 的训练流程 **Algorithm: Word2Vec (Skip-gram with Negative Sampling)** **输入**:语料库 $C$,嵌入维度 $d$,窗口大小 $c$,负样本数 $k$,学习率 $\eta$ **初始化**: 1. 随机初始化所有词的输入向量 $\mathbf{v}_w \sim \mathcal{N}(0, 0.1)$ 2. 初始化输出向量(或共享输入向量,取决于架构) **训练**: ``` for each epoch: for each sentence (w_1, ..., w_T) in C: for each position t = 1 to T: # 中心词 w_I = w_t # 正样本 for each j in [-c, c], j != 0: w_O = w_{t+j} # 负采样 for i = 1 to k: w_i^- ~ P_n(w) # unigram^3/4 # 更新向量 g = eta * (sigma(v_O^T v_I) - 1) * v_O # 正样本梯度 g_i = eta * sigma(-v_i^-^T v_I) * v_i^- # 负样本梯度 v_I = v_I - g - sum(g_i) v_O = v_O - g v_i^- = v_i^- - g_i ``` ### 4.2 GloVe 的训练流程 **Algorithm: GloVe Training** **输入**:语料库 $C$,嵌入维度 $d$,窗口大小 $c$,学习率 $\eta$ **步骤 1:构建共现矩阵** ``` X = zeros(|V|, |V|) for each sentence in C: for each position t: for each offset j in [-c, c], j != 0: X[w_t, w_{t+j}] += 1 / |j| ``` **步骤 2:最小二乘优化** ``` # 随机初始化 v_i, hat_v_j ~ N(0, 0.1) b_i, hat_b_j ~ zeros for each epoch: # 采样非零元素 (i, j) = sample_from_X() # 计算预测误差 pred = v_i^T hat_v_j + b_i + hat_b_j - log(X[i,j]) # 加权梯度 weight = f(X[i,j]) grad = weight * pred # 更新 v_i -= eta * grad * hat_v_j hat_v_j -= eta * grad * v_i b_i -= eta * weight * pred hat_b_j -= eta * weight * pred ``` ### 4.3 训练中的常见问题 **问题 1:高频词主导** - **表现**:如 "the", "a", "is" 等词占据了绝大多数共现 - **影响**:学到的向量被这些高频词主导 **GloVe 解决方案**:断点加权函数 $f(X_{ij})$(式 3.6) **Word2Vec 解决方案**:对高频词进行下采样,以概率 $P(w) = 1 - \sqrt{t / f_w}$ 跳过,其中 $f_w$ 是词 $w$ 的频率,$t$ 是频率阈值(通常为 $10^{-5}$)。这个公式确保高频词被更频繁地跳过,但不会被完全排除。 **问题 2:罕见词表示差** - **表现**:低频词的向量没有被充分训练 **解决方案**: 1. 增加罕见词的采样概率 2. 使用上下文加权 **问题 3:训练不收敛** - **表现**:损失不下降或 NaN **解决方案**: 1. 降低学习率 2. 梯度裁剪 3. 使用 Adagrad/Adam 等自适应学习率优化器 ### 4.4 超参数影响 | 超参数 | 典型值 | 影响 | |--------|--------|------| | **嵌入维度 $d$** | 50-300 | 维度越高表达能力越强,但也容易过拟合 | | **窗口大小 $c$** | 5-15 | 越大考虑更多上下文,但也引入更多噪声 | | **负样本数 $k$** | 5-20 | Skip-gram 常用 5-15 | | **最小词频** | 5-50 | 过滤掉极低频词 | | **学习率** | 0.001-0.05 | 过高会导致不收敛 | --- ## 五、词向量的评估与应用 ### 5.1 评估任务 **词相似度评估**: 常用数据集:WordSim-353, SimLex-999, MEN, TRUKES **定义(相似度指标)**: 给定人工标注的相似度分数 $s_{ij}$ 和模型预测的余弦相似度 $\hat{s}_{ij}$: **Spearman 相关系数**: $$\rho = 1 - \frac{6 \sum d_i^2}{n(n^2-1)} \tag{5.1}$$ 其中 $d_i$ 是两个排序的差异。 ### 5.2 类比任务(Analogy) **词类比任务**(Mikolov et al., 2013): > "man is to king as woman is to ?" **数学定义**: $$\text{queen} = \arg\max_{w} \cos(\mathbf{v}_w, \mathbf{v}_{king} - \mathbf{v}_{man} + \mathbf{v}_{woman}) \tag{5.2}$$ **评估指标**: $$\text{Accuracy} = \frac{\# \text{正确预测的类比}}{\# \text{总类比}} \tag{5.3}$$ ### 5.3 向量空间的几何性质 **性质 1:语义可加性**: $$\mathbf{v}_{\text{巴黎}} + \mathbf{v}_{\text{德国}} - \mathbf{v}_{\text{法国}} \approx \mathbf{v}_{\text{柏林}} \tag{5.4}$$ 这解释了为什么 Skip-gram 学到的向量具有"语义可加性"。 **性质 2:聚类结构**: 相似语义的词在向量空间中聚集形成簇。 **性质 3:性别/时态等二维子空间**: $$\mathbf{v}_{\text{男人}} - \mathbf{v}_{\text{女人}} \approx \mathbf{v}_{\text{国王}} - \mathbf{v}_{\text{女王}} \tag{5.5}$$ 这表明某些语义维度(如性别)在线性方向上有规律。 ### 5.4 预训练词向量的使用 **加载预训练向量**: ```python # 使用 GloVe embeddings = {} with open('glove.6B.300d.txt') as f: for line in f: values = line.split() word = values[0] vector = np.asarray(values[1:], dtype='float32') embeddings[word] = vector ``` **处理 OOV**: ```python def get_embedding(word, embeddings, dim): if word in embeddings: return embeddings[word] else: return np.random.randn(dim) * 0.01 # 随机初始化 ``` --- ## 六、静态词向量与上下文化表示的对比 ### 6.1 静态词向量的局限 **核心问题**: 同一个词在不同的上下文中,静态词向量是**相同的**。 **反例**: - "bank"(河岸)vs "bank"(银行):应该有不同的表示 - "run"(动词跑步)vs "run"(名词溪流):应该有不同的表示 **数学表示**: 对于同一词 $w$ 在不同上下文 $c_1$ 和 $c_2$ 中,静态词向量满足 $\mathbf{v}_w^{(c_1)} = \mathbf{v}_w^{(c_2)} = \mathbf{v}_w$。这忽略了语义的可变性。 ### 6.2 解决方案 **方案 1:多义词向量**(不常用) 让一个词对应多个向量,但这增加了模型复杂度。 **方案 2:上下文化表示**(ELMo、BERT) 每个词的表示依赖于其上下文: $$\mathbf{v}_{w,t}^{\text{ctx}} = f(\text{上下文}) \tag{6.2}$$ 这是下一份笔记的主题。 --- ## 七、数学公式速查 ### 7.1 Word2Vec 公式 **Skip-gram 条件概率**: $$P(w_O | w_I) = \frac{\exp(\mathbf{v}_{w_O}^{\top (O)} \mathbf{v}_{w_I}^{(I)})}{\sum_{w=1}^{|V|} \exp(\mathbf{v}_w^{\top (O)} \mathbf{v}_{w_I}^{(I)})} \tag{7.1}$$ **负采样损失**: $$\mathcal{L} = -\sum_{(w_I, w_O)} \left[ \log \sigma(\mathbf{v}_{w_O}^{\top (O)} \mathbf{v}_{w_I}^{(I)}) + \sum_{i=1}^k \mathbb{E}_{w_i^- \sim P_n} \log \sigma(-\mathbf{v}_{w_i^-}^{\top (O)} \mathbf{v}_{w_I}^{(I)}) \right] \tag{7.2}$$ ### 7.2 GloVe 公式 **共现矩阵**: $$X_{ij} = \sum_{t} \frac{1}{|j|} \cdot \mathbf{1}_{|w_t - w_{t+j}| = |j|} \tag{7.3}$$ **加权损失函数**: $$\mathcal{L} = \sum_{i,j} f(X_{ij}) \left( \mathbf{v}_i^\top \mathbf{\hat{v}}_j + b_i + \hat{b}_j - \log X_{ij} \right)^2 \tag{7.4}$$ **断点加权函数**: $$f(x) = \begin{cases} (x / x_{\max})^{3/4} & \text{if } x < x_{\max} \\ 1 & \text{otherwise} \end{cases} \tag{7.5}$$ ### 7.3 相似度度量 **余弦相似度**: $$\text{sim}(\mathbf{v}_i, \mathbf{v}_j) = \frac{\mathbf{v}_i^\top \mathbf{v}_j}{|\mathbf{v}_i| |\mathbf{v}_j|} \tag{7.6}$$ **Spearman 相关系数**: $$\rho = 1 - \frac{6 \sum d_i^2}{n(n^2-1)} \tag{7.7}$$ --- ## 八、总结 **Word2Vec 与 GloVe 的核心差异**: | 方面 | Word2Vec | GloVe | |------|---------|-------| | **理论基础** | 局部上下文预测 | 全局共现统计 | | **优化目标** | 条件对数似然 | 加权最小二乘回归 | | **训练方式** | 随机采样 + SGD | 矩阵预计算 + SGD | | **表示能力** | 相似词有相似向量 | 相似词有相似向量 | **共同点**: 1. 都产生**静态词向量**——同一个词在不同上下文中表示相同 2. 都利用了**分布假说**——相似的词有相似的上下文 3. 都产生**线性子空间**——词义关系可以在向量加减中体现 **局限性**: 1. 无法处理一词多义 2. 无法捕捉长距离依赖 3. 静态表示无法适应特定任务 **这是下一份笔记(ELMo 和 BERT)的动机**。 --- **延伸阅读**: 1. Mikolov et al., "Efficient Estimation of Word Representations in Vector Space" (2013) — Word2Vec 2. Mikolov et al., "Distributed Representations of Words and Phrases and their Compositionality" (2013) — Skip-gram 3. Pennington et al., "GloVe: Global Vectors for Word Representation" (EMNLP 2014) 4. Levy & Goldberg, "Neural Word Embedding as Implicit Matrix Factorization" (NIPS 2014) — 解释了 Word2Vec 与矩阵分解的联系 5. Rong, "word2vec Parameter Learning Explained" (2016) — 详细的梯度推导