Word2Vec
Word2Vec 是一种将词语(Word)映射为连续向量(Vector)的高效建模技术,由 Google 的 Tomas Mikolov 团队于 2013 年提出[1][2]。通过在大规模文本语料中自动学习,Word2Vec 将每个词表示为一个低维、稠密、连续的向量(Embedding),这种向量能够捕捉词语之间的语义和句法关系。与传统将词视为离散 ID 的方法(如 N-gram)不同,Word2Vec 将词嵌入到连续空间中,相似意义的词在向量空间中距离更近,为后续复杂模型(如 Transformer)奠定了基础。
Word2Vec 的底层是一个浅层神经网络,采用 Skip-gram 或 Continuous Bag-of-Words(CBOW)两种架构进行训练。训练后得到的词向量(Word Embedding)被广泛应用于自然语言处理(NLP)任务中,包括机器翻译(Machine Translation)、信息检索(Information Retrieval)、文本分类(Text Classification)和情感分析(Sentiment Analysis)等,成为当前 NLP 领域的重要基础方法之一。
历史背景
20 世纪 80 年代,人们开始尝试使用神经网络将单词和概念表示为向量[3][4]。2010 年,Tomáš Mikolov(当时就读于布尔诺理工大学)与合著者一起将单隐层的简单递归神经网络应用于语言建模[5]。Word2vec 由 Tomas Mikolov 及其团队于 2013 年在 Google Research 提出。Tomas Mikolov 在布尔诺理工大学(Brno University of Technology)完成了神经网络语言建模的博士研究后,加入 Google后,与 Kai Chen、Greg Corrado 和 Jeffrey Dean 等人合作,致力于大规模数据下的词表示学习问题。面对传统方法在大规模语料处理上的局限,Mikolov 团队提出了两种简洁高效的浅层神经网络架构,即 Continuous Bag-of-Words(CBOW)和 Skip-gram,统称为 Word2Vec。Word2Vec 实现了在数十亿词级别的数据上快速训练高质量词向量的目标,一经发布便在NLP领域引起了广泛关注和应用。
使用 Word2vec 算法创建的嵌入向量与早期的算法(如使用 n-grams 和潜在语义分析的算法)相比具有一些优势。GloVe 是斯坦福大学的一个团队专门作为竞争对手开发的,原始论文指出 GloVe 比 word2vec 有多处改进。Mikolov 认为,这种比较是不公平的,因为 GloVe 是在更多数据上训练出来的,而 fastText 项目表明,在相同数据上训练出来的 word2vec 更胜一筹。不过截至到现在,直接的 Word2vec 方法被认为是 "过时的"。基于transformer的模型,如 ELMo 和 BERT,在类似 Word2vec 的词嵌入模型之上添加了多个神经网络关注层,已被视为 NLP 领域的最新技术。
技术原理
Word2vec 的目的在于为每个词汇都分配一个稠密的向量,能够做到相比传统的稀疏向量(如 one-hot 编码),更具表达能力和计算效率。形式上也就是,如果词汇表为 [math]\displaystyle{ V }[/math],每个词 [math]\displaystyle{ w \in V }[/math] 被映射为向量 [math]\displaystyle{ \mathbf{v}_w \in \mathbb{R}^d }[/math],其中 [math]\displaystyle{ d \ll |V| }[/math]。
Word2vec使用两种模型架构中的任何一种来生成词汇的分布式表示:连续词袋模型(CBOW)或Skip-gram。在这两种架构中,word2vec 在遍历语料库时都会考虑单个词和滑动上下文窗口,这种设计来源于分布式假设,由语言学家 Zellig Harris 在1954年提出。它的核心思想是:“上下文相似的词具有相似的意义”(You shall know a word by the company it keeps)。即如果两个词在相似的上下文中出现,那么它们的意义可能也相似。
CBOW 可被视为一项 "填空 "任务,其中词汇嵌入代表了词汇影响上下文窗口中其他词汇相对概率的方式。语义相似的词应该以相似的方式影响这些概率,因为语义相似的词应该在相似的语境中使用。上下文词语的顺序不会影响预测(词袋假设)。
Skip-gram与CBOW相反,模型使用当前词来预测周围的语境词窗口。与较远的上下文词相比,Skip-gram更重视附近的上下文词。
模型训练完成后,学习到的词向量会被放置在向量空间中,这样,在语料库中具有共同语境的词(即语义和句法上相似的词)就会在空间中彼此靠近。相异程度较高的词在空间中的位置则相距较远。
模型架构
CBOW
CBOW(Continuous Bag of Words)模型是一种经典的词嵌入(Word Embedding)模型,由 Mikolov 等人在 2013 年提出,是 Word2Vec 的两种核心架构之一。CBOW 通过上下文词汇预测当前词,从而学习词向量。CBOW 的输入是目标词周围的上下文词汇(窗口内的相邻词),输出是对目标词 [math]\displaystyle{ V_t }[/math] 的预测。模型的目标是:根据上下文词汇预测中心词。设定窗口大小为 [math]\displaystyle{ 2c }[/math],即在目标词左右各取 [math]\displaystyle{ c }[/math] 个词作为上下文,那么对于中心词 [math]\displaystyle{ w_t }[/math],其上下文为:[math]\displaystyle{ C_t = \{w_{t-c}, \ldots, w_{t-1}, w_{t+1}, \ldots, w_{t+c} \} }[/math]。模型的结构分为三层,分别是输入层、嵌入层(Embedding)、输出层。
输入层:
每个上下文词 [math]\displaystyle{ w_{t+i} }[/math] 以 one-hot 向量表示为:
[math]\displaystyle{ \mathbf{x}_{t+i} \in \mathbb{R}^{|V|} }[/math]
其中 [math]\displaystyle{ |V| }[/math] 为词汇表大小。词向量通过嵌入矩阵 [math]\displaystyle{ W \in \mathbb{R}^{|V| \times N} }[/math] 得到:
[math]\displaystyle{ \mathbf{v}_{t+i} = W^\top \mathbf{x}_{t+i} }[/math]
嵌入层:
对上下文词向量求平均,获得上下文表示向量:
[math]\displaystyle{ \mathbf{h}_t = \frac{1}{2c} \sum_{\substack{-c \le i \le c \\ i \ne 0}} \mathbf{v}_{t+i} }[/math]
输出层:
设输出矩阵为 [math]\displaystyle{ W' \in \mathbb{R}^{|V| \times N} }[/math],对应词 [math]\displaystyle{ w_j }[/math] 的输出得分为:
[math]\displaystyle{ u_j = \mathbf{v}'_j \cdot \mathbf{h}_t }[/math]
对所有词使用 softmax 得到目标词的预测概率:
[math]\displaystyle{ P(w_t = j \mid C_t) = \frac{\exp(u_j)}{\sum_{k=1}^{|V|} \exp(u_k)} = \frac{\exp(\mathbf{v}'_j \cdot \mathbf{h}_t)}{\sum_{k=1}^{|V|} \exp(\mathbf{v}'_k \cdot \mathbf{h}_t)} }[/math]
优化目标:
最大化整个语料的预测对数概率,即最小化负对数似然损失函数(NLL):
[math]\displaystyle{ \mathcal{L} = - \frac{1}{T} \sum_{t=1}^{T} \log P(w_t \mid C_t) }[/math]
词向量提取:
训练完成后,词向量可以从输入嵌入矩阵 [math]\displaystyle{ W }[/math] 提取,也可以从输出矩阵 [math]\displaystyle{ W' }[/math] 提取,或者对两者进行平均得到最终词向量。
Skip-gram 模型
Skip-gram 是 Word2Vec 的另一种核心模型,由 Mikolov 等人于 2013 年提出。与 CBOW(通过上下文预测中心词)不同,Skip-gram 是通过中心词预测上下文词,适合捕捉罕见词的语义,尤其在大规模语料上表现优异。Skip-gram的模型结构也分为三层:输入层、投影层、输出层。同样假设窗口大小为 [math]\displaystyle{ 2c }[/math],对于中心词 [math]\displaystyle{ w_t }[/math],其上下文为:[math]\displaystyle{ C_t = \{w_{t-c}, \ldots, w_{t-1}, w_{t+1}, \ldots, w_{t+c} \} }[/math]。
输入层:一段文本中心词汇[math]\displaystyle{ w_t }[/math]的one-hot编码作为输入向量 [math]\displaystyle{ \mathbf{x}_t \in \mathbb{R}^{|V|} }[/math]。
投影层:
输入向量与嵌入矩阵 [math]\displaystyle{ W \in \mathbb{R}^{V \times d} }[/math] 相乘,得到词向量 [math]\displaystyle{ \mathbf{h} }[/math]: [math]\displaystyle{ \mathbf{h} = W^\top \mathbf{v} }[/math]
输出层:
对于上下文中每个词 [math]\displaystyle{ w_{t+j} }[/math]([math]\displaystyle{ j \in \{-c,\ldots,-1,1,\ldots,c\} }[/math]),计算其预测概率:
[math]\displaystyle{ P(w_{t+j} \mid w_t) = \frac{\exp(\mathbf{v}'_{w_{t+j}} \cdot \mathbf{v}_t)}{\sum_{w \in V} \exp(\mathbf{v}'_w \cdot \mathbf{v}_t)} }[/math]
其中,[math]\displaystyle{ W' \in \mathbb{R}^{|V| \times N} }[/math] 是输出权重矩阵,[math]\displaystyle{ \mathbf{v}'_w }[/math] 是对应词的输出向量。
优化目标:
Skip-gram 通过最大化所有中心词和上下文词对的条件概率来训练模型,损失函数为负对数似然:
[math]\displaystyle{ \mathcal{L} = - \frac{1}{T} \sum_{t=1}^T \sum_{\substack{-c \le j \le c \\ j \ne 0}} \log P(w_{t+j} \mid w_t) }[/math]
词向量提取:
在Skip-gram中,词向量即为嵌入层之后所得到的向量,而不同于CBOW,Skip-gram的输出矩阵W'虽然也可以用来作为获得词向量的依据,但是其含义是中心词在上下文中的角色,在学习词汇之间关系的任务中可能使用W'作为词向量会有更好的表现。
相比之下,Skip-gram的效果要优于CBOW,这是因为CBOW在平均了词向量之后丧失了词汇的位置信息,丢失了词汇之间的关联性,因此目前各种工程实现中常用Skip-gram模型。
训练方法
无论是CBOW还是Skip-gram,总是需要遍历整个词表,因此计算代价很大,所以就有了两种近似的计算方法,负采样与层次softmax。这两个是 Word2Vec 中非常重要的训练加速策略,它们用于高效地优化输出词的概率分布。
负采样(Negative Sampling):
负采样的核心思想在于将原始问题转换成一个二分类问题,让模型只区分正样本和负样本,例如在Skip-gram中,对于一个中心词 [math]\displaystyle{ w_t }[/math] 和一个正确的上下文词 [math]\displaystyle{ w_o }[/math],正确的上下文词被称为正样本。同时人为给出错误的上下文文本 [math]\displaystyle{ w'_{o_i} }[/math],也就是负样本。负样本的采样一般按照词频 [math]\displaystyle{ U }[/math] 的 [math]\displaystyle{ 3/4 }[/math] 次方作为采样概率,即:
[math]\displaystyle{ P(w'_{o_i}) \propto U(w'_{o_i})^0.75 }[/math]
负采样目的在于最小化负样本与中心词一起出现的概率,同时最大化正样本与中心词一起出现的概率,将softmax替换为sigmoid函数,得到新的损失函数:
[math]\displaystyle{ \mathcal{L}_{Skip-gram} = log\sigma(\mathbf{v}^\top_{w_o} \mathbf{v}_{w_t}) + \sum^{k}_{i=1}log\sigma(-\mathbf{v}^\top_{w'_{o_i}} \mathbf{v}_{w_t}) }[/math]
其中,[math]\displaystyle{ \sigma }[/math] 是sigmoid函数,[math]\displaystyle{ k }[/math] 为负样本个数。同样,该方法也能应用在CBOW模型中,只是负样本变成了中心词:
[math]\displaystyle{ \mathcal{L}_{CBOW} = log\sigma(\mathbf{v}^\top_{w_t} \mathbf{h}) + \sum^{k}_{i=1}log\sigma(-\mathbf{v}^\top_{w'_{o_i}} \mathbf{h}) }[/math]
不过在实际应用中大多数时候使用Skip-gram,因此负采样在CBOW中的应用很少。
层次 Softmax(Hierarchical Softmax):
层次softmax的核心思路是根据词汇的词频构建一个霍夫曼树,每个叶节点代表一个词汇,而预测一个词汇就是沿着树走的一条路径,对应的也就是一个不断重复的二分类问题,因此每个目标词汇 [math]\displaystyle{ w_t }[/math] 都会被编码为一串二进制编码: [math]\displaystyle{ code(w_t)=(b_1, b_2, \ldots, b_L), b_i \in {0,1} }[/math] 而这条路径上的非叶子节点被记为 [math]\displaystyle{ n_1, n_2, \ldots, n_L }[/math]。因此,在Skip-gram中,给定中心词 [math]\displaystyle{ w_t }[/math] 与上下文词 [math]\displaystyle{ w_o }[/math] 之后,上下文词的条件概率就变成了:
[math]\displaystyle{ P(w_o \mid w_t) = \prod_{i=1}^L(w_o) \sigma (|1-b_i|\mathbf{v}_{n_i}^\top\mathbf{v}_{w_t}) }[/math]
其中[math]\displaystyle{ \mathbf{v}_{n_i} }[/math]是路径节点的向量,相当于原始输出矩阵[math]\displaystyle{ W' }[/math]。损失函数为最大化词对的出现概率:
[math]\displaystyle{ \mathcal{L} = - \sum_{(w_t, w_o) \in D} \log P(w_o \mid w_t) }[/math]
同样,层次softmax也可以应用于CBOW中,条件概率中的目标词词向量更换为了上下文词汇的平均词向量:
[math]\displaystyle{ P(w_t \mid \text{context}) = \prod_{i=1}^{L(w_t)} \sigma\left( [1 - b_i(w_t)] \cdot \mathbf{v}_{n_i}^\top \mathbf{h} \right) }[/math]
由此也能够得到对应的损失函数。
应用领域
自然语言处理
Word2Vec 是现代 NLP 系统中最早成功实现无监督预训练嵌入层的技术之一,它能够将文本中的词汇转换为稠密的向量表示,并保留语义与句法信息,为各种语言理解与生成任务提供了统一的向量空间支持。
语义分析:
在语义分析方面,Word2Vec 能够通过词向量之间的相对距离和方向关系建模词义相似度与句法结构。例如,在词义消歧任务中,如果句子中出现了歧义词“bank”,模型可以利用其与上下文词(如“money”或“river”)之间的向量相似性,推断其在当前语境中是“银行”还是“河岸”。情感分析也是 Word2Vec 的典型应用场景之一,通过聚类“好”、“棒”、“糟糕”、“失望”等情感色彩明显的词向量,构建带情感权重的表示,再结合分类器(如 SVM)进行句子级或文档级的情绪判定。例如,企业可使用该方法自动识别客户评论的正负面态度。在主题建模任务中,研究者常利用 Word2Vec 学习到的语义向量进行 K-means 等聚类操作,从而发掘出语料中隐含的语义主题,如科技类文本中自动聚类出“人工智能”、“量子计算”、“大数据”等主题簇。
机器翻译:
在机器翻译任务中,Word2Vec 可用于词对齐与语义映射的预处理阶段。通过训练源语言与目标语言的词向量模型,并将其映射到共享向量空间,可以自动对齐如“hello”与“hola”,“school”与“école”这类语义对等词汇,这种方法在无监督机器翻译中尤其常见。此外,在基于神经网络的机器翻译系统(如 Seq2Seq 或 Transformer 模型)中,Word2Vec 也被用于初始化嵌入层权重,相比随机初始化可显著加速模型收敛,提高 BLEU 翻译质量得分。谷歌早期的 NMT 系统就曾在多语种语料上使用跨语言词向量来实现语言无关的嵌入表示,有效支持了低资源语言的翻译。
文本分类:
在文本分类任务中,Word2Vec 同样具有广泛用途。以新闻分类为例,不同主题(如“财经”、“体育”、“国际”)的新闻中出现的关键词往往语义聚集,通过 Word2Vec 向量聚合形成文本表示,再输入分类器(如 CNN、Transformer)进行训练,可高效地区分不同类别的文本。在垃圾邮件识别中,模型可捕捉如“中奖”、“优惠”、“请点击”等词汇的特征并识别其潜在风险。在法律文书分类中,词向量可帮助模型辨别“判决书”、“调解书”、“起诉状”等不同法律文体的词汇特征,从而自动进行文档归档。通常做法是在句子级别对每个词向量进行平均或加权平均操作,构建文档向量,再送入模型进行判别。以 IMDb 电影评论为例,研究人员常使用 Word2Vec 初始化嵌入表示,再结合情感标注数据进行二分类训练,用于判断用户评价是正面还是负面。
总体来看,Word2Vec 在 NLP 中的主要价值在于:提供一种轻量、高效且能迁移的通用词语表示形式,极大地降低了特征工程的门槛,为机器学习和深度学习模型提供了统一的输入基础。
推荐系统
虽然 Word2Vec 最初是为处理语言建模任务而设计,但其核心思想——“在上下文中共现的词语往往意义相关”——可以被自然迁移到非语言领域,特别是推荐系统中。推荐系统中的“用户行为序列”与 NLP 中的“句子”结构高度相似,而“商品、视频、音乐等内容”则可类比为“词”。基于这种结构对应关系,Word2Vec 成为建模用户偏好和内容相似性的强大工具。
在实践中,推荐系统会将用户的历史点击序列、购物行为或播放列表视作时间序列数据,将其中每一个物品(如商品ID、音乐ID)作为一个“词”输入 Word2Vec 模型进行训练。采用 Skip-gram 结构后,模型试图预测某个物品的上下文物品(即前后点击或购买的内容),从而学习出反映行为模式的向量表示。
训练完成后,Word2Vec 模型输出的嵌入向量可以直接用于推荐。最常见的方式是通过计算当前浏览/购买商品与其他商品之间的向量相似度(通常为余弦相似度),从而生成相似商品推荐(Item-to-Item 推荐)。此外,还可以将一个用户所有历史行为的物品向量进行平均,得到用户的兴趣画像向量,用于个性化推荐排序。
这一思想已经在多个主流平台落地并取得了良好效果。例如:
·淘宝、京东等电商平台使用商品序列训练 Word2Vec,构建“商品—商品”图谱,用于猜你喜欢、搭配购、商品联想等场景。比如用户在浏览“运动鞋”页面后,系统会推荐“运动袜”、“运动手表”等与其行为序列中相邻频繁出现的物品。
·美团和大众点评等本地生活平台,通过用户在一定时间段内访问的商家序列(如早餐店、便利店、药店),构建“地点向量”或“服务向量”,支持基于用户轨迹的本地商家推荐,如“去过 A 的人,也常去 B”。
信息检索
在传统信息检索系统中,搜索结果的相关性通常依赖于关键词的精确匹配,例如布尔检索、TF-IDF 或 BM25 等基于词频的模型。这些方法尽管在速度和工程实现上具备优势,但在语义层面存在严重缺陷:一旦查询词与文档中的词不完全一致,即便它们在意义上高度相关,也可能无法匹配。这就导致了检索召回率不足或排序不准确的问题。Word2Vec 所提供的分布式表示弥补了这一不足,它将语义上相近的词投射到向量空间中的相邻位置,从而支持更灵活、更具语义关联性的检索策略。
查询扩展(Query Expansion):
例如,当用户输入关键词“肺炎”时,系统可以在训练好的词向量模型中自动找出与其相似的词,如“呼吸道感染”、“发烧”、“流感”等,并将这些词加入查询词集合中,从而扩大搜索范围,提高语义召回能力。此类机制在医学检索、法律文献检索中尤为重要,因为术语表达方式多变,而查询词往往较为简单。
文档排序:
在文档排序任务中,系统可将查询和文档中词嵌入后计算语义相关性得分,辅助判断哪些文档更符合用户意图,用于替代传统的基于词频的打分方式。此外,Word2Vec 在短文本理解中也非常有效,常用于搜索建议、问答匹配、智能补全等场景,尤其适合处理查询词稀疏、语义模糊的用户输入。
短文本理解:
此外,短文本理解任务中 Word2Vec 的作用也尤为显著。在搜索建议、智能补全、FAQ 匹配等场景中,用户输入往往是极短的词组甚至单词,这使得传统稀疏表示方法效果极差。而 Word2Vec 可通过词向量的上下文信息推断潜在语义,提升理解准确度。例如,在输入“退货”时系统可联想到“退款”、“售后”、“客服”等相关查询,从而实现更贴近用户意图的补全建议。
其他领域
Word2Vec 的通用表示能力使其在多个非语言学领域也展现出强大的迁移价值。通过将非语言数据结构化为“序列”或“上下文”形式,Word2Vec 能够学习出反映实体关系的向量表示,从而广泛应用于生物信息学、社会科学及专业技术领域。
生物信息学:
在生物信息学中,研究者将蛋白质或 DNA 序列中的氨基酸、核苷酸片段视为“词”,构建“生物语言”。通过训练 Word2Vec 模型,可以学习到功能相关序列的向量表示,应用于蛋白质功能预测、疾病相关区域识别等任务。例如,某些氨基酸片段在多个蛋白质中共现频繁,模型会自动捕捉它们的潜在生物学意义。此外,Word2Vec 也被用于药物发现场景,辅助建模药物与靶点间的语义联系。
社会科学:
在社会科学中,Word2Vec 被用于探测语言中的刻板印象和社会偏见。通过分析词向量之间的距离,如“nurse”更接近“she”,“doctor”更接近“he”,可揭示潜在的性别偏见结构。同时,研究人员也使用时间序列语料构建跨年代词向量,研究词义随时代的语义漂移,如“liberal”、“gender”等词在不同时期的语义演变路径。
法律、金融、医疗等垂直领域:
在法律、金融、医疗等垂直领域,Word2Vec 有助于理解专业术语之间的语义关系。在法律文本分析中,模型可用于预测文书之间的相似度,辅助法官判例归类与类案推荐;在金融领域,Word2Vec 被用于情绪识别系统中,帮助模型理解公告、舆情或分析报告中的潜在语义态度;在医疗信息处理中,词向量支持将病症、药品与治疗手段建模为统一向量空间,用于构建医学知识图谱或提升电子病历挖掘效率。
优缺点
优点
捕捉语义和语法关系:
通过上下文预测(Skip-gram/CBOW),可学习到单词的分布式表示,相似语义或语法角色的词在向量空间中距离相近。
支持线性类比关系(如“国王 - 男 + 女 ≈ 女王”)。
适用于大规模数据:
可高效训练数十亿级别的语料,内存消耗相对较低。
通用性强:
词向量可作为下游任务(如文本分类、机器翻译)的特征输入,提升模型性能。
局限性
无法处理多义词(Polysemy):
每个词仅对应单一向量,无法区分不同上下文中的多义性(如“苹果”指水果或公司)。
依赖局部上下文:
仅基于窗口内的局部共现信息,忽略文档级或语料级的全局统计特征(如GloVe的优势)。
需要大量训练数据:
小规模语料下生成的词向量质量较差,难以捕捉低频词语义。
静态词向量(Static Embeddings):
词向量在训练后固定,无法动态适应不同上下文(后续模型如ELMo、BERT解决了这一问题)。
窗口大小敏感:
表现受上下文窗口大小影响,过大或过小均可能导致语义捕捉不充分。
未考虑词序信息:
Skip-gram和CBOW模型忽略窗口内词的顺序关系(后续改进如Seq2Vec或Transformer可解决)。
相关技术与扩展
GloVe(Global Vectors for Word Representation)
背景:
GloVe 是由斯坦福大学的 Jeffrey Pennington、Richard Socher 和 Christopher D. Manning 于 2014 年提出,旨在结合传统基于计数的模型(如 LSA)和 Word2Vec 的优势,提出一种高效的全局词向量训练方法。
技术原理:
GloVe 是一种基于全局共现信息来学习词向量的方法[6],与 Word2Vec 不同,它不依赖上下文窗口中的预测任务,而是采用词与词之间在整个语料库中共现频率的统计信息来构造词语之间的关系。
GloVe 的设计灵感来自以下关键观察:词语的语义关系可以通过它们与其他词共现的比例来表达,而不是仅通过是否共现或是否邻近。例如,“ice” 和 “steam” 都与 “water” 有很强的共现关系,但 “ice” 更倾向与 “cold” 共现,而 “steam” 更倾向与 “hot” 共现。GloVe 试图让词向量之间的差异或比例能反映出这种语义关系。
在训练之前,GloVe 首先对整个语料库构建一个 共现矩阵[math]\displaystyle{ X }[/math]:
·每个元素 [math]\displaystyle{ X_{ij} }[/math] 表示词[math]\displaystyle{ j }[/math]在词 [math]\displaystyle{ i }[/math] 的上下文窗口中出现的次数;
·矩阵是稀疏且高维的,规模为 [math]\displaystyle{ V \times V }[/math],其中 [math]\displaystyle{ V }[/math] 是词汇表大小。
GloVe 的一个重要设计理念是:两个词之间的语义关系可由它们对其他词的共现比值刻画。对于一个目标词 [math]\displaystyle{ i }[/math],考虑两个上下文词 [math]\displaystyle{ j }[/math] 和 [math]\displaystyle{ k }[/math],如果 [math]\displaystyle{ i }[/math] 与 [math]\displaystyle{ j }[/math] 的共现频率远高于与 [math]\displaystyle{ k }[/math],则两者在语义上的关联也会不同。
定义贡献概率为:
[math]\displaystyle{ P_{ik} = \frac{X_{ik}}{\sum_{k'} X_{ik'}} }[/math]
GloVe 期望通过学习得到的词向量 [math]\displaystyle{ w_i }[/math],能使词之间的向量关系满足下列公式形式:
[math]\displaystyle{ F(\mathbf{w}_i, \tilde{\mathbf{w}}_j, X_{ij}) = \mathbf{w}_i^\top \tilde{\mathbf{w}}_j + b_i + \tilde{b}_j \approx \log X_{ij} }[/math]
即目标是让词向量的点积加上偏置项逼近共现频率的对数值,而不是原始频数,后者变化范围太大。
为了实现上述目标,GloVe 构建了以下加权平方误差损失函数:
[math]\displaystyle{ J = \sum_{i,j=1}^{V} f(X_{ij}) \cdot \left( \mathbf{w}_i^\top \tilde{\mathbf{w}}_j + b_i + \tilde{b}_j - \log X_{ij} \right)^2 }[/math]
其中:
[math]\displaystyle{ X_{ij} }[/math]: 词 [math]\displaystyle{ i }[/math] 和 [math]\displaystyle{ j }[/math] 的共现次数;
[math]\displaystyle{ \mathbf{w}_i }[/math] 、[math]\displaystyle{ \tilde{\mathbf{w}}_j }[/math] : 词向量;
[math]\displaystyle{ f(x) }[/math]:权重函数(防止高频词主导优化);
[math]\displaystyle{ b_i }[/math] , [math]\displaystyle{ {b}_j }[/math]:偏置项。
这个函数可以防止高频词主导模型训练,也避免了低频词对整体模型质量的影响。
总结与对比:
·不同于 Word2Vec:Word2Vec 是基于预测任务(局部上下文窗口);而 GloVe 是基于矩阵分解(全局共现频率);
·相比传统 LSA(SVD):GloVe 使用非线性权重函数,训练时不需要全局矩阵分解,更高效;
·适合全局语义关系建模,尤其在大规模语料训练中表现优异;
·支持线性类比关系,类似 Word2Vec(如“king - man + woman ≈ queen”)
FastText
背景:
FastText 是由 Facebook AI Research 的 Armand Joulin、Tomas Mikolov 等人于 2016 年提出[7],旨在解决 Word2Vec 模型在处理罕见词、词形变化(如复数、时态)等方面的能力不足。其核心理念是在训练过程中引入子词信息,以增强词向量对形态的建模能力。
技术原理:
FastText 的核心思想是:将词视为子词(subword)n-gram 的组合体,而不是独立的原子单位。这一设计增强了模型对罕见词、形态变化词以及未登录词(OOV)的表示能力。
子词建模(Subword Embedding):
每个单词 [math]\displaystyle{ w }[/math] 被划分为若干个字符 n-gram,例如设置 n = 3~6 时:
对于词 “where”,首先在其两端添加边界符号(如 < 和 >),构成:<where>,然后提取字符 n-gram 得到: <wh, whe, her, ere, re>,包括完整词本身 "where",最终表示为一个 n-gram 集合 [math]\displaystyle{ G_w }[/math]。
词向量的表示为其所有 n-gram 向量的平均或和:
[math]\displaystyle{ v_w = \sum_{g \in G} w_g z_g }[/math]
其中:
[math]\displaystyle{ z_g }[/math] 是 n-gram [math]\displaystyle{ g }[/math] 的嵌入向量;
[math]\displaystyle{ G_w }[/math] 是词 [math]\displaystyle{ w }[/math] 的所有子词集合。
这种表示方式让模型在遇到未登录词时,也可以通过其组成子词获取合理向量。
模型结构与训练:
FastText 延续了 Word2Vec 的 Skip-gram 架构,但输入词不再是 one-hot 编码的词本身,而是其所有 n-gram 的组合。训练目标为:给定中心词(子词组合向量),预测其上下文词。即最大化如下目标函数:
[math]\displaystyle{ L_{\text{Skip-gram}} = \sum_{(w_t, w_o) \in D} \left[ \log \sigma\left( \mathbf{v}_{w_o}^\top \mathbf{v}_{w_t} \right) + \sum_{i=1}^{k} \mathbb{E}_{w_i' \sim P_n(w)} \log \sigma\left( -\mathbf{v}_{w_i'}^\top \mathbf{v}_{w_t} \right) \right] }[/math]
其中:
[math]\displaystyle{ w }[/math] 是由子词构成的中心词向量;
[math]\displaystyle{ v_{wo} }[/math] 是上下文词向量;
负采样 [math]\displaystyle{ P_n(w) }[/math] 用于高效近似 softmax。
FastText 的训练过程本质上是端到端地联合优化所有子词的向量表示,以提升整体语义建模能力。
总结与对比:
子词增强表示能力:FastText 通过引入 n-gram,有效表示未登录词与形态变化词;
面向多语言与拼写多样化语言(如芬兰语、德语)效果显著优于 Word2Vec;
与 Word2Vec 相比:Word2Vec 只能对词表中出现过的词进行建模,FastText 可泛化到未出现的新词,具备更强的鲁棒性与泛化能力;
与 GloVe 相比:GloVe 基于全局共现信息构建稠密表示,适合静态建模,FastText 基于局部上下文与子词结构,适合细粒度语义与动态扩展;
应用场景广泛:在文本分类、命名实体识别、搜索排序、拼写纠错、推荐系统中广泛使用;
BERT 模型
背景:
BERT 是由 Google AI Language 团队于 2018 年提出的一种预训练语言表示模型[8],发表在论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》中。该模型首次将 深度双向 Transformer 编码器 应用于语言建模任务,并通过大规模语料上的预训练 + 微调机制,在多个自然语言处理任务上取得了 SOTA(state-of-the-art)成绩。
BERT 的设计动机是解决传统语言模型(如 Word2Vec、GloVe)在上下文建模、语义歧义处理和句子级理解方面的不足,特别是在建模“一个词在不同上下文中含义不同”这一关键问题。
技术原理:
基础架构:Transformer Encoder:
BERT 构建在 Transformer 架构之上,具体使用了 多层 Transformer 编码器堆叠(通常 BERT-base 为 12 层,BERT-large 为 24 层)。Transformer 由 Vaswani 等人在 2017 年提出,其最大特点是 完全基于注意力机制(Self-Attention),无需使用 RNN 或 CNN,可并行处理任意长度的输入。
每层包含:
多头自注意力机制(Multi-Head Self-Attention);
前馈神经网络(Feed-Forward Layer);
残差连接 + 层归一化。
Transformer 中每个词的表示会综合考虑所有其他词对它的影响,因此能捕捉复杂的依赖结构。
输入方式表示:
BERT 的输入不只是单词序列,而是词 + 位置 + 句子类型三重嵌入之和:Input Embedding = Token Embedding + Position Embedding + Segment Embedding
例如用于句子对任务(如问答)时,Segment A 表示第一句话,Segment B 表示第二句话。输入序列结构为:[CLS] 句子A [SEP] 句子B [SEP],其中[CLS] 用于分类任务的特殊标记;[SEP] 是句子分隔符。
预训练阶段:
BERT 采用两种 自监督学习任务在大规模语料(如 Wikipedia 和 BooksCorpus)上进行训练:
(1)Masked Language Model(MLM):随机遮蔽输入序列中约 15% 的词,模型需预测被 []MASK 替换的词是什么,本质上是一个多分类任务:
[math]\displaystyle{ L_{\text{MLM}} = - \sum_{i \in M} \log P(w_i \mid x_{\text{masked}}) }[/math]
(2)Next Sentence Prediction(NSP):输入两个句子 A 和 B,任务是判断 B 是否是 A 的真实下一句,是一个二分类任务:
[math]\displaystyle{ L_{\text{NSP}} = -\log P(\text{IsNext} \mid A, B) }[/math]
微调阶段:
在预训练后,BERT 可被快速迁移到下游任务,如:文本分类(情感分析)、序列标注(命名实体识别)、问答系统,只需在最后加上一层简单的任务特定结构,并用少量数据进行微调即可。
总结与对比:
深度双向建模:BERT 同时利用左上下文与右上下文,解决传统语言模型单向建模的局限;
动态词表示:同一个词在不同句子中的表示不同,能处理多义词与上下文依赖;
Transformer 架构支持全局依赖建模,相比 RNN 更并行高效;
统一多任务结构:BERT 能处理分类、标注、问答等多类任务,具备高度迁移能力;
与 Word2Vec/GloVe 对比:Word2Vec/GloVe 生成的是固定词向量、语境无关,BERT 输出的是上下文相关的词表示,能捕捉复杂句法语义关系;
动态词嵌入( ELMo):
背景:
ELMo(Embeddings from Language Models)是由 Allen Institute for AI(AI2)的 Matthew Peters 等人在 2018 年 NAACL 上提出的预训练词嵌入方法[9]。ELMo 是 NLP 中首个大规模应用上下文动态词向量的模型,突破了 Word2Vec 和 GloVe 中“一个词一个向量”的静态表示限制。其提出背景在于自然语言中存在大量多义词与语义歧义现象(如 "bank" 表示“银行”或“河岸”),传统静态词向量模型无法根据上下文动态调整词的含义表示。而 ELMo 利用双向语言模型(BiLM)捕捉词的上下文依赖关系,为每个词生成可变的、语境敏感的表示。
技术原理:
ELMo 基于传统语言模型(Language Model, LM),但引入了以下三个关键技术点:
双向语言模型(BiLM):
一个正向语言模型(从左到右):[math]\displaystyle{ P(w_1, w_2, \ldots, w_T) = \prod_{t=1}^{T} P(w_t \mid w_1, \ldots, w_{t-1}) }[/math]
一个反向语言模型(从右到左):[math]\displaystyle{ P(w_T, \ldots, w_1) = \prod_{t=1}^{T} P(w_t \mid w_{t+1}, \ldots, w_T) }[/math]
这两个模型均使用深层 LSTM(Long Short-Term Memory) 网络进行建模,层数通常为两层。
多层表示聚合机制:
ELMo 并不是仅提取 LSTM 的最后一层输出作为词向量,而是将所有层的隐状态按照加权方式聚合,从而获得更加丰富的语义特征。
每个词的 ELMo 表示由以下公式给出:
[math]\displaystyle{ \text{ELMo}(w_t) = \gamma \sum_{j=0}^{L} s_j \cdot \mathbf{h}_t^{(j)} }[/math]
其中:
[math]\displaystyle{ \mathbf{h}_t^{(j)} }[/math] 表示第 [math]\displaystyle{ j }[/math] 层对词 [math]\displaystyle{ w_t }[/math] 的隐状态,是前向和后向语言模型的连接结果。
[math]\displaystyle{ s_j }[/math] 是第[math]\displaystyle{ j }[/math]层的可学习权重,表示该层对最终表示的贡献程度;
[math]\displaystyle{ γ }[/math] 是可学习缩放因子,控制整体表示的幅度。
训练与迁移使用:
ELMo 先在大规模语料上训练语言模型(如 1 Billion Word Benchmark),然后将训练好的表示迁移到下游任务中,并在下游任务中联合微调(fine-tune)其权重[math]\displaystyle{ s_j }[/math],[math]\displaystyle{ γ }[/math]。这种机制大幅提高了模型对语境、词义变化的感知能力,适用于情感分类(Sentiment Analysis)、问答系统(QA)和自然语言推理(NLI)。
总结与对比:
上下文敏感词向量:ELMo 是首个提供每个词在不同上下文中动态表示的预训练词嵌入;
双向语言模型建模上下文:同时考虑前文与后文,有效捕捉语言结构与语义;
与 Word2Vec/GloVe 对比:ELMo 输出的词向量会随句子变化,是“动态词向量”;
与 BERT 对比:BERT 使用 Transformer 架构,具备更强建模能力,训练代价更高,ELMo 使用 LSTM 架构,计算成本相对较低,更适合中小规模任务。
开源实现与工具
Word2Vec 自 2013 年由 Google 发布以来,被广泛应用于自然语言处理任务。除了原始的 C 语言实现,目前已有多个高效的开源工具和库支持 Word2Vec 的训练与使用。
Gensim 库
特点:
- 语言:Python
- 功能:
- 支持 CBOW 和 Skip-gram 两种训练模式。
- 提供 负采样(Negative Sampling) 和 层次 Softmax(Hierarchical Softmax) 加速训练。
- 可调整参数:窗口大小、词向量维度、最小词频、训练轮次(epochs)等。
- 支持模型保存为
.bin
(二进制)或.txt
(纯文本)格式,兼容其他 NLP 工具(如 FastText、GloVe)。 - 提供 增量训练(继续训练已有模型)和 词汇表更新 功能。
示例代码:
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence # 用于流式读取大文件
# 示例1:基础训练(列表输入)
sentences = [
["自然", "语言", "处理", "很", "有趣"],
["深度学习", "改变", "了", "NLP"],
["Word2Vec", "是", "经典", "算法"]
]
model = Word2Vec(
sentences=sentences,
vector_size=300, # 词向量维度
window=5, # 上下文窗口
min_count=1, # 最小词频
workers=4, # 并行线程数
sg=1, # 1=Skip-gram, 0=CBOW
hs=0, # 0=负采样, 1=层次Softmax
negative=5, # 负采样数
epochs=10 # 训练轮次
)
# 示例2:大文件训练(流式读取)
corpus_path = "corpus.txt" # 每行一个句子,词语用空格分隔
model = Word2Vec(
sentences=LineSentence(corpus_path), # 自动按行流式读取
vector_size=300,
window=5,
min_count=5, # 过滤低频词
workers=8
)
# 模型使用
print(model.wv["自然"]) # 获取词向量
print(model.wv.most_similar("NLP", topn=3)) # 相似词查询
# 模型保存与加载
model.save("word2vec.model") # 二进制格式
model.wv.save_word2vec_format("vectors.bin", binary=True) # 兼容原始格式
loaded_model = Word2Vec.load("word2vec.model")
适用场景:
- 快速实验 Word2Vec 模型,适用于中小规模语料(百万级词汇)。
- 需要与其他 Python NLP 工具(如 spaCy、NLTK)集成时。
TensorFlow / PyTorch 实现
特点:
- 语言:Python(基于 TensorFlow/PyTorch 框架)
- 功能:
- 提供更灵活的模型自定义能力(如修改损失函数、调整网络结构)。
- 支持 GPU 加速训练,适合大规模语料(十亿级词汇)。
- 可与其他深度学习模型(如 LSTM、Transformer)结合使用。
TensorFlow 实现示例:
import tensorflow as tf
import numpy as np
# 示例:Skip-gram负采样实现
vocab_size = 10000
embedding_dim = 300
num_ns = 5 # 负采样数
# 自定义Word2Vec模型
class Word2Vec(tf.keras.Model):
def __init__(self):
super().__init__()
self.target_embedding = tf.keras.layers.Embedding(
vocab_size, embedding_dim, input_length=1)
self.context_embedding = tf.keras.layers.Embedding(
vocab_size, embedding_dim, input_length=num_ns+1)
def call(self, pair):
target, context = pair
# target shape: (batch, 1)
# context shape: (batch, 1+num_ns)
word_emb = self.target_embedding(target) # (batch, 1, dim)
context_emb = self.context_embedding(context) # (batch, 1+num_ns, dim)
return tf.matmul(word_emb, context_emb, transpose_b=True)
# 数据准备(假设已预处理)
target_words = np.random.randint(0, vocab_size, (1000, 1))
context_words = np.random.randint(0, vocab_size, (1000, 6)) # 1正样本+5负样本
# 编译训练
model = Word2Vec()
model.compile(optimizer='adam', loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True))
model.fit(x=(target_words, context_words), epochs=5)
# 获取词向量
embedding_layer = model.get_layer('target_embedding')
word_vectors = embedding_layer.get_weights()[0]
PyTorch 实现示例:
import torch
import torch.nn as nn
# 自定义 Word2Vec 模型(CBOW)
class Word2Vec(nn.Module):
def __init__(self, vocab_size, embedding_dim):
super().__init__()
# 中心词和上下文词共享同一个嵌入矩阵
self.embeddings = nn.Embedding(vocab_size, embedding_dim)
def forward(self, target, context):
# target shape: (batch_size,)
# context shape: (batch_size,)
target_emb = self.embeddings(target) # (batch_size, embedding_dim)
context_emb = self.embeddings(context) # (batch_size, embedding_dim)
# 计算点积得分(Skip-gram目标)
scores = torch.sum(target_emb * context_emb, dim=1) # (batch_size,)
return scores
适用场景:
- 需要与深度学习模型联合训练(如文本分类+词向量微调)。
- 研究场景,需自定义 Word2Vec 的变体(如结合注意力机制)。
原始 C 语言实现
特点:
- 语言:C
- 功能:
- Google 官方发布的原始实现,效率极高(适合超大规模语料)。
- 仅支持基本的 Skip-gram 和 CBOW,无负采样或层次 Softmax 优化。
- 输出格式为二进制(
.bin
)或文本(.txt
)词向量。
使用方法:
# 从源码编译(需要gcc)
git clone https://github.com/tmikolov/word2vec
cd word2vec
make
# 训练命令详解
./word2vec -train corpus.txt \ # 输入文件(每行一个句子)
-output vectors.bin \ # 输出词向量
-size 300 \ # 向量维度
-window 5 \ # 窗口大小
-sample 1e-5 \ # 高频词降采样阈值
-negative 5 \ # 负采样数
-hs 0 \ # 禁用层次Softmax
-threads 16 \ # 线程数
-binary 1 \ # 二进制输出
-iter 10 # 训练轮次
适用场景:
- 需要最高训练效率(如 Wikipedia 或 Common Crawl 级别语料)。
- 对模型定制需求低,仅需基础词向量生成。
参考文献
- ↑ Mikolov T, Chen K, Corrado G, et al. Efficient estimation of word representations in vector space[J]. arXiv preprint arXiv:1301.3781, 2013.
- ↑ Mikolov T, Sutskever I, Chen K, et al. Distributed representations of words and phrases and their compositionality[J]. Advances in neural information processing systems, 2013, 26.
- ↑ Hinton G E. Learning distributed representations of concepts[C]//Proceedings of the Annual Meeting of the Cognitive Science Society. 1986, 8.
- ↑ Elman J L. Finding structure in time[J]. Cognitive science, 1990, 14(2): 179-211.
- ↑ Mikolov T, Karafiát M, Burget L, et al. Recurrent neural network based language model[C]//Interspeech. 2010, 2(3): 1045-1048.
- ↑ Pennington J, Socher R, Manning C D. Glove: Global vectors for word representation[C]//Proceedings of the 2014 conference on empirical methods in natural language processing (EMNLP). 2014: 1532-1543.
- ↑ Joulin A, Grave E, Bojanowski P, et al. Bag of tricks for efficient text classification[J]. arXiv preprint arXiv:1607.01759, 2016.
- ↑ Devlin J, Chang M W, Lee K, et al. Bert: Pre-training of deep bidirectional transformers for language understanding[C]//Proceedings of the 2019 conference of the North American chapter of the association for computational linguistics: human language technologies, volume 1 (long and short papers). 2019: 4171-4186.
- ↑ PETERS M E, NEUMANN M, IYER M, et al. Deep contextualized word representations[J/OL]. arXiv, 2018: 1802.05365 [2023-12-01]. https://arxiv.org/abs/1802.05365.