当前位置:   article > 正文

一文搞懂one-hot和embedding_one hot

one hot

在 NLP领域,word embedding 已经成为了众所周知的技术。在现实生活中 word embedding 已经拥有非常广泛的应用:语音助手、机器翻译、情感分析… 因为 word embedding 的特殊性,它几乎覆盖了所有 NLP 的应用。接下来说说  传统的 one-hot 编码开始,阐述其优劣,并延伸至 word embedding 技术和其优点

人类可以很轻易地理解一个单词、词组或者字母,比如「LOVE」,但机器是理解不了的。想要让机器理解单词,就必须要把它变成一串数字(向量)。下面介绍的 One-Hot Encoding(One-Hot 编码)和 Word Embedding (词嵌入)和就是把单词变成向量的两类方法

一、One-Hot Encoding (词汇表->稀疏向量)

1.首先one-hot是什么?为什么用one-hot?

一般来说,机器学习教程会推荐你或要求你,在开始拟合模型之前,先以特定的方式准备好数据;其中,一个很好的例子就是对类别数据(Categorical data)进行 One-Hot 编码

那么,什么是类别数据?类别数据是一种只有标签值而没有数值的变量。它的值通常属于一个大小固定且有限的集合。类别变量也常被称为标称值(nominal)。
下面举例说明:

  • 宠物(pet)变量包含以下几种值:狗(dog)、猫(cat)。
  • 颜色(color)变量包含以下几种值:红(red)、绿(green)、蓝(blue)。
  • 位次(place)变量包含以下几种值:第一(first)、第二(second)和第三(third)。

以上例子中的每个值都代表着一个不同的类别。有些类别彼此间存在一定的自然关系,比如自然的排序关系。上述例子中,位次(place)变量的值就有这种自然的排序关系。这种变量被称为序数变量(ordinal variable)。

2.类别数据有什么问题?

有些算法可以直接应用于类别数据。比如,你可以不进行任何数据转换,将决策树算法直接应用于类别数据上(取决于具体实现方式)。但还有许多机器学习算法并不能直接操作标签数据。这些算法要求所有的输入输出变量都是数值(numeric)。通常来说,这种限制主要是因为这些机器学习算法的高效实现造成的,而不是算法本身的限制。
但这也意味着我们需要把类别数据转换成数值形式。如果输出变量是类别变量,那你可能还得将模型的预测值转换回类别形式,以便在一些应用中展示或使用
如何将类别数据转换成数值数据:

两个方法:1.整数编码                          2.One-Hot 编码

a.整数编码:第一步,先要给每个类别值都分配一个整数值。
比如,用 1 表示红色(red),2 表示绿色(green),3 表示蓝色(blue)。这种方式被称为标签编码或者整数编码,可以很轻松地将它还原回类别值。整数之间存在自然的排序关系,机器学习算法也许可以理解并利用这种关系。比如,前面的位次(place)例子中的序数变量就是一个很好的例子。对于它我们只需要进行标签编码就够了。

b.One-Hot 编码

但对于不存在次序关系的类别变量,仅使用上述的整数编码是不够的。实际上,使用整数编码会让模型假设类别间存在自然的次序关系,从而导致结果不佳或得到意外的结果(预测值落在两个类别的中间)。这种情况下,就要对整数表示使用 One-Hot 编码了。One-Hot 编码会去除整数编码,并为每个整数值都创建一个二值变量。

再通俗一点:

将离散型特征使用one-hot编码,确实会让特征之间的距离计算更加合理。比如,有一个离散型特征,代表工作类型,该离散型特征,共有三个取值,不使用one-hot编码,其表示分别是x_1 = (1), x_2 = (2), x_3 = (3)。两个工作之间的距离是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那么x_1和x_3工作之间就越不相似吗?显然这样的表示,计算出来的特征的距离是不合理。那如果使用one-hot编码,则得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那么两个工作之间的距离就都是sqrt(2).即每两个工作之间的距离是一样的,显得更合理。

在颜色(color)的示例中,有 3 种类别,因此需要 3 个二值变量进行编码。对应的颜色位置上将被标为“1”,其它颜色位置上会被标为“0”。

  1. red, green, blue
  2. 1, 0, 0
  3. 0, 1, 0
  4. 0, 0, 1

二、word embedding - 让计算机学会爱(词间的关系)

