从Word2Vec到Glove——探究词向量模型的演变
创始人
2025-05-30 04:39:55

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️

👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博相关......)👈

Glove

(封面图由文心一格生成)

从Word2Vec到Glove——探究词向量模型的演变

在机器学习和自然语言处理领域,词向量是一种常见的表征文本的方式。在过去几年里,各种词向量模型如雨后春笋般出现。其中,Word2Vec、Glove、FastText等成为了最流行的几种。其中,Glove模型因为其独特的理论基础和良好的性能而受到了广泛的关注。

本篇博客将会介绍Glove模型的原理和实现方法,并与其他词向量模型进行对比。我们将探究Glove模型是如何通过联合矩阵分解的方法,将语料库中的词语和共现信息转化为高效的词向量表达。

1. Word2Vec简介

Word2Vec是一种流行的词向量模型,最初由Tomas Mikolov等人于2013年提出。这个模型通过学习大量的文本语料库来构建词向量。Word2Vec模型有两种实现方式:连续词袋模型(CBOW)和Skip-Gram模型。

CBOW模型的目标是在给定一个词的上下文单词时,预测这个词本身。Skip-Gram模型则是给定一个词,预测它的上下文单词。具体来说,CBOW模型使用上下文单词的平均值作为输入来预测目标词,而Skip-Gram模型则使用目标词来预测其周围的上下文单词。

对于这两种模型,我们可以通过神经网络来进行训练。训练过程中,神经网络会学习到每个单词的向量表达,并将它们作为输出。这些向量可以被用来表示单词之间的相似性,例如计算余弦相似度。

虽然Word2Vec模型是一种强大的词向量模型,但它也有一些缺点。例如,它无法捕捉不同单词之间的复杂关系,如“女王”与“女孩”的关系。另外,Word2Vec模型通常需要较长的训练时间,因为需要遍历整个语料库多次。

2. Glove模型简介

Glove模型是一种基于全局向量的词向量模型,由Jeffrey Pennington、Richard Socher和Christopher D. Manning在2014年提出。Glove模型基于一个简单的直观想法:通过词与词之间的共现信息来学习它们的向量表示。

具体来说,Glove模型试图学习一组词向量,使得这些向量在点乘空间下对应的共现矩阵与实际共现矩阵的误差最小。这样的做法可以有效地捕捉不同单词之间的复杂关系,同时也可以减少训练时间,使得Glove模型在大规模数据集上具有很好的性能。

3. Glove模型原理

Glove模型的核心思想是通过词与词之间的共现信息来学习词向量。具体来说,Glove模型首先定义了一个共现矩阵XXX,其中XijX_{ij}Xij​表示单词iii和单词jjj在上下文中同时出现的次数。例如,如果语料库中的一句话为“the quick brown fox jumps over the lazy dog”,那么单词“the”和单词“quick”在上下文中同时出现的次数为1。

接下来,Glove模型试图学习一个词向量矩阵WWW,其中每一行对应一个单词的向量表示。同时,Glove模型还学习一个偏置向量bbb。通过这些参数,我们可以计算出每一对单词iii和jjj的点乘结果:

wiTwj+bi+bj=log⁡(Xij)w_i^Tw_j + b_i + b_j = \log(X_{ij})wiT​wj​+bi​+bj​=log(Xij​)

其中,log⁡(Xij)\log(X_{ij})log(Xij​)表示共现信息的对数值。这个公式表明,我们希望通过词向量和偏置项的线性组合来预测两个单词的共现信息。

为了最小化预测误差,Glove模型定义了以下目标函数:

J=∑i,j=1∣V∣f(Xij)(wiTwj+bi+bj−log⁡(Xij))2J = \sum_{i,j=1}^{|V|}f(X_{ij})(w_i^Tw_j + b_i + b_j - \log(X_{ij}))^2J=i,j=1∑∣V∣​f(Xij​)(wiT​wj​+bi​+bj​−log(Xij​))2

其中,∣V∣|V|∣V∣表示语料库中单词的总数,f(Xij)f(X_{ij})f(Xij​)是一个权重函数,用于平衡不同共现次数的影响。通常情况下,f(Xij)f(X_{ij})f(Xij​)可以设置为:

