基于Python的自然语言处理系列(3):GloVe

        在自然语言处理(NLP)领域,GloVe(Global Vectors for Word Representation)是一种有效的词向量表示方法,与Word2Vec相辅相成。GloVe通过构建词汇的全局共现统计量来生成词向量,这使得它在捕捉词汇之间的语义关系方面非常有效。本篇文章将详细介绍GloVe模型的原理、实现方法及应用场景。

1. GloVe 原理

1.1 GloVe的背景

        GloVe模型由Jeffrey Pennington等人在2014年提出。与Word2Vec的局部上下文窗口方法不同,GloVe通过分析整个语料库中词汇的全局共现信息来生成词向量。其核心思想是:词与词之间的共现概率矩阵可以有效地揭示它们之间的语义关系。

1.2 GloVe的工作原理

        GloVe模型的基本步骤包括:

  1. 构建词汇的共现矩阵:统计每对词汇在语料库中共同出现的次数。
  2. 计算词对的共现概率:根据共现矩阵计算每对词的共现概率。
  3. 优化目标函数:通过最小化词对之间的差异,来学习词向量,使得词向量的内积能够近似共现概率。

2. GloVe 实现

2.1 定义简单数据集

        我们使用一个简单的语料库来演示GloVe模型的实现。

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
from collections import Counter

# 定义语料库
corpus = ["apple banana fruit", "banana apple fruit", "banana fruit apple",
          "dog cat animal", "cat animal dog", "cat dog animal"]

corpus = [sent.split(" ") for sent in corpus]
print(corpus)

2.2 数据预处理

        获取词序列和唯一词汇,并进行数值化处理。

# 获取词序列和唯一词汇
flatten = lambda l: [item for sublist in l for item in sublist]
vocab = list(set(flatten(corpus)))
print(vocab)

# 数值化处理
word2index = {w: i for i, w in enumerate(vocab)}
print(word2index)

# 词汇表大小
voc_size = len(vocab)
print(voc_size)

# 添加UNK标记
vocab.append('<UNK>')
word2index['<UNK>'] = len(word2index)
index2word = {v: k for k, v in word2index.items()}
print(vocab)

2.3 构建共现矩阵

        我们需要统计每对词汇在给定窗口大小内的共现次数。

from collections import defaultdict

window_size = 1
co_occurrence_matrix = defaultdict(lambda: defaultdict(int))

for sentence in corpus:
    for i, target in enumerate(sentence):
        context = [sentence[j] for j in range(max(0, i - window_size), min(len(sentence), i + window_size + 1)) if j != i]
        for ctx in context:
            co_occurrence_matrix[target][ctx] += 1

# 将共现矩阵转化为NumPy数组
def build_co_occurrence_matrix(word2index, co_occurrence_matrix):
    matrix = np.zeros((len(word2index), len(word2index)))
    for word1 in co_occurrence_matrix:
        for word2 in co_occurrence_matrix[word1]:
            matrix[word2index[word1], word2index[word2]] = co_occurrence_matrix[word1][word2]
    return matrix

co_occurrence_matrix_np = build_co_occurrence_matrix(word2index, co_occurrence_matrix)
print(co_occurrence_matrix_np)

2.4 GloVe模型训练

        GloVe的训练过程包括定义模型、损失函数,并通过优化算法来训练模型。

class GloVe(nn.Module):
    def __init__(self, vocab_size, embedding_dim, alpha=0.75, x_max=100):
        super(GloVe, self).__init__()
        self.alpha = alpha
        self.x_max = x_max
        self.embedding_dim = embedding_dim
        
        self.W = nn.Embedding(vocab_size, embedding_dim)
        self.W_out = nn.Embedding(vocab_size, embedding_dim)

    def forward(self, target, context, co_occurrence):
        target_emb = self.W(target)
        context_emb = self.W_out(context)
        dot_product = torch.sum(target_emb * context_emb, dim=1)
        return torch.mean((dot_product - torch.log(co_occurrence + 1e-10)) ** 2)

# 初始化模型
embedding_dim = 50
model = GloVe(voc_size, embedding_dim)
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 构建训练数据
def generate_training_data(co_occurrence_matrix_np):
    target = []
    context = []
    co_occurrence = []
    for i, word1 in enumerate(vocab):
        for j, word2 in enumerate(vocab):
            if co_occurrence_matrix_np[i, j] > 0:
                target.append(i)
                context.append(j)
                co_occurrence.append(co_occurrence_matrix_np[i, j])
    return torch.LongTensor(target), torch.LongTensor(context), torch.FloatTensor(co_occurrence)

target, context, co_occurrence = generate_training_data(co_occurrence_matrix_np)

# 训练模型
epochs = 10
for epoch in range(epochs):
    model.train()
    optimizer.zero_grad()
    loss = model(target, context, co_occurrence)
    loss.backward()
    optimizer.step()
    print(f'Epoch {epoch + 1}/{epochs}, Loss: {loss.item()}')

2.5 可视化结果

        训练完成后,我们可以通过可视化来检查词向量的效果。

def plot_embeddings(model, vocab, index2word):
    embeddings = model.W.weight.data.numpy()
    plt.figure(figsize=(10, 10))
    for i, word in enumerate(vocab):
        plt.scatter(embeddings[i, 0], embeddings[i, 1])
        plt.text(embeddings[i, 0], embeddings[i, 1], word, fontsize=9)
    plt.xlabel('Dimension 1')
    plt.ylabel('Dimension 2')
    plt.title('Word Embeddings')
    plt.show()

plot_embeddings(model, vocab, index2word)

结语

        在本篇文章中,我们详细介绍了GloVe模型的原理和实现过程。通过实现GloVe模型,我们能够生成高质量的词向量,这些词向量在许多NLP任务中具有广泛的应用。在下一篇文章中,我们将探讨GloVe的改进和应用,包括如何在实际任务中有效利用这些词向量。敬请期待!

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的Anthony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值