word2vec基于负采样的模型原理介绍

word2vec是由Google在2013年开源的一款用于获取词向量的工具包,本文通过解读其源代码揭示了word2vec背后的算法原理,包括Hierarchical Softmax与Negative Sampling两种模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    word2vec 是 Google 于 2013 年开源推出的一个用于获取 word vector 的工具包,它简单、高效,因此引起了很多人的关注。由于 word2vec 的作者 Tomas Mikolov 在两篇相关的论文 [3,4] 中并没有谈及太多算法细节,因而在一定程度上增加了这个工具包的神秘感。一些按捺不住的人于是选择了通过解剖源代码的方式来一窥究竟,出于好奇,我也成为了他们中的一员。读完代码后,觉得收获颇多,整理成文,给有需要的朋友参考。


相关链接


(一)目录和前言

(二)预备知识

(三)背景知识

(四)基于 Hierarchical Softmax 的模型

(五)基于 Negative Sampling 的模型

(六)若干源码细节





作者: peghoty 

转载出处: http://blog.youkuaiyun.com/itplus/article/details/37998797

### Word2vec负采样原理详解 Word2vec是一种高效的词嵌入技术,能够将词语映射到连续的向量空间中,从而捕捉语义关系。然而,在训练过程中,传统的Softmax方法会面临计算复杂度高的问题,尤其是在大规模数据集上。为了提高效率并降低计算成本,引入了负采样(Negative Sampling)这一优化策略。 #### 负采样的基本概念 负采样是一种近似目标函数的技术,旨在减少每次更新参数所需的计算量。它通过仅考虑一小部分负样本而非整个词汇表中的所有单词来简化损失函数的计算[^2]。具体来说,对于给定的目标词及其上下文词对,负采样会选择若干个不相关的词作为“负样本”,并将这些负样本与实际存在的正样本一起参与梯度下降的学习过程。 #### 数学表达式 假设当前正在处理一对 (target, context),即目标词 \( w_t \) 和其对应的上下文词 \( w_c \)。定义事件发生的概率为: \[ P(D=1|w_t,w_c)=σ(\text{score}(w_t,w_c)) \] 其中,\( σ(x) = \frac{1}{1+\exp(-x)} \) 是sigmoid激活函数;而得分函数通常表示为目标词和上下文词之间点积的结果加上偏置项: \[ \text{score}(w_t,w_c) = v_{w_t}^\top u_{w_c} \] 在这里,\( v_{w_t} \) 表示目标词的输入向量,\( u_{w_c} \) 则是上下文词的输出向量。 对于每个正样本 (\( D=1 \)) 及选定数量 k 的负样本 (\( D=0 \)) ,最终的损失函数可写成如下形式: \[ -\log σ(v_{w_t}^\top u_{w_c}) - \sum_{i=1}^{k}\log σ(-v_{n_i}^\top u_{w_c}) \] 此处 \( n_1,...,n_k \) 代表从噪声分布抽取出来的 k 个负样本索引[^3]。 #### 如何选取负样本? 在实践中,负样本的选择遵循特定的概率分布而不是均匀随机抽选。Mikolov等人建议采用一种基于词频调整后的非均匀分布来进行负采样操作。这种分布倾向于更频繁地挑选高频词汇作为潜在的干扰因素,同时保留一定比例低频词汇的可能性。具体而言,该分布被设计成满足以下条件的比例关系: \[ P(w)\propto f(w)^{\alpha}, \quad \alpha≈0.75 \] 这意味着越常见的单词有更高的几率成为候选负面实例之一,但同时也给予不太常见却可能重要的术语适当的关注程度。 #### 实现细节 当应用Keras框架构建带有负采样Word2Vec模型时,可以通过自定义层或者利用现有库支持的功能轻松实现上述机制。例如,可以创建一个专门负责生成负样本列表的小型辅助模块,并将其集成至主网络结构之中。以下是简单的伪代码展示如何模拟此流程的一部分: ```python import numpy as np from keras.layers import Input, Embedding, Reshape, Dot, Dense from keras.models import Model def generate_negatives(context_word_indices, vocab_size, num_negative_samples): negative_sample_probs = get_unigram_distribution(vocab_size)**0.75 / sum(get_unigram_distribution(vocab_size)**0.75) negatives = [] for cwi in context_word_indices: negs = np.random.choice(len(negative_sample_probs), size=num_negative_samples, replace=False, p=negative_sample_probs) negatives.append(negs) return negatives # 构建模型... ``` 以上片段展示了如何依据预设好的unigram distribution来获取指定数目下的负样本集合。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值