深度学习应用在自然语言处理当中的时候,基本都会通过词向量的方式将one-hot编码的向量,转换为词向量。至于为什么这么做,

一个原因是因为深度学习对稀疏输入效果不好,

第二个最主要原因是,那种one-hot方式的编码,对于每一个不同的单词或者中文的词语,之间关系没有办法表达出来,也即,对于不同的单词,两个单词的one-hot编码的向量的相似度永远为0, 也即cos(Vi, Vj) = 0。那么问题来了,怎样表示出单词之间的内在联系呢?embedding来了

要了解 embedding 的优点,我们可以对应 One-hot 编码来观察。One-hot 编码是一种最普通常见的表示离散数据的表示,首先我们计算出需要表示的离散或类别变量的总个数 N,然后对于每个变量,我们就可以用 N-1 个 0 和单个 1 组成的 vector 来表示每个类别。这样做有两个很明显的缺点:

  • 对于具有非常多类型的类别变量,变换后的向量维数过于巨大,且过于稀疏。
  • 映射之间完全独立,并不能表示出不同类别之间的关系。

因此,考虑到这两个问题,表示类别变量的理想解决方案则是我们是否可以通过较少的维度表示出每个类别,并且还可以一定的表现出不同类别变量之间的关系,这也就是 embedding 出现的目的。

Embedding 是一个将离散变量转为连续向量表示的一个方式。在神经网络中,embedding 是非常有用的,因为它不光可以减少离散变量的空间维数,同时还可以有意义的表示该变量。

我们可以总结一下,embedding 有以下 3 个主要目的:

  • 在 embedding 空间中查找最近邻,这可以很好的用于根据用户的兴趣来进行推荐。
  • 作为监督性学习任务的输入。
  • 用于可视化不同离散变量之间的关系。

这也就意味对于维基百科书籍表示而言,使用 Neural Network Embedding,我们可以在维基百科上获取到的所有 37,000 本书,对于每一篇,仅仅用一个包含 50 个数字的向量即可表示。此外,因为 embedding 是可学习的,因此在不断的训练过程中,更相似的书籍的表示在 embedding space 中将彼此更接近。
One-hot 编码的最大问题在于其转换不依赖于任何的内在关系,而通过一个监督性学习任务的网络,我们可以通过优化网络的参数和权重来减少 loss 以改善我们的 embedding 表示,loss 越小,则表示最终的向量表示中,越相关的类别,它们的表示越相近

Embedding 可视化,可以看出词与词之间的相似性

底下这个图是我用tensorflow训练人民的名义的embedding的结果

三、总结

最后我们来做一个总结,自然语言的向量化表示方法主要有两类:one-hot encoding 和 word embedding。它们的优缺点如下:
在这里插入图片描述

四、应用

Embedding 的基本内容如前面介绍所示,然而我想说的是它的价值并不仅仅在于 word embedding 或者 entity embedding,这种将类别数据用低维表示且可自学习的思想更存在价值。通过这种方式,我们可以将神经网络,深度学习用于更广泛的领域,Embedding 可以表示更多的东西,而这其中的关键在于要想清楚我们需要解决的问题和应用 Embedding 表示我们得到的是什么。

说到embedding就不得不说说word2vector了,word2vector做法即为embedding的过程,这个可以扩展到推荐中的item2vector 。顺便提一嘴word2vec:

1.可以看作是多分类任务

2.浅层神经网络

3.数据构造模式:cbow、skip-gram模式

完结!

以下加一点用tensorflow模拟embedding的一点代码做个记录

  1. import tensorflow as tf
  2. import numpy as np
  3. #类似语料库
  4. embedding_dict = tf.convert_to_tensor(np.random.random(size=(30,4)))
  5. #输入的词索引
  6. input_train = tf.convert_to_tensor([1,2,4,5])
  7. 检索得到对应词的embedding权重
  8. embed = tf.nn.embedding_lookup(embedding_dict,input_train)
  9. #由于我的tensorflow的版本较高,session开启方式不同
  10. sess = tf.compat.v1.Session()
  11. sess.run(tf.compat.v1.global_variables_initializer())
  12. print(sess.run(embedding_dict))
  13. print("====================================")
  14. print(sess.run(embed))
  15. sess.close()
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/922746
推荐阅读
相关标签
  

闽ICP备14008679号