LSTM系列_LSTM的数据准备(2)——如何编写OneHotEncoder(热编码)序列数据

导读:

什么是热编码,原意是OneHotEncoderOneHotEncoder就是把一些有意义的文字或符号转换成及其能读懂的语言。

我们有时想对一系列有意义的数据进行处理或者预测,但这种有意义的数据不一定是数字,有可能是英文,汉字,标记,我们可以对其分类,然后用特定的数字编码(代替)他们。而不同的编码方式有着不同的表现力。

源码地址:https://github.com/yangwohenmai/LSTM/tree/master/%E9%95%BF%E7%9F%AD%E6%9C%9F%E8%AE%B0%E5%BF%86(LSTM)/LSTM%E7%9A%84%E6%95%B0%E6%8D%AE%E5%87%86%E5%A4%87/%E5%9C%A8%E7%BC%96%E5%86%99one-hot%E7%BC%96%E7%A0%81%E5%BA%8F%E5%88%97%E6%95%B0%E6%8D%AE

OneHotEncoder的工作示例

让我们用一个有效的例子来具体化。

假设我们有一系列标签,其值为“红色”和“绿色”。

我们可以将'red'指定为0的整数值,将'green'指定为整数值1.只要我们总是将这些数字指定给这些标签,就称为整数编码。一致性很重要,以便我们可以稍后反转编码并从整数值返回标签,例如在进行预测时。

接下来,我们可以创建一个二进制向量来表示每个整数值。对于2个可能的整数值,向量的长度为2。

编码为0的“红色”标签将用二进制矢量[1,0]表示,其中第零个索引用值1标记。反过来,编码为1的“绿色”标签将用二进制向量[0,1],其中第一个索引标记为值1。

如果我们有序列:

1

'red', 'red', 'green'

我们可以用整数编码来表示它:

1

0, 0, 1

和热门编码:

1

2

3

[1, 0]

[1, 0]

[0, 1]

 

为什么要使用OneHotEncoder

OneHotEncoder允许分类数据的表示更具表现力。

许多机器学习算法无法直接使用分类数据。必须将类别转换为数字。这对于分类的输入和输出变量都是必需的。

我们可以直接使用整数编码,在需要的地方重新调整。这可能适用于类别之间存在自然序数关系的问题,反过来又是整数值,例如温度“冷”,“暖”和“热”的标签。

当没有顺序关系并且允许表示依赖任何这样的关系可能有损于学习解决问题时可能存在问题。一个例子可能是标签'dog'和'cat'

在这些情况下,我们希望为网络提供更具表现力的能力,以便为每个可能的标签值学习类似概率的数字。这有助于使问题更容易网络建模。当OneHotEncoder用于输出变量时,它可以提供比单个标签更细微的预测集。

手动OneHotEncoder

在这个例子中,我们假设我们有一个字母字母的示例字符串,但示例序列并未涵盖所有可能的示例。

我们将使用以下字符的输入序列:

1

hello world

我们将假设所有可能输入的范围是小写字符和空格的完整字母表。因此,我们将以此为借口演示如何推出自己的热编码。

下面列出了完整的示例。

from numpy import argmax
# 定义一个编码字符串
data = 'hello world'
print(data)
# 定义输入值得所有分类类型
alphabet = 'abcdefghijklmnopqrstuvwxyz '
# define a mapping of chars to integers
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# 转换成整形编码输入
integer_encoded = [char_to_int[char] for char in data]
print(integer_encoded)
# 编码过程
onehot_encoded = list()
for value in integer_encoded:
	letter = [0 for _ in range(len(alphabet))]
	letter[value] = 1
	onehot_encoded.append(letter)
print(onehot_encoded)
# 逆转换第一行数据
inverted = int_to_char[argmax(onehot_encoded[0])]


从char值到整数值创建所有可能输入的映射。然后使用该映射对输入字符串进行编码。我们可以看到输入'h'中的第一个字母编码为7,或者可能输入值(字母表)数组中的索引7。首先运行该示例打印输入字符串。

然后将整数编码转换为OneHotEncoder。这是一次完成一个整数编码字符。将创建0值的列表作为字母表的长度,以便可以表示任何预期的字符。

接下来,特定字符的索引标记为1.我们可以看到编码为7的第一个字母'h'整数由长度为27且第7个索引标记为1的二进制向量表示。

最后,我们反转第一个字母的编码并打印结果。我们通过使用NumPy argmax()函数定位具有最大值的二进制向量中的索引,然后在字符值的反向查找表中使用整数值来实现此操作。

注意:输出格式化是为了便于阅读。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

hello world

 

[7, 4, 11, 11, 14, 26, 22, 14, 17, 11, 3]

 

