Python教程-如何在Python中对序列数据进行独热编码

在本教程中,我们将学习将输入或输出的序列数据转换为独热编码,以用于序列分类。
独热编码是机器学习中的一个有用特性,因为有些机器学习算法不能直接处理分类数据。在处理数据集时,我们经常会遇到不具有特定偏好顺序的列。
如果我们正在处理序列分类类型的问题,那么分类数据必须转换为数字。当我们使用深度学习方法,如长短时记忆递归神经网络(LSTM)时,也会使用这种技术。
首先,我们将讨论分类数据。
什么是分类数据?
分类数据是具有标签值而不是数值的变量类型。这些类型的变量也称为名义变量。让我们看看以下分类数据的示例。
- 具有值"Maruti"和"Jaguar"的"汽车"变量。
- 具有值"Veg"和"Non-Veg"的"食物"变量。
- 具有值"first"、"second"和"third"的"地方"变量。
如上面的代码中所示,某些类别可能具有自然关系,例如自然排序。在第三个示例中,“地方”变量具有值的自然顺序。
分类数据的问题
一些机器学习算法可以直接处理分类数据。但有些算法不能直接处理标签数据,因为它们要求所有数据变量和输出变量都是数字。
因此,我们必须将层次数据转换为数字形式。假设分类变量是一个输出变量,那么您可能还希望通过模型将预测转换回分类形式以表示它们或在某些应用中使用它们。
如何将分类数据转换为数值数据
有两种方法可以将分类数据转换为数值数据。
- 整数编码
- 独热编码
在下一部分中,我们将讨论独热编码。
什么是独热编码?
独热编码用于将分类变量转换为数值。在进行进一步的数据分析之前,将分类值映射为整数值。每一列包含“0”或“1”,对应于它所在的列。在这个过程中,每个整数值都表示为一个二进制向量,除了整数的索引,该索引用1标记。
独热编码的示例
让我们通过以下简单的示例来理解它。
假设我们有一个标签序列,其值为'yellow'和'red'。为了将它们转换为数字值,我们分别为'yellow'分配了整数值1,为'red'分配了整数值0。当我们遇到这些标签时,我们将分配相同的整数值。这被称为整数编码。
让我们看另一个例子 - 假设有一个名为"animal"的类别,它有四个值 - Cat、Dog、Cow和Camel。考虑下面的表格,其中包含了动物及其对应的分类值。
输入表格 -
动物 | 动物的分类值 |
---|---|
猫 | 5 |
狗 | 10 |
牛 | 15 |
骆驼 | 11 |
下面是进行独热编码后的输出。
猫 | 狗 | 牛 | 骆驼 |
---|---|---|---|
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 0 | 0 | 1 |
如果我们将上述输出表示成矢量形式,它将如下所示。
猫 - > [1, 0, 0, 0]
狗 - > [0, 1, 0, 0]
牛 - > [0, 0, 1, 0]
骆驼 - > [0, 0, 0, 1]
为什么要使用独热编码?
独热编码的一个最大优点是,它能够更具表现力地表示分类数据。正如我们前面讨论的,许多机器学习算法不能直接处理分类数据,因此需要将其转换为整数。
我们可以直接使用整数值或在需要时使用它。它可以解决自然序数与类别之间存在关系的问题。例如 - 我们可以为"天气"标签分配整数值,如'冬季'、'夏季'和'季风'。
但如果没有找到任何有序关系,可能会有问题。如果我们允许表示倾斜或任何这种关系,可能会损害解决问题的学习能力。
手动进行独热编码
在下面的示例中,我们将考虑一个字母字符串的示例,该字符串将被转换为整数值。
hello world
现在,我们将对上面给定的字符串值实施独热编码。让我们看看以下示例。
示例 -
from numpy import argmax
# Here we are define input string
str_data = 'hello python'
print(str_data)
# Here we are defining possible input values of english alphabate
eng_alphabet = 'abcdefghijklmnopqrstuvwxyz '
# define a mapping of chars to integers
char_to_int = dict((c, i) for i, c in enumerate(eng_alphabet))
int_to_char = dict((i, c) for i, c in enumerate(eng_alphabet))
# input data is encoding in integer
int_encoded = [char_to_int[char] for char in data]
print(int_encoded)
# one hot encode
onehot_encoded = list()
for value in int_encoded:
letter = [0 for _ in range(len(eng_alphabet))]
letter[value] = 1
onehot_encoded.append(letter)
print(onehot_encoded)
# invert encoding
inverted = int_to_char[argmax(onehot_encoded[0])]
print(inverted)
输出:
hello python
[7, 4, 11, 11, 14, 26, 15, 24, 19, 7, 14, 13]
[[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, 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, 1, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
解释:
在上面的代码中,我们声明了输入字符串并将其打印出来。接下来,我们定义了可能输入的英语字母的范围。然后,从字符值到整数值的所有可能输入的映射被创建。我们使用这个映射来对输入字符串进行编码。
正如我们在上面的输出中所看到的,第一个字母h被编码为7。然后,这个整数编码被转换为独热编码。一个整数一次编码一个字符。
每个字符都有特定的索引值;我们标记了特定字符的索引为1。第一个字符在27位的二进制向量中表示为7。我们将第7个索引标记为1表示h。
现在,我们将学习如何使用scikit-learn库来实施独热编码。
使用Scikit-learn进行独热编码
在本示例中,假设有以下3个标签的输出序列。
"apple"
"mango"
"banana"
一个示例的10个时间步骤序列可能是:
apple, apple, mango, apple, banana, banana, mango, apple.
我们对上述标签进行整数编码,例如1、2、3。在独热编码中,我们将使用具有3个值的二进制向量,例如[1, 0, 0]。序列中至少包含一个可能值的示例。
我们将使用scikit-learn库。我们将使用它的LabelEncoder模块来创建标签的整数编码,以及OneHotEncoder来创建整数编码值的独热编码。
让我们来看看以下示例。
示例 -
from numpy import array
from numpy import argmax
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# defining sequence example
data_1 = ['apple', 'apple', 'mango', 'apple', 'banana', 'banana', 'mango', 'apple']
values_of_seq = array(data_1)
print(values_of_seq)
# first appling integer encode
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values_of_seq)
print(integer_encoded)
# Now doing binary encode
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)
输出:
['apple' 'apple' 'mango' 'apple' 'banana' 'banana' 'mango' 'apple']
[0 0 2 0 1 1 2 0]
[[1. 0. 0.]
[1. 0. 0.]
[0. 0. 1.]
[1. 0. 0.]
[0. 1. 0.]
[0. 1. 0.]
[0. 0. 1.]
[1. 0. 0.]]
解释 -
在上面的代码中,首先,我们打印了标签的序列。然后,我们执行了整数编码,最后进行了独热编码。OneHotEncoder类返回了一个整洁的稀疏编码。但对于某些应用来说,这并不高效,比如与keras库一起使用时。
使用Keras进行独热编码
假设我们有一个已经进行了整数编码的序列。我们可以直接使用整数编码工作,也可以将整数编码映射到标签值。我们可以使用to_categorical()函数将整数数据进行独热编码。
在这个示例中,我们有五个整数值[0, 1, 2, 3, 4],并且有以下15个数字的输入序列。
data_1 = [1, 4, 3, 3, 0, 3, 2, 2, 4, 0, 1, 2, 1, 4, 3]
示例 -
from numpy import array
from numpy import argmax
from keras.utils import to_categorical
# define example
data_1 = [1, 4, 3, 3, 0, 3, 2, 2, 4, 0, 1, 2, 1, 4, 3]
data = array(data_1)
print(data)
# one hot encoding using the to_categorical() method
encoded = to_categorical(data)
print(encoded)
# invert encoding
inverted = argmax(encoded[0])
print(inverted)
输出:
[1 4 3 3 0 3 2 2 4 0 1 2 1 4 3]
[[0. 1. 0. 0. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 1. 0.]
[1. 0. 0. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 0. 1.]
[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 1. 0.]]
1
在上述示例中,我们使用Keras的to_categorical()函数将整数编码的序列转换为独热编码。
结论
独热编码是一种用于将分类数据转换为数值数据的常用技术。它适用于许多机器学习问题,特别是在深度学习和神经网络中。无论您是手动进行编码还是使用库函数,都可以轻松地实现独热编码。独热编码有助于提高模型的性能,并在处理分类数据时提供了更多的灵活性。
希望这个教程有助于您理解和实现独热编码的基本概念。如果您有任何问题或需要进一步的协助,请随时提问!