f(Xij)={(Xij/xmax)αif Xij(Xij​/xmax​)α​if Xij​

其中,xmaxx_{max}xmax​是一个阈值,α\alphaα是一个参数。这个权重函数的作用是对共现次数较多的单词进行惩罚,以防止它们在模型中占据过多的权重。

我们可以使用随机梯度下降等优化算法来最小化目标函数。在训练过程中,我们可以通过在共现矩阵中滑动一个固定大小的窗口来计算每个单词与其上下文单词之间的共现信息。

4. Glove模型与其他模型对比

在自然语言处理领域,除了Glove模型之外,还有许多其他词向量模型,例如FastText、ELMo和BERT等。下面,我们将Glove模型与这些模型进行对比。

(1)Word2Vec vs. Glove

与Word2Vec模型相比,Glove模型具有以下优势:

  • Glove模型可以捕捉单词之间的复杂关系,例如“女王”和“女孩”的关系。
  • Glove模型可以处理更大规模的数据集,并且训练时间更短。
  • Glove模型可以通过简单的矩阵分解方法来学习词向量,因此具有更好的可解释性。

然而,Glove模型也有一些缺点:

  • Glove模型对不同单词之间的相似性进行了平均化处理,因此在某些情况下可能无法捕捉到单词之间的微小差异。
  • Glove模型对于停用词等常见词汇可能无法提供准确的向量表示。

(2)FastText vs. Glove

FastText模型是一种基于字符级别的词向量模型,它可以在单词级别和子单词级别上学习向量表示。与Glove模型相比,FastText模型具有以下优势:

  • FastText模型可以处理未登录词,因为它可以将单词分解成字符级别的n-gram,并学习它们的向量表示。
  • FastText模型可以更好地捕捉单词内部的语义信息,例如单词的前缀和后缀。

然而,FastText模型也有一些缺点:

  • FastText模型的向量表示可能过于细粒度,无法很好地捕捉整个单词的含义。
  • FastText模型在处理较小的数据集时可能会出现过拟合现象。

(3)ELMo vs. Glove

ELMo模型是一种基于深度神经网络的词向量模型,可以学习上下文相关的词向量表示。与Glove模型相比,ELMo模型具有以下优势:

  • ELMo模型可以处理上下文相关的语义信息,因此可以更好地捕捉句子的含义。
  • ELMo模型可以应用于多种自然语言处理任务,例如命名实体识别和句子分类等。

然而,ELMo模型也有一些缺点:

  • ELMo模型需要大量的计算资源和数据来训练,因此训练时间可能较长。
  • ELMo模型对于每个输入单词都需要计算一次向量表示,因此在处理长文本时可能会变得非常缓慢。

(4)BERT vs. Glove

BERT模型是一种基于Transformer架构的预训练语言模型,可以在大规模语料库上学习上下文相关的词向量表示。与Glove模型相比,BERT模型具有以下优势:

  • BERT模型可以处理上下文相关的语义信息,因此可以更好地捕捉句子的含义。
  • BERT模型可以预训练,然后在各种自然语言处理任务中进行微调。

然而,BERT模型也有一些缺点:

  • BERT模型需要大量的计算资源和数据来训练,因此训练时间可能较长。
  • BERT模型在某些任务上可能过拟合,并且需要针对具体任务进行微调。

5. 代码实现

import numpy as npclass Glove:def __init__(self, learning_rate=0.05, num_epochs=50, window_size=10, embedding_size=100, x_max=100, alpha=0.75):self.learning_rate = learning_rateself.num_epochs = num_epochsself.window_size = window_sizeself.embedding_size = embedding_sizeself.x_max = x_maxself.alpha = alphadef build_vocab(self, corpus):self.word2id = {}self.id2word = {}for sentence in corpus:for word in sentence:if word not in self.word2id:id = len(self.word2id)self.word2id[word] = idself.id2word[id] = wordself.vocab_size = len(self.word2id)def build_cooccur_matrix(self, corpus):cooccur_matrix = np.zeros((self.vocab_size, self.vocab_size))for sentence in corpus:for i, center_word in enumerate(sentence):center_id = self.word2id[center_word]for j in range(max(0, i - self.window_size), i):context_word = sentence[j]context_id = self.word2id[context_word]distance = i - jweight = 1.0 / distancecooccur_matrix[center_id, context_id] += weightcooccur_matrix[context_id, center_id] += weightfor j in range(i + 1, min(len(sentence), i + self.window_size + 1)):context_word = sentence[j]context_id = self.word2id[context_word]distance = j - iweight = 1.0 / distancecooccur_matrix[center_id, context_id] += weightcooccur_matrix[context_id, center_id] += weightself.cooccur_matrix = cooccur_matrixdef train(self):self.embedding_matrix = np.random.uniform(-1, 1, (self.vocab_size, self.embedding_size))biases_1 = np.zeros(self.vocab_size)biases_2 = np.zeros(self.vocab_size)indices = np.nonzero(self.cooccur_matrix)weights = self.cooccur_matrix[indices]i_indices = indices[0]j_indices = indices[1]for epoch in range(self.num_epochs):for i, j, weight in zip(i_indices, j_indices, weights):x_ij = weightf_x_ij = (x_ij / self.x_max) ** self.alpha if x_ij < self.x_max else 1embedding_i = self.embedding_matrix[i, :]embedding_j = self.embedding_matrix[j, :]bias_i = biases_1[i]bias_j = biases_2[j]inner_product = np.dot(embedding_i, embedding_j)error = inner_product + bias_i + bias_j - np.log(x_ij)gradient_i = f_x_ij * error * embedding_jgradient_j = f_x_ij * error * embedding_ibias_gradient_i = f_x_ij * errorbias_gradient_j = f_x_ij * errorself.embedding_matrix[i, :] -= self.learning_rate * gradient_iself.embedding_matrix[j, :] -= self.learning_rate * gradient_jbiases_1[i] -= self.learning_rate * bias_gradient_ibiases_2[j] -= self.learning_rate * bias_gradient_jdef most_similar(self, word, k=10):word_id = self.word2id[word]word_vector = self.embedding_matrix[word_id, :]cosine_similarities = np.dot(self.embedding_matrix, word_vector) / (np.linalg.norm(self.embedding_matrix, axis=1) * np.linalg.norm(word_vector))most_similar_indices = cosine_similarities.argsort()[::-1][1:k+1]most_similar_words = [self.id2word[id] for id in most_similar_indices]return most_similar_words

在这里,我们首先定义了Glove类,包含了模型的参数和训练过程。在build_vocab方法中,我们将输入的语料库转换成单词id和单词之间的映射关系。在build_cooccur_matrix方法中,我们将输入的语料库转换成共现矩阵的形式。在train方法中,我们使用随机梯度下降算法来训练模型,并更新词向量和偏差。在most_similar方法中,我们使用余弦相似度来计算单词之间的相似性,并返回最相似的单词列表。

6. 总结

本篇博客介绍了Glove模型的原理和实现方法,并与其他词向量模型进行了对比。Glove模型通过联合矩阵分解的方法,将语料库中的词语和共现信息转化为高效的词向量表达。相对于其他模型,Glove模型可以更好地捕捉单词之间的复杂关系,同时也可以减少训练时间,使得在大规模数据集上具有很好的性能。

在实际应用中,我们需要根据具体的任务和数据集来选择最适合的词向量模型。未来,随着自然语言处理技术的不断发展,我们可以期待更加先进的词向量模型的出现,从而进一步提高自然语言处理的性能和效果。


❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️

👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博相关......)👈

相关内容

热门资讯

今日重大通报“宁波游戏大厅究竟... 亲.宁波游戏大厅这款游戏是可以开挂的,确实是有挂的,通过添加客服【4830828】很多玩家在这款游戏...
玩家实测“开心联盟牛牛其实有透... 您好:开心联盟牛牛这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在开心联...
最新一款.中州棋牌到底是不是挂... 最新一款.中州棋牌到底是不是挂.(原来真的有挂)亲.中州棋牌这款游戏是可以开挂的,确实是有挂的,通过...
今日重大消息“友乐趣游, 有没... 您好:友乐趣游,这款游戏可以开挂,确实是有挂的,需要了解加客服微信【3398215】很多玩家在这款游...
独家实测.威信娱乐究竟有挂吗.... 独家实测.威信娱乐究竟有挂吗.(详细开挂教程)亲,威信娱乐这个游戏其实有挂的,确实是有挂的,需要了解...