[[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

 

h

现在我们已经看到了如何从头开始编写自己的热编码,让我们看看如何在输入序列完全捕获预期输入值范围的情况下,使用scikit-learn库自动执行此映射。

 

OneHotEncoder与scikit学习

在此示例中,我们假设您具有以下3个标签的输出序列:

 

1

2

3

"cold"

"warm"

"hot"

10个时间步骤的示例序列可以是:

 

1

cold, cold, warm, cold, hot, hot, warm, cold, warm, hot

这首先需要整数编码,例如1,2,3。这之后是整数的一个热编码到具有3个值的二进制向量,例如[1,0,0]。

该序列提供序列中每个可能值的至少一个示例。因此,我们可以使用自动方法来定义标签到整数和整数到二进制向量的映射。

在本例中,我们将使用scikit-learn库中的编码器。具体来说,LabelEncoder用于创建标签的整数编码,而OneHotEncoder用于创建整数编码值的OneHotEncoder

下面列出了完整的示例。

from numpy import array
from numpy import argmax
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# 定义一个实例
data = ['cold', 'cold', 'warm', 'cold', 'hot', 'hot', 'warm', 'cold', 'warm', 'hot']
values = array(data)
print(values)
# 转换成整形编码
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values)
print(integer_encoded)
# 转换成向量编码
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
print(onehot_encoded)
# 逆转换第一行数据
inverted = label_encoder.inverse_transform([argmax(onehot_encoded[0, :])])
print(inverted)


训练数据包含所有可能示例的集合,因此我们可以依赖整数和OneHotEncoder变换来创建标签到编码的完整映射。首先运行该示例将打印标签序列。接下来是标签的整数编码,最后是OneHotEncoder

默认情况下,OneHotEncoder类将返回更有效的稀疏编码。这可能不适合某些应用程序,例如与Keras深度学习库一起使用。在这种情况下,我们通过设置sparse = False参数来禁用稀疏返回类型。

如果我们在这个3值热编码中接收到预测,我们可以轻松地将变换反转回原始标签。

首先,我们可以使用argmax()NumPy函数来定位具有最大值的列的索引。然后可以将其馈送到LabelEncoder以计算反向变换回文本标签。

这在示例的结尾处被证明,其中第一个热编码示例的逆变换返回到标签值'cold'。

再次注意,输入的格式是为了便于阅读。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

['cold' 'cold' 'warm' 'cold' 'hot' 'hot' 'warm' 'cold' 'warm' 'hot']

 

[0 0 2 0 1 1 2 0 2 1]

 

[[ 1.  0.  0.]

[ 1.  0.  0.]

[ 0.  0.  1.]

[ 1.  0.  0.]

[ 0.  1.  0.]

[ 0.  1.  0.]

[ 0.  0.  1.]

[ 1.  0.  0.]

[ 0.  0.  1.]

[ 0.  1.  0.]]

 

['cold']

在下一个例子中,我们看看如何直接对一个整数值序列进行热编码。

OneHotEncoder与Keras

您可能有一个已经整数编码的序列。

在进行一些缩放之后,您可以直接使用整数。或者,您可以直接对整数进行热编码。如果整数没有真正的序数关系并且实际上只是标签的占位符,这一点很重要。

Keras库提供了一个名为to_categorical()的函数,您可以将其用于OneHotEncoder整数数据。

在这个例子中,我们有4个整数值[0,1,2,3],我们有以下10个数字的输入序列:

 

1

data = [1, 3, 2, 0, 3, 2, 2, 1, 0, 1]

序列有一个所有已知值的示例,因此我们可以直接使用to_categorical()函数。或者,如果序列从0开始(从0开始)并且不代表所有可能的值,我们可以指定num_classes参数to_categorical(num_classes = 4)

下面列出了此功能的完整示例。

from numpy import argmax
# 定义一个编码字符串
data = 'hello world'
print(data)
# 定义输入值得所有分类类型
alphabet = 'abcdefghijklmnopqrstuvwxyz '
# define a mapping of chars to integers
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))
# 转换成整形编码输入
integer_encoded = [char_to_int[char] for char in data]
print(integer_encoded)
# 编码过程
onehot_encoded = list()
for value in integer_encoded:
	letter = [0 for _ in range(len(alphabet))]
	letter[value] = 1
	onehot_encoded.append(letter)
print(onehot_encoded)
# 逆转换第一行数据
inverted = int_to_char[argmax(onehot_encoded[0])]

然后将整数编码为二进制向量并打印。我们可以看到第一个整数值1被编码为[0,1,0,0]就像我们期望的那样。首先运行示例定义并打印输入序列。

然后,我们通过在序列中的第一个值上使用NumPy argmax()函数来反转编码,该函数返回第一个整数的期望值1。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

[1 3 2 0 3 2 2 1 0 1]

 

[[ 0.  1.  0.  0.]

[ 0.  0.  0.  1.]

[ 0.  0.  1.  0.]

[ 1.  0.  0.  0.]

[ 0.  0.  0.  1.]

[ 0.  0.  1.  0.]

[ 0.  0.  1.  0.]

[ 0.  1.  0.  0.]

[ 1.  0.  0.  0.]

[ 0.  1.  0.  0.]]

 

1

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日拱一两卒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值