人工智能必知必会-词向量(案例)

学了好久的向量和矩阵,有小伙伴问我,这xx玩意学着有啥用啊?能吃吗?不能吃不学了!
好好好,同学先别激动。今天咱们就先不讲理论,讲点有趣的工程落地,来满足你的好奇心,让你爽一下再继续前行!

本文中的代码看不懂也没关系,只需要看懂人话就行了!那正式开始了!

beijing:china, tokyo:?

首先提出问题,beijing和china的关系,相当于tokyo和谁的关系?
就算不进行任何计算你也会脱口而出,是japan。这背后的逻辑可以通过深度学习,被人工智能所掌握到!
这又和我们之前学的向量有啥关系呢?听我慢慢道来!

加载词向量

import torch
import torchtext
from torchtext import vocab
gv = torchtext.vocab.GloVe(name='6B', dim=50)

我们加载预先训练好的Glove词向量。简单说就是有人已经把每个英文单词对应成一个向量了。这个过程有兴趣我以后再细节给你讲,今天你只需要加载,拿过来用就可以了。
保证你的网速和磁盘空间,这个词向量有点大862M

len(gv.vectors), gv.vectors.shape

输出:

(400000, torch.Size([400000, 50]))

这意味着我们的词向量里面包含了400000个词,每个词用50个维度来表示。

使用词向量

假设我们要看tokyo这个词的词向量是多少,就可以这样操作

gv.stoi['tokyo']

输出:

1363

这个1363就是tokyo在gv词向量中的索引,接下来就可以

gv.vectors[1363]

输出:

tensor([-0.3117,  0.1947,  0.1908,  0.6841,  0.2916, -0.8988,  0.2263,  0.1783,
        -1.4774, -0.0919,  0.0898, -0.9447, -0.1938,  0.5808,  0.2021,  0.9924,
        -1.0311,  0.4247, -1.1420,  0.7197,  2.1561, -0.1420, -0.9298, -0.2810,
        -0.0110, -1.6787,  0.4445,  0.5470, -0.7136, -0.6774,  2.3393,  0.2858,
         1.4062, -0.0078, -0.1528, -1.1147,  0.2415, -0.6591, -0.0449,  0.0468,
        -1.1396, -0.4484,  0.9181, -0.7405,  1.0508,  0.0527,  0.1343,  0.6226,
         0.6138, -0.0973])

什么的词向量就长成这个样子!真丑~

你还可以通过itos把坐标映射回单词

gv.itos[1363]

输出:

'tokyo'

近似词

怎么衡量两个向量是否相似,你还记得吗?
对,距离和角度都可以。我们今天就是用距离,如果两个向量距离越小,代表他们约相似,对吧。同样,如果两个词向量见的距离越小,那就代表某种意义上,他们意义相近。

def get_wv(word):
    return gv.vectors[gv.stoi[word]]
get_wv('tokyo')

输出:

tensor([-0.3117,  0.1947,  0.1908,  0.6841,  0.2916, -0.8988,  0.2263,  0.1783,
        -1.4774, -0.0919,  0.0898, -0.9447, -0.1938,  0.5808,  0.2021,  0.9924,
        -1.0311,  0.4247, -1.1420,  0.7197,  2.1561, -0.1420, -0.9298, -0.2810,
        -0.0110, -1.6787,  0.4445,  0.5470, -0.7136, -0.6774,  2.3393,  0.2858,
         1.4062, -0.0078, -0.1528, -1.1147,  0.2415, -0.6591, -0.0449,  0.0468,
        -1.1396, -0.4484,  0.9181, -0.7405,  1.0508,  0.0527,  0.1343,  0.6226,
         0.6138, -0.0973])

ok,接下来我们就把tokyo转化成词向量,去遍历所有的词,然后找到和它距离最近的10个

def sim_10(word, n=10):
    all_dists = [(gv.itos[i],  torch.dist(word, w) )for i, w in enumerate(gv.vectors)]
    return sorted(all_dists, key=lambda t: t[1])[:n]

sim_10(get_wv('tokyo'))

输出:

[('tokyo', tensor(0.)),
 ('osaka', tensor(3.2893)),
 ('seoul', tensor(3.3802)),
 ('shanghai', tensor(3.6196)),
 ('japan', tensor(3.6599)),
 ('japanese', tensor(4.0788)),
 ('singapore', tensor(4.1160)),
 ('beijing', tensor(4.2423)),
 ('taipei', tensor(4.2454)),
 ('bangkok', tensor(4.2459))]

和我们预想的差不多,都是一些大都市。另外tokyo自然和tokyo本身距离最近为0,所以第一个输出的是tokyo。

w2 - w1 = w4 - w3

ok,最后的一步就是用这个暴力的数学公式解决问题,他的意义就是china - beijing = ? - tokyo:
有了这个公式接下来就是一个向量加减操作了

def analogy(w1, w2, w3, n=5, filter_given=True):
    print('\n[%s : %s :: %s : ?]' % (w1, w2, w3))

    # w2 - w1 + w3 = w4
    closest_words = sim_10(get_wv(w2) - get_wv(w1) + get_wv(w3))

    # 过滤防止输入参数出现在结果中
    if filter_given:
        closest_words = [t for t in closest_words if t[0] not in [w1, w2, w3]]
    print(closest_words[:2])
analogy('beijing', 'china', 'tokyo')

输出:

[beijing : china :: tokyo : ?]
[('japan', tensor(2.7869)), ('japanese', tensor(3.6377))]

向量带给你新的观察世界的视角!

目录:
人工智能必知必会-前言
人工智能必知必会-标量,向量,矩阵,张量
人工智能必知必会-向量的加减与缩放
人工智能必知必会-向量的内积
人工智能必知必会-向量之间的距离
人工智能必知必会-初识矩阵
人工智能必知必会-矩阵与向量
人工智能必知必会-矩阵的加减法
人工智能必知必会-矩阵乘法
人工智能必知必会-矩阵与方程组
人工智能必知必会-再看矩阵与向量
人工智能必知必会-矩阵与向量乘法的物理意义
人工智能必知必会-词向量(案例)
人工智能必知必会-矩阵相乘上

人工智能必知必会-矩阵相乘下

你可能感兴趣的:(人工智能必知必会-词向量(案例))