在自然语言处理中,词嵌入是非常重要的技术,在[Pytorch基础二十三、(Word2Vec)](http://mp.weixin.qq.com/s?__biz=Mzg3NDIyMzI0Mw==&mid=2247484117&idx=1&sn=fa14b6d4e84f04b26a3189b7ac8664f0&chksm=ced54131f9a2c82743502a0da4e14a9cb8cc3c192e54f8fb4a66cc6e2466d36f71af55bfbf0e&scene=21#wechat_redirect)中介绍了word2vec,其实还有很多其他的算法,比如fasttext,glove。当然还有最新比较火的bert,ELMo,XLNet,ERNIE等等,其实词向量主要用在下游任务,比如文本分类,NER,机器翻译等等。下面介绍一些pytorch自带的自然语言处理包torchtext,https://github.com/pytorch/text
一、torchtext安装与基本操作
1.1、安装torchtext
pip install torchtext
1. 2、导入torchtext库
import torch
import torchtext.vocab as vocab
print(torch.__version__)
1.0.1.post2
1. 3、查看torchtext目前提供的预训练词嵌入名称
vocab.pretrained\_aliases.keys()
dict_keys(['charngram.100d', 'fasttext.en.300d', 'fasttext.simple.300d', 'glove.42B.300d', 'glove.840B.300d', 'glove.twitter.27B.25d', 'glove.twitter.27B.50d', 'glove.twitter.27B.100d', 'glove.twitter.27B.200d', 'glove.6B.50d', 'glove.6B.100d', 'glove.6B.200d', 'glove.6B.300d'])
1. 4、查看一下glove提供的预训练模型
[key for key in vocab.pretrained_aliases.keys()
if "glove" in key]
['glove.42B.300d',
'glove.840B.300d',
'glove.twitter.27B.25d',
'glove.twitter.27B.50d',
'glove.twitter.27B.100d',
'glove.twitter.27B.200d',
'glove.6B.50d',
'glove.6B.100d',
'glove.6B.200d',
'glove.6B.300d']
预训练的GloVe模型的命名规范大致是“模型.(数据集.)数据集词数.词向量维度”。
1. 5、下载预训练模型glove.6B.50d
cache_dir = "/Users/Datasets/glove"
# glove = vocab.pretrained_aliases["glove.6B.50d"](cache=cache_dir)
glove = vocab.GloVe(name='6B', dim=50, cache=cache_dir) # 与上面等价
返回的实例主要有以下三个属性:
stoi : 词到索引的字典:
itos : ⼀个列表,索引到词的映射;
vectors : 词向量。
1. 6、查看glove词表大小
print("一共包含%d个词。" % len(glove.stoi))
一共包含400000个词。
1. 7、我们可以通过词来获取它在词典中的索引,也可以通过索引获取词。
glove.stoi['beautiful'], glove.itos[3366]
(3366, 'beautiful')
二、应用预训练词向量
2.1、求近义词
def knn(W, x, k):
# 添加的1e-9是为了数值稳定性
cos = torch.matmul(W, x.view((-1,))) / (
(torch.sum(W * W, dim=1) + 1e-9).sqrt() * torch.sum(x * x).sqrt())
_, topk = torch.topk(cos, k=k)
topk = topk.cpu().numpy()
return topk, [cos[i].item() for i in topk]
def get_similar_tokens(query_token, k, embed):
topk, cos = knn(embed.vectors,
embed.vectors[embed.stoi[query_token]], k+1)
for i, c in zip(topk[1:], cos[1:]): # 除去输入词
print('cosine sim=%.3f: %s' % (c, (embed.itos[i])))
get\_similar\_tokens('chip', 3, glove)
cosine sim=0.856: chips
cosine sim=0.749: intel
cosine sim=0.749: electronics
2.2、求类比词
除了求近义词以外,我们还可以使⽤预训练词向量求词与词之间的类比关系。例如,“man”(男人): “woman”(⼥人):: “son”(⼉子) : “daughter”(⼥儿)是⼀个类⽐例子:“man”之 于“woman”相当于“son”之于“daughter”
def get_analogy(token_a, token_b, token_c, embed):
vecs = [embed.vectors[embed.stoi[t]]
for t in [token_a, token_b, token_c]]
x = vecs[1] - vecs[0] + vecs[2]
topk, cos = knn(embed.vectors, x, 1)
return embed.itos[topk[0]]
get\_analogy('man', 'woman', 'son', glove)
'daughter'
参考文献:
[1] GloVe 项⽬目⽹网站。 https://nlp.stanford.edu/projects/glove/
[2] fastText 项⽬目⽹网站。 https://fasttext.cc/