知识点:one-hot独热编码

1,089 阅读4分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」。

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来转化为独热编码。