1. one-hot 独热
独热,是机器学习中初学者经常听到的一个词。
从字面意义看,独表示唯独,一家独大,独占鳌头,独热表示只有1个热,其他都是凉的。
事实也是如此。
我们来看一个独热编码的例子:
[0, 1, 0, 0, 0]
可以看到,上面只有一个1,其他都是凉凉的0,这就是独热。
假设,我们有5种状态:金、木、水、火、土。我们给这5个状态留了5个空,它们都有专门的位置。
数字 | 位置编号 |
---|---|
金 | 0 |
木 | 1 |
水 | 2 |
火 | 3 |
土 | 4 |
自从有了这个规则以后,但凡是老金出现,都是以这种状态示人:[1, 0, 0, 0, 0]
,我有5个兄弟,我表示第一个。老土出现那就是:[0, 0, 0, 0, 1]
。
如果两个一起出现,是这样式的:[[1, 0, 0, 0, 0],[0, 0, 0, 0, 1]]
.
这就是独热的表示。
2. 为什么要用独热?
为什么会用这种奇怪的方式表示呢?老金直接是0,老土直接是4不就完了?
其实这么做是有目的的。
独热是为了体现公平。每次出现都携带者团队成员的数量,避免了招摇撞骗,说房子是自己的,其实自己只占几份之一。另外,每个成员只能是1,只是用来标记是不是你,无法夸大你的比重,比如展示成[99, 0, 0, 0, 0]
,这样就不是独热的标准。
通过独热的编码标准,使得计算时,公平公正。大家的值都是1,避免了你是1我是2,出现谁大谁小从而干扰计算。
如果,你的基础学科比较好的话,其实我上面说那么多,都是下面的通俗化:
大部分算法是基于向量空间中的度量来进行计算的,为了使非偏序关系的变量取值不具备偏序性,而且到圆点是等距的。使用one-hot编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理。
3. 独热的局限
虽然,独热编码有优势。但是,它也是有局限性的。
独热适合表示少量的,无关联的数据。
-
首先说它不适合大量的数据。如果总共有5条数据,那其中一条是这么表示
[1, 0, 0, 0, 0]
,如果是10条,这么表示[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
。如果是5000条,那就是1个1,4999个0。这种情况,术语上叫过于稀疏,反而不利于计算。 -
另外,也是因为独热很公正公平,所以导致成员间没有个人关系。有时候,尤其当自然语言处理时,我们很希望能表示出每个词语间的相关性。
比如,我们要表示心情好坏程度,有如下几种心情:悲伤、郁闷、无聊、微笑、大笑、爆笑。那么,我们假设以0为中心点,负面的情绪定义为负数,正面的情绪定义为正数。上面几种状态可以这么表示:
心情 | 表示 |
---|---|
悲伤 | -3 |
郁闷 | -2 |
无聊 | -1 |
微笑 | 1 |
大笑 | 2 |
爆笑 | 3 |
这样,我们就可以了解他们之间的关系了:爆笑(3)程度要大于微笑(1)。大笑(2)和郁闷(-2)是完全相反的状态。
这种带成员关系的数据,就不合适用独热来表示了。
4. 独热的应用场景
一般的分类问题,比如手写数字识别,OCR识别,花朵种类识别。
TensorFlow提供了一个将数值转换为独热编码的方法:
import tensorflow as tf
labels = [1,2,3]
ys = tf.keras.utils.to_categorical(labels, 5)
print(ys)
最终输出的结果:
[[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]]
此方法很有用,因为一般训练集标记的不是独热编码,比如手写识别结果存储都是具体的:3、6、2,我们可以使用to_categorical
来转化为独热编码。