如何在Python中进行独热编码的序列数据
在本教程中,我们将学习将输入或输出的序列数据转换为用于序列分类的独热编码。
独热编码是机器学习的一个有用功能,因为很少有机器学习算法可以直接处理分类数据。在处理数据集时,我们会遇到一列没有特定偏好顺序的数据。
如果我们正在处理的是序列分类问题,那么分类数据必须转换为数字。当我们使用深度学习方法,如长短期记忆循环神经网络时,也会使用这种技术。
首先,我们将讨论分类数据。
什么是分类数据
分类数据是具有标签值而不是数值的变量类型。这些类型的变量也被称为名义变量。让我们看一个分类数据的示例。
- 一个“汽车”变量,值为“Maruti”和“Jaguar”。
- 一个“食物”变量,值为“Veg”和“Non-Veg”。
- 一个“地点”变量,值为“第一”,“第二”和“第三”。
正如我们在上面的代码中所看到的,一些类别可能有自然的关系,比如自然的排序。在第三个示例中,“地点”变量具有值的自然排序。
分类数据的问题
一些机器学习算法可以直接处理分类数据。但是有一些算法无法直接在标签数据上操作,因为它们要求所有的数据变量和输出变量都是数值类型。
因此,我们需要将层次化数据转换为数值形式。假设分类变量是一个输出变量。在这种情况下,您可能还希望将模型的预测结果转换回分类形式,以表示它们或在某些应用中使用它们。
如何将分类数据转换为数值数据
有两种方法可用于将分类数据转换为数值数据。
- 整数编码
- 独热编码
在下一节中,我们将讨论 独热编码 。
什么是独热编码
独热编码用于将分类变量转换为数值。在进行进一步的数据分析之前,将分类值映射为整数值。每列包含“0”或“1”,对应于它所在的列。在此过程中,每个整数值都表示为一个二进制向量,除了整数的索引处,其他位置都为零,整数的索引处为1。
独热编码示例
通过以下简单示例来理解独热编码。
假设我们有一个标签序列,值为’黄色’和’红色’。为了将它们转换为数值,我们将’黄色’分配一个整数值1,对应于它在列中的类别数量,将’红色’分配为0。当我们遇到这些标签时,我们将分配相同的整数值。这被称为整数编码。
让我们看另一个示例 – 假设有一个名为animal的类别,它有四个值 – 猫、狗、牛和骆驼。考虑以下表格,其中包含动物及其对应的分类值。
输入表格 –
Animal | Categorical Value of Animal |
---|---|
Cat | 5 |
Dog | 10 |
Cow | 15 |
Camel | 11 |
经过One-Hot编码后,输出如下所示。
Cat | Dog | Cow | Camel |
---|---|---|---|
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个索引标记为h的1。
现在,我们将学习如何使用 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
解释 –
在上面的代码中,我们将整数编码为二进制向量并打印。然后,我们使用了Numpy的 argmax() 函数对序列中的第一个值进行反向编码。