Glove模型的原理与代码


一、背景

 GloVe模型即Global Vectors模型,该模型认为语料库中单词出现的统计(共现矩阵) 是学习词向量表示的无监督学习算法的重要资料,但如何基于这些统计生成单词向量表示是一个难题,GloVe模型给出了一个答案,它利用全局(整个)语料库的统计信息来生成这个单词的向量表示
 在做单词的词嵌入表示方面,在2014年的时候主要有两种。一种是矩阵分解方法 (Matrix Factorization Methods),一种是基于浅窗口的方法(Shallow Window-Based Methods)。基于浅窗口的方法中的典型代表就是word2vec的方法,下文以简单的例子介绍矩阵分解方法。


二、原理部分

1.共现矩阵

给定数据集

1.  I like deep learning.
2.  I like NLP.
3.  I enjoy flying

共现矩阵
 考虑附近的一个单词,即窗口的大小为2,得到给定数据集的共现矩阵如下:

计数 I like enjoy deep learning NLP flying .
I 0 2 1 0 0 0 0 0
Iike 2 0 0 1 0 1 0 0
enjoy 1 0 0 0 0 0 1 0
deep 0 1 0 0 1 0 0 0
learning 0 0 0 1 0 0 0 1
NLP 0 1 0 0 0 0 0 1
flying 0 0 1 0 0 0 0 1
. 0 0 0 0 1 1 1 0

 有了这个矩阵,每个词的向量就可以表示出来了。如上表中I的向量表示就是 [0,2,1,0,0,0,0,0],但使用此矩阵去表示词向量存在问题。随着词汇的增多,向量的维度会变得很大,最终导致维度增高,需要大量存储空间,这也会导致向量变得稀疏,模型的鲁棒性变差。

2. F值的获取

 令 X i j X_{ij} Xij表示单词j出现在单词i上下文的次数,则获得任意单词出现在单词i的上下文次数之和 X i X_i Xi:
X i = ∑ k X i k (1) X_i=\sum _{k}X_{ik} \tag{1} Xi=kXik(1)
 从而获得单词j出现在单词i上的概率 P i j P_{ij} Pij:
P i j = P ( j ∣ i ) = P i j P i (2) P_{ij}=P(j|i)=\frac{P_{ij}}{P_{i}} \tag{2} Pij=P(ji)=PiPij(2)


例子:通过一个简单的例子来展示是如何从共现概率抽取出某种语义的,考虑两个单词i和j之间的某种特殊兴趣。 假设我们对热力学感兴趣,然后我们令i=ice和j=steam,两个单词之间的关系能通过研究它们基于不同单词k得到的共现矩阵概率之比来确定。令k=solid,我们期望Pik/Pjk的值很大;同理假设k=gas,我们期望Pik/Pjk的值很小;而对于那些与两者都相关或都不相关的单词比如k=water或k=fashion,Pik/Pjk的值应该接近1。如下表所示为在大语料库中计算的概率,与我们的期望很符合。

Probability and Ration k=solid k=gas k=water k=fashion
P(k|ice) 1.9×10e-4 6.6×10e-5 3.0×10e-3 1.7×10e-5
P(k|steam) 2.2×10e-5 7.8×10e-4 2.2×10e-3 1.8×10e-5
P(k|ice)/P(k|steam) 8.9 8.5×10e-2 1.36 0.96

 观察上式,注意到比值 P i k / P j k P_{ik}/P_{jk} Pik/Pjk依赖于3个单词i、j和k,那么常用的模型如下式:
F ( w i , w j , w k ~ ) = P i k P j k (3) F(w_i,w_j,\tilde{w_k})=\frac{P_{ik}}{P_{jk}} \tag{3} F(wi,wj,wk~)=PjkPik(3)
 上式中 w ∈ R d w\in R^d wRd是词向量, w ~ ∈ R d \tilde w\in R^d w~Rd是区分上下文词向量,然后F还可能依赖于现在未指定的参数,所以需要添加一些参数。

3. Glove公式的获取

 我们希望F能编码信息在词向量空间中表示比值 P i k / P j k P_{ik}/P_{jk} Pik/Pjk。因为向量空间是天然的线性结构,进行向量差计算是很自然的,基于此我们可以限制函数F只依赖于两个目标词的向量差,则上式变为:
F ( w i − w j , w k ~ ) = P i k P j k (4) F(w_i-w_j,\tilde{w_k})=\frac{P_{ik}}{P_{jk}}\tag{4} F(wiwj,wk~)=PjkPik(4)
 我们注意到上式中F 的参数是向量,而等式右边是标量。两者冲突,为了避免这个问题,尝试取这些参数的点积,从而让左边也变成标量,如下式所示:
F ( ( w i − w j ) T w k ~ ) = P i k P j k (5) F((w_i-w_j)^T\tilde{w_k})=\frac{P_{ik}}{P_{jk}} \tag{5} F((wiwj)Twk~)=PjkPik(5)
 注意到单词-单词的共现矩阵是对称的,即改变单词和上下文词位置得到的值是一样的,即 X i j = X j i X_{ij}=X_{ji} Xij=Xji。我们的最终模型应该在这转换下保持不变。要满足这种对称性,需要进行以下操作。将减法的函数变成除法的函数:
F ( ( w i − w j ) T w k ~ ) = F ( w i T w k ~ − w j T w k ~ ) = F ( w i T w k ~ ) F ( w j T w k ~ ) (6) F((w_i-w_j)^T\tilde{w_k})=F(w_i^T\tilde{w_k}-w_j^T\tilde{w_k}) =\frac{F(w_i^T\tilde{w_k})}{F(w_j^T\tilde{w_k})}\tag{6} F((wiwj)Twk~)=F(wiTwk~wjTwk~)=F(wjTwk~)F(wiTwk~)(6)
 参考(3)式可得:
F ( w i T w k ~ ) = P i k = X i k X i (7) F(w_i^T\tilde{w_k})=P_{ik}=\frac{X_{ik}}{X_i}\tag{7} F(wiTwk~)=Pik=XiXik(7)
 为了让(6)式成立,让F为指数函数,从而有:
w i T w k ~ = l o g ( P i k ) = l o g ( X i k ) − l o g ( X i ) (8) w_i^T\tilde{w_k}=log(P_{ik})=log(X_{ik})-log(X_{i})\tag{8} wiTwk~=log(Pik)=log(Xik)log(Xi)(8)
下面,我们注意到式(8)如果没有 l o g ( X i ) log(X_i) log(Xi)就会满足对称的可交换性。然而该项是与k独立的,所以它可以吸收到 w i w_i wi的偏差 b i b_i bi中,最终增加 w k ~ \tilde{w_k} wk~的偏差 b k ~ \tilde{b_k} bk~以保证可交换性。得到下面的等式:
w i T w k ~ + b i + b k ~ = l o g ( X i k ) (9) w_i^T\tilde{w_k}+b_i+\tilde{b_k}=log(X_{ik})\tag{9} wiTwk~+bi+bk~=log(Xik)(9)

4. 损失函数的获取

 如果把i和k对调,那么式(9)也成立。等式(9)是等式(3)的极大简化,但它实际上是有问题的,因为当它的参数为零时,对数就没发散了(log(0))。一种解决方案类似拉普拉斯平滑,即增加一个小偏移 l o g ( X i k ) → l o g ( X i k + 1 ) log(X_{ik})→log(X_{ik}+1) log(Xik)log(Xik+1),这样既维持了X的稀疏性,又避免对数发散。
 这样我们用词向量和偏差项表达了两个词共现的词频的对数,但是该模型的一个缺点是它将所有的共现概率看成平等的(即使那些很少共现的情况),这些稀有的共现情形可能是噪音或者携带的信息不多。
 我们希望等式(9)两边越接近越好,因此我们利用均方误差计算损失,并引入了权重函数 f ( X i j ) f(X_{ij}) f(Xij),如下式所示:
L = ∑ i , j = 1 V f ( X i j ) ( w i T w k ~ + b i + b k ~ − l o g ( X i k ) ) 2 (10) L=\sum_{i,j=1}^{V}f(X_{ij})(w_i^T\tilde{w_k}+b_i+\tilde{b_k}-log(X_{ik}))^2\tag{10} L=i,j=1Vf(Xij)(wiTwk~+bi+bk~log(Xik))2(10)
 上式中V是词典大小,权重函数 f ( X i j ) f(X_{ij}) f(Xij)定义如下:
f ( X w , c ) = { ( X w , c x m a x ) α , x < x m a x 1 , o t h e r w i s e (11) f(X_{w,c})= \begin{cases} (\frac{X_{w,c}}{x^{max}})^{\alpha}, x<x_{max}\\ 1, otherwise \end{cases} \tag{11} f(Xw,c)={ (xmaxXw,c)αx<xmax1,otherwise(11)
 模型的表现依赖于 x m a x x_{max} xmax的取值,在实验中取 x m a x = 100 x_{max}=100 xmax=100,作者发现 α \alpha α取3/4要优于取1时的线性函数。该模型生成两组词向量, W W W W ~ \tilde{W} W~,当X是对称的时候,这两组词向量是等价的,唯一不同的是它们随机初始化的结果;另一方面,有证据表明对于某些类型的神经网络,训练神经网络的多个实例,然后组合训练结果能有助于减少过拟合和噪声,通常也会改善结果。因此,作者采用 W + W ~ W+\tilde{W} W+W~之和作为词向量。
 利用词贡献矩阵来设计比值和损失函数来设计模型,从而构建词训练向量。

三、代码部分

文件构成:

在这里插入图片描述

文件获取
链接:https://pan.baidu.com/s/1nONl_XXPbJVwKpZLmDpf4A
提取码:1zvw

输入数据:用词嵌入层函数生成的词表中每个单词对应的64维词嵌入表示;

输入数据的标签:获取nltk中的Reuters数据处理模块中的所有句子(后文简称句子),并通过词表句子中各词汇对应的索引共现矩阵 获得共现矩阵作为输入数据的标签。

需要训练的参数:每个单词对应的64维词嵌入表示,即每个单词对应的 w i 、 w k ~ 、 b i 、 b k ~ w_i、\tilde{w_k}、b_i、\tilde{b_k} wiwk~bibk~

输出结果:每个单词对对应的64维嵌入式表示,在glove.vec文件中。

1.词表映射

完成功能

  • 完成创建词表(每一个词都有与之对应的索引值)的工作;
  • 根据词表,获得文章中每个句子中词汇所对应的索引值,根据输入文章建立idx_to_token、token_to_idx的词典。
  • 词表的其他操作。

实际代码
代码在vocab.py文件中:

from collections import defaultdict, Counter
class Vocab:
    def __init__(self, tokens=None):
        self.idx_to_token = list()  # 使用列表存储所有的标记,从而根据索引值获取相应的标记
        self.token_to_idx = dict()  # 使用字典实现标记到索引的映射

        if tokens is not None:
            if "<unk>" not in tokens:
                tokens = tokens + ["<unk>"]
            for token in tokens:
                self.idx_to_token.append(token) #获取id_to_token
                self.token_to_idx[token] = len(self.idx_to_token) - 1 # h获取token_to_id
            self.unk = self.token_to_idx['<unk>']

    @classmethod
    # 创建词表、输入的text包含若干句子,每个句子由若干标记构成
    def build(cls, text, min_freq=1, reserved_tokens=None):
        token_freqs = defaultdict(int)  # 存储标记及其出现次数的映射字典
        for sentence in text:
            for token in sentence: # 统计词频
                token_freqs[token] += 1
        # 无重复的标记,其中预留了未登录词汇(Unknown word)标记(<unk>)以及若干
        # 用户自定义的预留标记
        uniq_tokens = ["<unk>"] + (reserved_tokens if reserved_tokens else [])
        uniq_tokens += [token for token, freq in token_freqs.items() if freq >= min_freq and token != "<unk>"]
        return cls(uniq_tokens)

    # 返回词表的大小,即词表中有多少个互不相同的标记
    def __len__(self):
        return len(self.idx_to_token)

    # 查找输入标记对应的索引值,如果该标记不存在,则返回标记<unk>的索引值0
    def __getitem__(self, token):
        return self.token_to_idx.get(token, self.unk)

    # 查找一系输入标记对应的索引值
    def convert_tokens_to_ids(self, tokens):
        return [self[token] for token in tokens]

    #  查找一系列索引值对应的标记
    def convert_ids_to_tokens(self, indices):
        return [self.idx_to_token[index] for index in indices]


def save_vocab(vocab, path):
    with open(path, 'w') as writer:
        writer.write("\n".join(vocab.idx_to_token))


def read_vocab(path):
    with open(path, 'r') as f:
        tokens = f.read().split('\n')
    return Vocab(tokens)

2. 词嵌入

完成功能

  • 根据输入文章,衔接词表映射部分;
  • 初始化、建立、加载、保存单词序列表示到词嵌入向量表示的相关操作。

代码实现
代码在utils.py文件中:

import torch
from torch.utils.data import DataLoader, Dataset, TensorDataset
from vocab import Vocab
from nltk.corpus import reuters  # 从nltk中导入Reuters数据处理模块


# Constants
BOS_TOKEN = "<bos>"  # 句首标记
EOS_TOKEN = "<eos>"  # 句尾标记
PAD_TOKEN = "<pad>"  # 补齐序列长度的标记
BOW_TOKEN = "<bow>"
EOW_TOKEN = "<eow>"

WEIGHT_INIT_RANGE = 0.1


def load_reuters():
    text = reuters.sents()  # 获取Reuters数据中的所有句子(已完成标记解析)
    text = [[word.lower() for word in sentence]
            for sentence in text]  # 将语料中的词转换为小写(可选)
    # 构建词表,并传入预留标记,包括idx_to_token、token_to_idx
    vocab = Vocab.build(text, reserved_tokens=[
                        PAD_TOKEN, BOS_TOKEN, EOS_TOKEN])  # 构建词表,并传入预留标记,包括idx_to_token、token_to_idx
    # 找出文本中每一个句子中单词所对应的序列
    corpus = [vocab.convert_tokens_to_ids(
        sentence) for sentence in text]  # 利用词表将文本数据转换为id表示

    return corpus, vocab


def save_pretrained(vocab, embeds, save_path):
    with open(save_path, "w") as writer:
        #记录词表大小
        writer.write(f"{
      
      embeds.shape[0]} {
      
      embeds.shape[1]}\n")
        for idx, token in enumerate(vocab.idx_to_token):
            vec = " ".join(["{:.4f}".format(x) for x in embeds[idx]])
            #每一行对应一个单词以及由空格分隔的词向量
            writer.write(f"{
      
      token} {
      
      vec}\n")
    print(f"Pretrained embeddings saved to:{
      
      save_path}")


def load_pretrained(load_path):
    with open(load_path, "r") as fin:
        n, d = map(int, fin.readline().split())
        tokens = []
        embeds = []
        for line in fin:
            line = line.rstrip().split(' ')
            token, embeds = line[0], list(map(float, line[1:]))
            tokens.append(token)
            embeds.append(embeds)
        vocab = Vocab(tokens)
        embeds = torch.tensor(embeds, dtype=torch.float)
    return vocab, embeds


def get_loader(dataset, batch_size, shuffle=True):
    data_loader = DataLoader(
        dataset,
        batch_size=batch_size,
        collate_fn=dataset.collate_fn,
        shuffle=shuffle  # 打乱数据顺序
    )
    return data_loader


def init_weights(model):
    for name, param in model.named_parameters():
        # print("------------------------------------------------------")
        # print("model.named_parameters()",model.named_parameters())
        if "embedding" not in name:
            torch.nn.init.uniform_(
                param, a=-WEIGHT_INIT_RANGE, b=WEIGHT_INIT_RANGE)

3. 训练函数

完成功能

  • 构建Glove的数据标签——共现矩阵;
  • 构建Glove模型——随机生成每个单词对应的 w i 、 w k ~ 、 b i 、 b k ~ w_i、\tilde{w_k}、b_i、\tilde{b_k} wiwk~bibk~
  • 设置超参数;
  • 进行训练(计算损失函数,进行反向传播更像参数);
  • 求和词嵌入矩阵与上下文嵌入矩阵,作为最终的预训练词向量,保存预训练词向量在glove.vec文件中
    代码实现
    代码在train.py文件中:
# Defined in Section 5.3.4
# 0.导入相关的包
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import Dataset
from torch.nn.utils.rnn import pad_sequence
from tqdm.auto import tqdm  # 进度条
from utils import BOS_TOKEN, EOS_TOKEN, PAD_TOKEN
from utils import load_reuters, save_pretrained, get_loader, init_weights
from collections import defaultdict
# 1.构建数据集
class GloveDataset(Dataset):
    # 构建共现矩阵
    def __init__(self, corpus, vocab, context_size=2):
        # 记录词与上下文在给定语料中的共现次数
        self.cooccur_counts = defaultdict(float)
        self.bos = vocab[BOS_TOKEN] # 句首标志
        self.eos = vocab[EOS_TOKEN] # 句尾标志
        for sentence in tqdm(corpus, desc="Dataset Construction"):
            sentence = [self.bos] + sentence + [self.eos] # 给每个句子添加首尾标志
            for i in range(1, len(sentence)-1):
                w = sentence[i]
                left_contexts = sentence[max(0, i - context_size):i]
                right_contexts = sentence[i+1:min(len(sentence), i + context_size)+1]
                # 共现次数随距离衰减: 1/d(w, c)
                for k, c in enumerate(left_contexts[::-1]):
                    self.cooccur_counts[(w, c)] += 1 / (k + 1)
                for k, c in enumerate(right_contexts):
                    self.cooccur_counts[(w, c)] += 1 / (k + 1)
        self.data = [(w, c, count) for (w, c), count in self.cooccur_counts.items()]


    def __len__(self):
        return len(self.data)

    def __getitem__(self, i):
        return self.data[i]

    def collate_fn(self, examples):
        words = torch.tensor([ex[0] for ex in examples])
        contexts = torch.tensor([ex[1] for ex in examples])
        counts = torch.tensor([ex[2] for ex in examples])
        return (words, contexts, counts)
# 2.构建模型
class GloveModel(nn.Module):
    def __init__(self, vocab_size, embedding_dim):
        super(GloveModel, self).__init__()
        # 词嵌入及偏置向量
        self.w_embeddings = nn.Embedding(vocab_size, embedding_dim)
        self.w_biases = nn.Embedding(vocab_size, 1)
        # 上下文嵌入及偏置向量
        self.c_embeddings = nn.Embedding(vocab_size, embedding_dim)
        self.c_biases = nn.Embedding(vocab_size, 1)

    def forward_w(self, words):
        w_embeds = self.w_embeddings(words)
        w_biases = self.w_biases(words)
        return w_embeds, w_biases

    def forward_c(self, contexts):
        c_embeds = self.c_embeddings(contexts)
        c_biases = self.c_biases(contexts)
        return c_embeds, c_biases
# 3. 进行训练
embedding_dim = 64
context_size = 2
batch_size = 1024
num_epoch = 10

# 用以控制样本权重的超参数
m_max = 100
alpha = 0.75
# 从文本数据中构建GloVe训练数据集
corpus, vocab = load_reuters() # 获得文本中句子的各个单词对应的id以及词表(包括id_to_token、token_to_id)
# 获得共现矩阵,格式为(i,j,Xij)
dataset = GloveDataset(
    corpus,
    vocab,
    context_size=context_size
)
# 获取数据
data_loader = get_loader(dataset, batch_size)


device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GloveModel(len(vocab), embedding_dim)
model.to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)

model.train()
for epoch in range(num_epoch):
    total_loss = 0
    for batch in tqdm(data_loader, desc=f"Training Epoch {
      
      epoch}"):
        words, contexts, counts = [x.to(device) for x in batch]
        # 提取batch内词、上下文的向量表示及偏置
        word_embeds, word_biases = model.forward_w(words)
        context_embeds, context_biases = model.forward_c(contexts)
        # 回归目标值:必要时可以使用log(counts+1)进行平滑
        log_counts = torch.log(counts)
        # 样本权重
        weight_factor = torch.clamp(torch.pow(counts / m_max, alpha), max=1.0)
        optimizer.zero_grad()
        # 计算batch内每个样本的L2损失
        loss = (torch.sum(word_embeds * context_embeds, dim=1) + word_biases + context_biases - log_counts) ** 2
        # 样本加权损失
        wavg_loss = (weight_factor * loss).mean()
        wavg_loss.backward()
        optimizer.step()
        total_loss += wavg_loss.item()
    print(f"Loss: {
      
      total_loss:.2f}")

# 合并词嵌入矩阵与上下文嵌入矩阵,作为最终的预训练词向量
combined_embeds = model.w_embeddings.weight + model.c_embeddings.weight
save_pretrained(vocab, combined_embeds.data, "glove.vec")

4. 输出结果

查看输出结果——glove.vec文件的前10行,可以看出该词汇表中包含31081个词汇,每个词汇都用一个维度为64的向量表示。

31081 64
<unk> -0.4085 0.8987 0.7059 0.7185 0.9490 -0.0561 2.8609 -0.7485 -1.8053 2.1793 -2.4878 0.0345 -0.1757 -1.0810 2.1173 0.2526 1.3901 2.1672 -0.1088 0.0411 -0.8595 0.4096 1.2418 -0.4485 -1.0148 -0.7377 0.9641 0.0876 -0.3041 -1.0965 -0.8752 1.1737 0.8401 0.3029 -1.5457 -0.9569 2.7822 2.3788 -0.0764 1.1274 1.7693 -0.3070 -0.9756 -0.6645 0.2116 0.1810 -2.4117 0.8760 0.0885 1.5944 -0.7053 -2.4556 1.0691 -0.0498 -1.8511 -1.6034 -1.0854 -1.1143 -0.9923 -1.6857 -0.4288 -0.1488 -2.7060 1.7940
<pad> -0.8651 -1.4205 0.1538 0.8596 1.2616 2.0623 -0.0754 -3.0511 -0.2593 3.5522 -0.3786 0.1582 -0.8871 0.5294 1.0323 0.3120 0.1401 0.1791 -0.0731 -1.2885 0.4815 -0.2397 -2.4249 -1.6040 -1.2258 -1.3283 2.0739 -2.6558 -0.0550 -0.6551 2.2865 -0.5187 1.3293 -0.7430 -1.2599 2.2371 -0.0043 -1.3675 0.4349 0.9450 1.8032 1.3498 -1.6710 -1.9188 1.1731 -1.6169 1.0894 2.5721 1.3433 -0.0291 0.7335 0.3176 -0.7047 1.0760 -2.0114 -0.6320 -0.8257 0.1365 0.6683 -0.1208 0.3386 0.7058 -2.0128 -1.1558
<bos> 0.8375 1.0491 1.0586 0.7123 0.6173 1.5974 0.6996 -0.7708 -0.8275 -0.4097 1.2857 1.5608 -1.4125 -0.9450 1.2393 1.4405 3.1632 -0.1669 -0.6690 -0.7283 -3.1852 -0.9773 -0.5971 1.3336 0.1704 1.4336 -0.3655 -0.4922 -0.3136 0.3780 -0.8888 -1.0120 -0.0238 -0.2521 1.3591 -1.7552 -0.4077 -1.5118 -1.4096 1.1173 -1.9888 0.3899 1.8854 -1.1858 -1.8155 0.8776 -0.1199 0.3856 -1.3803 -1.3327 -1.1912 0.2297 -0.5097 -0.6247 -1.0207 -0.3741 -1.6244 -0.4947 0.7122 -1.2210 -0.8188 -2.1322 -0.3603 -1.6456
<eos> -0.5236 -1.4939 -0.2992 0.2372 -0.4128 -1.0130 0.1224 0.4514 -0.1113 -0.1326 -0.4931 -0.6550 -0.2787 -0.1797 1.3713 0.7784 -1.0101 1.6711 0.0735 1.0077 -0.9487 1.1664 1.1180 0.6614 1.4972 2.1433 -0.4960 -0.2498 1.4693 2.4584 0.1520 0.3418 1.0970 -0.0842 1.3505 0.3414 0.0706 1.7857 -0.8231 -1.9785 -0.0890 -1.7407 0.7638 -1.0670 -1.2944 0.9511 -0.9706 -1.2764 0.3585 -0.0910 0.1407 -0.6052 0.9690 0.0972 -0.6491 -0.2324 0.9503 -0.5575 -0.2425 0.0733 -0.6119 -1.5401 -1.3110 -0.6490
asian 0.4405 0.4520 -0.7834 -0.4270 -0.6023 -0.8673 0.2736 1.2317 -0.1891 0.7490 -0.9570 1.6441 -0.3157 0.2430 -1.0691 -1.0251 -0.1034 0.2524 0.6864 -1.7021 -0.3312 -1.1372 0.1041 0.3926 -0.1056 1.7013 1.3913 -0.8130 0.4417 0.1841 0.8766 1.0558 -2.3248 0.4372 -0.9351 -0.7902 -0.3110 -0.4279 0.2044 -0.6004 0.6137 -1.5871 -0.0144 0.8195 0.2291 -2.5306 -1.3012 -1.9574 1.3367 0.3883 -0.8562 0.3859 -0.1099 -1.5851 -1.1978 0.5488 0.0449 0.1612 0.0356 -0.3480 -0.2186 0.4304 0.7294 0.4923
exporters 0.0840 -0.9613 0.2720 1.6380 0.5373 -0.0336 -2.7280 -0.0487 -0.5931 0.9054 0.2349 -0.3953 -0.1489 -1.5672 1.2424 0.5670 -0.0946 -0.5283 1.1217 -0.7045 0.4312 -0.3768 0.4174 0.5587 -0.9715 0.4640 -0.4097 1.1417 -0.3601 -0.2703 -0.5120 -0.2322 -0.4222 -0.5467 -0.6012 1.1019 0.7490 0.2103 -0.6741 0.2142 -0.3330 1.5998 -0.3308 -0.9017 -0.7634 -0.6371 -1.3426 -0.3131 0.2103 -0.4185 -0.5146 -0.1345 -1.6099 0.1236 -0.7250 -1.6605 0.4145 -0.2883 -1.4757 -0.2841 -0.0695 1.0867 -2.1164 -1.5033
fear 0.6053 -1.3619 -1.1394 0.6564 -0.6681 0.4316 0.5249 -0.8856 1.6624 -0.8638 0.4759 -1.2574 1.5907 0.5267 1.9173 1.9248 0.1725 2.2849 -1.8490 1.0726 -1.9933 1.6526 -0.5451 -2.4535 2.2571 -0.5513 0.2169 -2.5283 -0.6891 -0.6629 -0.4507 -2.3457 1.0951 0.2181 1.2726 1.5696 0.1705 -0.1639 3.5436 -0.5956 -0.1075 2.3517 1.3718 0.6459 1.9080 -1.2858 1.5629 -1.0341 -0.1488 0.8437 0.0782 0.5239 -0.7100 -1.7051 -0.4746 0.3000 1.6840 -0.1448 0.7242 -0.7754 -1.2053 0.3618 0.8861 -0.1127
damage -0.5377 0.7230 1.1688 1.0622 -1.1178 -1.2865 0.5395 -0.3287 -1.2611 -0.6243 -0.8019 -0.8632 -0.9318 -0.0488 -0.1017 -0.3548 -0.3201 1.4771 1.2074 0.2899 1.3337 1.7881 0.0078 0.2031 0.2655 -1.5270 0.4358 -1.4903 1.0678 -1.4593 -1.2401 0.2522 0.4696 -1.6459 -0.6612 0.8361 0.7920 -0.3588 -1.0676 -0.4648 1.6891 0.8083 0.0524 -0.1956 -0.6889 1.4710 0.8635 -1.2285 1.0868 -0.0265 -0.4927 -0.4698 -1.0656 0.5271 -1.2145 1.2974 -0.9155 0.3161 1.6806 0.7144 2.4944 -0.1253 0.3875 -0.6805
from 0.6597 -0.3975 0.0937 -0.5497 -0.0910 0.3402 0.1203 0.1770 0.0102 -0.0932 -0.2123 0.5183 0.1500 0.1804 0.6875 0.7291 -0.0214 -0.5352 -0.0097 0.3185 -0.0407 -0.5585 0.6052 -0.6745 0.1689 0.6893 0.0002 -0.2718 0.3238 0.2101 1.1889 -0.5163 -0.1644 -0.8906 0.2868 -0.3394 -0.1351 0.2338 -0.7605 0.6383 0.4410 0.2914 -0.0760 -0.0911 -0.1914 0.9026 -0.1548 -0.1500 -0.0221 -0.2595 0.4880 -0.6256 -0.1206 0.0327 -0.4932 0.5348 0.2539 -0.0097 0.1378 0.7407 0.0558 -0.4919 0.0275 0.4378


总结

本文介绍了Glove的基本原理,借助nltk中的Reuters数据处理模块中的所有句子用代码实现了Glove模型的训练,获得了词表中每个单词的预训练向量,为后续的基于预训练模型的学习奠定了基础。

猜你喜欢

转载自blog.csdn.net/qq_40940944/article/details/128294478
今日推荐