文章目录
- 一、背景
- 二、原理部分
- 1.共现矩阵
- 2. F值的获取
- 3. Glove公式的获取
- 4. 损失函数的获取
- 三、代码部分
- 1.词表映射
- 2. 词嵌入
- 3. 训练函数
- 4. 输出结果
- 总结
一、背景
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=k∑Xik(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(j∣i)=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
w∈Rd是词向量,
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(wi−wj,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((wi−wj)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((wi−wj)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=1∑Vf(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} wi、wk~、bi、bk~
输出结果:每个单词对对应的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} wi、wk~、bi、bk~;
- 设置超参数;
- 进行训练(计算损失函数,进行反向传播更像参数);
- 求和词嵌入矩阵与上下文嵌入矩阵,作为最终的预训练词向量,保存预训练词向量在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模型的训练,获得了词表中每个单词的预训练向量,为后续的基于预训练模型的学习奠定了基础。