查看原文
其他

一文读懂词向量Word2Vec及Python实现

王海华 模型视角 2023-08-15

Word2Vec 简介

Word2Vec 是一个流行的词嵌入算法,由 Tomas Mikolov 和他的团队在 2013 年提出。它的主要目的是将每个单词映射到固定大小的向量,这些向量能够捕捉单词之间的语义关系

我们通过一个简单的例子来解释这句话。

假设你有以下句子:

  • "狗喜欢玩球。"
  • "猫喜欢爬树。"
  • "狗和猫都是宠物。"
  • "足球是一种流行的运动。"

现在,当我们使用 Word2Vec 算法训练这些句子时,我们会得到每个单词的向量表示。这些向量不是随机的数字,而是捕捉了单词之间的语义关系。例如:

  • “狗”和“猫”的向量可能会很接近,因为它们都被描述为“宠物”。
  • 而“玩球”和“足球”之间也可能有某种关系,因为它们都与“球”这个概念有关。
  • 同时,“玩球”和“爬树”之间的关系可能就不那么紧密,因为它们描述的是完全不同的活动。这意味着,如果我们查看“狗”的向量与其他所有单词的向量之间的相似性,我们可能会发现“猫”是最相似的,而“爬树”可能是最不相似的。

在数学上,这种“相似性”通常通过计算向量之间的余弦相似度来量化。

余弦相似度用于度量两个向量的夹角的余弦值,以此作为两个向量之间的相似度。公式如下:

其中:

  • 是两个向量。
  • 表示 的点积。
  • 分别表示 的模长(也叫做范数),它们的计算方法是取向量的每个元 素的平方,然后求和,再取平方根。余弦相似度的值范围在 之间,其中 1 表示两个向量完全相似,0 表示两个向量完全不 相关,而 - 1 表示两个向量完全相反。

具有高余弦相似度的两个向量表示它们在语义上很接近。

这正是 Word2Vec 能够实现的:通过学习文本中的上下文,为每个单词生成一个向量,这个向量能够捕捉与其他单词的语义关系

Word2Vec 的工作原理

Word2Vec 的训练基于两种主要的架构:CBOW (Continuous Bag of Words) 和 Skip-Gram。

CBOW (连续词袋模型):

  • 它预测目标单词 (中心词) 基于其上下文 (周围的词) 。换句话说,它使用上下文来预测 目标单词。
  • 输入层: 上下文词的 one-hot 编码。
  • 输出层: 目标单词的概率分布。

在 CBOW 中,根据上下文词(例如 ) 预测目标 词 的概率。给定一个上下文 , 目标词 的概率为:

其中:

  • 是目标词 的输出向量。
  • 是上下文的嵌入向量,通常是上下文词嵌入向量的平均值。
  • 是词汇表大小。

Skip-Gram:

  • 它的工作方式与 CBOW 相反。它试图使用目标单词来预测其上下文。
  • 输入层: 目标单词的 one-hot 编码。
  • 输出层: 上下文词的概率分布。

与 CBOW 相反,Skip-Gram 试图从目标词预测上下文。对于每个上下文词 (其中 的概率为:

其中:

  • 是上下文词 的输出向量。
  • 是目标词 的输入向量。
  • 是词汇表大小。

神经网络架构:

Word2Vec 使用浅层的神经网络,通常只有一层隐藏层。该网络可以是基于上述两种架构之一进行训练的。在训练过程结束后,权重从输入层到隐藏层被用作单词的向量表示。 

训统过程:

  1. 初始值: 开始时,模型的权重是随机的,每个单词都有一个随机的向量表示。
  2. 滑动窗口:选择一个窗口大小,然后在文本中滑动这个窗口,每次滑动都提取目标词和其上 下文词,并基于选择的架构(CBOW 或Skip-Gram)进行训练。
  3. 优化: 使用 softmax 函数来计算输出词的概率分布,并使用反向传播和梯度下降来优化权重,使误差最小化。
  4. 抽取词向量:训练结束后,从输入到隐藏层的权重被用作词的向量表示。

负采样:

由于 softmax 函数需要考虑词汇表中的每个单词,因此计算成本会非常高。为了解决这个问题,Word2Vec 使用了一种称为 "负采样" 的技术。在这种方法中,而不是更新所有单词的权 重,它只更新正样本和一小部分随机选择的负样本的权重。

让我们定义一个正样本为 ,其对应的损失为:

其中:

  • 是 Sigmoid 函数。
  • 是词 被选为负样本的概率。

经过训练,语义上相似或相关的词在向量空间中会靠得很近。例如,"king" 和 "queen" 之间的关系可以通过向量算术来捕获,如:king - man + woman ≈ queen。

Word2Vec 使用上下文信息,通过浅层神经网络训练,为每个单词提供了一个密集的向量表示,这些向量能够捕捉单词的语义和句法关系。

Python实现

gensim  库可以非常简便地训练 Word2Vec 模型。以下是使用 gensim 训练 Word2Vec Skip-Gram 模型的步骤:

安装 gensim:

pip install gensim

使用 gensim 训练 Word2Vec:

from gensim.models import Word2Vec
import logging

# 为了显示训练日志
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

# 示例句子
sentences = [
    "I love machine learning",
    "Machine learning is fascinating",
    "Deep learning and machine learning are both subsets of AI"
]

# Tokenization
sentences = [sentence.split() for sentence in sentences]

# 训练 Word2Vec 模型
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4, sg=1)  # sg=1 表示使用 Skip-Gram; 若为0则使用 CBOW

# 保存模型
model.save("word2vec_example.model")

使用模型: 加载模型并查询相似的词:

# 加载模型
model = Word2Vec.load("word2vec_example.model")

# 查找与 "machine" 最相似的词
similar_words = model.wv.most_similar("machine", topn=5)
print(similar_words)

你也可以直接获取某个词的向量:

vector = model.wv['machine']
print(vector)

以上就是使用 gensim 进行 Word2Vec 训练的简化示例。请注意,为了得到有意义的词向量,你需要一个大型的语料库。这里只是为了展示如何使用库而提供的小型示例,感兴趣的朋友可以使用自己的或公开的语料库进行训练。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存