从Word2Vec到Glove |
您所在的位置:网站首页 › 词向量字典 › 从Word2Vec到Glove |
❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️
👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博相关......)👈
(封面图由文心一格生成)
从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模型首先定义了一个共现矩阵 X X X,其中 X i j X_{ij} Xij表示单词 i i i和单词 j j j在上下文中同时出现的次数。例如,如果语料库中的一句话为“the quick brown fox jumps over the lazy dog”,那么单词“the”和单词“quick”在上下文中同时出现的次数为1。 接下来,Glove模型试图学习一个词向量矩阵 W W W,其中每一行对应一个单词的向量表示。同时,Glove模型还学习一个偏置向量 b b b。通过这些参数,我们可以计算出每一对单词 i i i和 j j j的点乘结果: w i T w j + b i + b j = log ( X i j ) w_i^Tw_j + b_i + b_j = \log(X_{ij}) wiTwj+bi+bj=log(Xij) 其中, log ( X i j ) \log(X_{ij}) log(Xij)表示共现信息的对数值。这个公式表明,我们希望通过词向量和偏置项的线性组合来预测两个单词的共现信息。 为了最小化预测误差,Glove模型定义了以下目标函数: J = ∑ i , j = 1 ∣ V ∣ f ( X i j ) ( w i T w j + b i + b j − log ( X i j ) ) 2 J = \sum_{i,j=1}^{|V|}f(X_{ij})(w_i^Tw_j + b_i + b_j - \log(X_{ij}))^2 J=i,j=1∑∣V∣f(Xij)(wiTwj+bi+bj−log(Xij))2 其中, ∣ V ∣ |V| ∣V∣表示语料库中单词的总数, f ( X i j ) f(X_{ij}) f(Xij)是一个权重函数,用于平衡不同共现次数的影响。通常情况下, f ( X i j ) f(X_{ij}) f(Xij)可以设置为: f ( X i j ) = { ( X i j / x m a x ) α if X i j < x m a x 1 otherwise f(X_{ij}) = \begin{cases} (X_{ij}/x_{max})^\alpha & \text{if } X_{ij} < x_{max} \ 1 & \text{otherwise} \end{cases} f(Xij)={(Xij/xmax)αif Xij} for sentence in corpus: for word in sentence: if word not in self.word2id: id = len(self.word2id) self.word2id[word] = id self.id2word[id] = word self.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 - j weight = 1.0 / distance cooccur_matrix[center_id, context_id] += weight cooccur_matrix[context_id, center_id] += weight for 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 - i weight = 1.0 / distance cooccur_matrix[center_id, context_id] += weight cooccur_matrix[context_id, center_id] += weight self.cooccur_matrix = cooccur_matrix def 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 = weight f_x_ij = (x_ij / self.x_max) ** self.alpha if x_ij |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |