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

机器学习算法不能直接处理分类数据。

分类数据必须转换为数字。

当您处理序列分类类型问题并计划使用深度学习方法(如长短期记忆循环神经网络)时,此规则适用。

在本教程中,您将学习如何将输入或输出序列数据转换为独热编码,以便在 Python 中使用深度学习解决序列分类问题。

完成本教程后,您将了解:

  • 什么是整数编码和独热编码,以及它们在机器学习中为何必要。
  • 如何在 Python 中手动计算整数编码和独热编码。
  • 如何在 Python 中使用 scikit-learn 和 Keras 库自动编码您的序列数据。

使用我的新书《使用 Python 的长短期记忆网络启动您的项目,其中包括逐步教程和所有示例的 Python 源代码文件。

让我们开始吧。

How to One Hot Encode Sequence Classification Data in Python

如何在 Python 中对序列分类数据进行独热编码
图片由 Elias Levy 提供,部分权利保留。

教程概述

本教程分为4个部分,它们是:

  1. 什么是独热编码?
  2. 手动独热编码
  3. 使用 scikit-learn 进行独热编码
  4. 使用 Keras 进行独热编码

什么是独热编码?

独热编码是将分类变量表示为二进制向量的一种方式。

这首先需要将分类值映射到整数值。

然后,每个整数值都被表示为一个二进制向量,除了整数的索引处标记为 1 之外,所有值都为零。

独热编码的示例

我们通过一个实例来具体说明。

假设我们有一个包含值“red”和“green”的标签序列。

我们可以将“red”分配整数值 0,将“green”分配整数值 1。只要我们始终将这些数字分配给这些标签,这就称为整数编码。一致性很重要,这样我们以后才能反转编码并从整数值获取标签,例如在进行预测时。

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

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

如果我们有序列

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

以及独热编码

为什么使用独热编码?

独热编码可以使分类数据的表示更具表现力。

许多机器学习算法无法直接处理分类数据。类别必须转换为数字。对于作为分类的输入和输出变量,都需要这样做。

我们可以直接使用整数编码,并在需要时重新缩放。这可能适用于类别之间存在自然序数关系的问题,以及随后的整数值,例如温度标签“冷”、“暖”和“热”。

如果不存在序数关系,并且让表示依赖于任何此类关系可能会损害解决问题的学习,则可能会出现问题。一个例子可能是标签“狗”和“猫”。

在这些情况下,我们希望赋予网络更强的表达能力,使其能够为每个可能的标签值学习一个类似概率的数字。这有助于使网络更容易对问题进行建模。当独热编码用于输出变量时,它可能提供比单个标签更细微的预测集。

需要 LSTM 帮助进行序列预测吗?

参加我的免费7天电子邮件课程,了解6种不同的LSTM架构(附代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

手动独热编码

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

我们将使用以下字符作为输入序列

我们将假设所有可能输入的宇宙是完整的小写字母表和空格。因此,我们将以此为例来演示如何实现我们自己的独热编码。

完整的示例如下所示。

运行该示例首先打印输入字符串。

创建了所有可能输入的映射,从字符值到整数值。然后使用此映射对输入字符串进行编码。我们可以看到输入中的第一个字母“h”被编码为 7,或者在可能的输入值(字母表)的数组中的索引 7。

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

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

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

注意:输出已格式化以提高可读性。

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

使用 scikit-learn 进行独热编码

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

一个 10 个时间步的示例序列可能是

这首先需要整数编码,例如 1, 2, 3。然后是整数到包含 3 个值的二进制向量的独热编码,例如 [1, 0, 0]。

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

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

完整的示例如下所示。

运行该示例首先打印标签序列。接着是标签的整数编码,最后是独热编码。

训练数据包含所有可能的示例集,因此我们可以依靠整数和独热编码转换来创建标签到编码的完整映射。

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

如果我们收到这种 3 值独热编码的预测,我们可以轻松地将转换反转回原始标签。

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

这在示例的末尾进行了演示,将第一个独热编码示例反向转换回标签值“cold”。

同样,请注意输入已格式化以提高可读性。

在下一个示例中,我们将探讨如何直接对整数序列进行独热编码。

使用 Keras 进行独热编码

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

您可以直接处理这些整数,经过一些缩放后。或者,您可以直接对整数进行独热编码。如果这些整数没有真正的序数关系,而只是标签的占位符,那么这一点很重要。

Keras 库提供了一个名为 to_categorical() 的函数,您可以使用它对整数数据进行独热编码。

在此示例中,我们有 4 个整数值 [0, 1, 2, 3],并且我们有以下 10 个数字的输入序列

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

此函数的完整示例如下所示。

运行该示例首先定义并打印输入序列。

然后将整数编码为二进制向量并打印。我们可以看到,第一个整数值 1 被编码为 [0, 1, 0, 0],正如我们所预期的那样。

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

进一步阅读

本节列出了一些进一步阅读的资源。

总结

在本教程中,您学习了如何使用 Python 中的独热编码对分类序列数据进行深度学习编码。

具体来说,你学到了:

  • 什么是整数编码和独热编码,以及它们在机器学习中为何必要。
  • 如何在 Python 中手动计算整数编码和独热编码。
  • 如何在 Python 中使用 scikit-learn 和 Keras 库自动编码您的序列数据。

您对准备序列数据有什么疑问吗?
在评论中提出您的问题,我将尽力回答。

立即开发用于序列预测的 LSTM!

Long Short-Term Memory Networks with Python

在几分钟内开发您自己的 LSTM 模型。

...只需几行python代码

在我的新电子书中探索如何实现
使用 Python 构建长短期记忆网络

它提供关于以下主题的自学教程
CNN LSTM、编码器-解码器 LSTM、生成模型、数据准备、进行预测等等...

最终将 LSTM 循环神经网络引入。
您的序列预测项目。

跳过学术理论。只看结果。

查看内容

203 条对《如何在 Python 中对序列数据进行独热编码》的回应

  1. Natallia Lundqvist 2017 年 7 月 12 日下午 7:02 #

    感谢您的这篇文章!来得很及时。一个问题。to_categorical(data) 工具接受向量作为输入。如果您有一个 2D 张量作为输入,该怎么办?您是会遍历样本数量(可能有数十万个条目 + 在循环中进行模型训练)还是必须执行 seq = tokenizer.texts_to_sequences(inputseq) 然后 tokenizer.sequences_to_matrix(seq, mode='binary')??最后一个选项将以数组([ 0., 1., 1., …, 0., 0., 0.])的形式给出 2D 张量作为输出。在这种情况下,模型训练照常进行,但对于解码预测,您必须循环才能找到所有最大值(argmax 只给出第一个最大值)。

    • Jason Brownlee 2017 年 7 月 13 日上午 9:52 #

      哎呀,如果没有具体细节很难给出好的建议。选择一种保留序列结构的形式。

    • 哈利 2019 年 1 月 10 日上午 12:09 #

      您什么时候进行填充?在 sequences_to_matrix 之前还是之后?

      • Jason Brownlee 2019 年 1 月 10 日上午 7:51 #

        两种都试试,看看哪种最适合您的特定数据集。

    • 2022 年 3 月 27 日下午 3:05 #

      我如何将独热编码数据集转换为标签编码。即从多列到两列

  2. 弗朗哥 2017 年 7 月 14 日上午 5:30 #

    杰森,又一篇很棒的文章!谢谢您。我刚刚把它添加到我的机器学习清单中。

  3. 罗希特 2017 年 7 月 14 日上午 10:22 #

    我们如何在 keras 中执行整数编码?是否有像 scikit 中的 LabelEncoder 这样的内置函数?

  4. 莫伊 2017 年 7 月 24 日下午 2:20 #

    嗨,Jason,

    好文!

    如果序列不代表所有可能的值,并且我们不知道要设置 num_classes 参数的类的数量,该怎么办?

    • Jason Brownlee 2017 年 7 月 25 日上午 9:26 #

      谢谢。

      是的,这是一个挑战。

      恕我直言,您可能需要在未来重新编码数据。或者选择一种对尚未见过的新值有“空间”的编码。我预计在这个主题上有一些很好的研究。

  5. 马尔科姆 2017 年 8 月 17 日下午 9:44 #

    一如既往的富有信息量的帖子!

    我了解如何使用它来训练模型。
    然而,您如何确保您想要获取预测的数据与训练数据以相同的方式编码?例如,“热”映射到第 3 列。

    对于我的应用程序,一旦模型经过训练,它将需要在以后和不同的机器上提供预测。

    • Jason Brownlee 2017 年 8 月 18 日上午 6:19 #

      很好的问题!

      它必须是一致的。您可以重复使用相同的代码,和/或保存执行转换的“模型”。

  6. 萨西 2017 年 9 月 11 日下午 4:16 #

    谢谢你!很棒的工作…………。

  7. NVK 2017 年 9 月 29 日上午 3:37 #

    嘿,
    一如既往的出色教程!
    不过,有一个问题——如果我的数据集既包含分类值又包含连续值,该怎么办?独热编码不会编码整个数据集吗,而我真正需要的只是编码分类列?
    另外,推荐的流程是 (a) 仅缩放数字数据 (b) 编码整个数据集吗?
    还是 (a) 编码整个数据集然后 (b) 缩放所有值?

    • Jason Brownlee 2017 年 9 月 29 日上午 5:09 #

      我建议只对分类变量进行编码。

      • Vel 2020 年 2 月 4 日下午 5:22 #

        podi naayae

    • 奥拉 2018 年 8 月 8 日上午 5:34 #

      好帖子!

  8. ed 2017 年 10 月 4 日上午 5:03 #

    你好,

    我正在从事模型产品化工作。为了减少实验和生产之间的数据处理差距,我想在 Keras 模型中嵌入独热编码。问题是

    1. 使用“to_categorical”时,它会即时转换分类数据,这似乎会破坏编码。例如,我们在训练模型时有“apple”、“orange”和“banana”。推出模型后,其中包括“lemon”等未见的类别。我们如何处理这种情况?

    2. 由于想将编码嵌入到 Keras 中。因此,尝试不使用 sklearn 标签编码器和独热编码器。是否可以做到这一点?

    请 kindly advise。

    • Jason Brownlee 2017 年 10 月 4 日上午 5:50 #

      也许您可以开发自己的小型函数来执行编码并始终如一地执行它?

  9. Adhaar Sharma 2017 年 10 月 5 日上午 8:38 #

    嗨,Jason,

    喜欢这个网站!有一个小问题

    如果我有一个包含 6 个分类属性的 X 数据集,其中每个属性分别具有以下唯一类别数量 [4, 4, 4, 3, 3, 3]。另外,假设有 600 个实例

    当我对这个 X 数据集进行 LabelEncode 和 OneHotEncode 后,我正确地得到了 fit_transform 方法后的 21 个 0-1 值的序列。

    然而,当我以这种方式输入 X 数据集,即形状为 (600, 21) 时,我得到一个比仅保留 LabelEncoded 且形状为 (600, 6) 时更糟糕的错误。

    我的问题是我做错了什么吗?我是否应该将我得到的 21 个整数序列重新分组到它们各自的簇中?例如:我通过 OneHotEncode 得到第一行的这个数组
    [0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0]
    那我应该把这些数字重新组合成这样吗
    [(0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 1, 0)]
    现在我的输入数据集的形状又变回 (600, 6) 了吗?

    我尝试使用此公式创建 NumPy 数组,但 sci-kit 决策树分类器会检查并尝试转换 dtype 为对象的任何 NumPy 数组,因此元组未通过验证。

    本质上,我想知道 (600, 21) 的形状是否会导致任何数据丢失。如果是,那么将编码重新分组到它们各自属性的最佳方法是什么,以便我可以降低我的错误。

    谢谢!

    • Jason Brownlee 2017 年 10 月 5 日下午 5:21 #

      嗯。

      编码后数据应为 500, 21,目前为止一切顺利。

      无需分组。

      技能好坏取决于算法和您的特定数据。一切都是为了帮助我们发现适合我们问题的方法而进行的测试。

      考虑尝试更多算法。
      考虑只编码部分变量,而将其他变量保持原样或进行整数编码。
      集思广益,尝试更多事情,请参阅此帖子获取想法
      https://machinelearning.org.cn/machine-learning-performance-improvement-cheat-sheet/

      希望这些能作为一个开始有所帮助。

      • Adhaar Sharma 2017 年 10 月 6 日上午 5:30 #

        好的,太棒了!我只是不确定是调试独热编码器还是尝试其他方法。看来尝试其他方法是正确的选择。

        非常感谢您的帮助,杰森!

  10. 普拉尚特 2017 年 10 月 10 日上午 4:24 #

    你好,
    一如既往的出色教程!
    我有一个疑问……为什么我们要重塑 integer_encoded 向量
    “integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)”?

    • Jason Brownlee 2017 年 10 月 10 日上午 7:53 #

      很好的问题,因为 sklearn 工具期望 2D 数据作为输入。

  11. 多卢奈 2017 年 12 月 11 日上午 1:18 #

    你好,

    非常感谢您的精彩帖子!
    有一些研究只使用单词的索引而不将它们转换为独热编码,

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

    他们只使用这个序列作为输入。我想问一下,由于我们从 0 开始生成索引,那么在进行 0 填充时不会有问题吗?

    非常感谢!

    • Jason Brownlee 2017 年 12 月 11 日上午 5:27 #

      0 通常保留给“无词”或“未知词”。

      • 多卢奈 2017 年 12 月 11 日上午 6:08 #

        好的,但是在独热形式中,为什么我们没有为未知词保留 0 位置?

        • Jason Brownlee 2017 年 12 月 11 日下午 4:49 #

          这在使用 Keras 等库执行编码时会自动发生。我们也可以手动完成。

          • 多卢奈 2017 年 12 月 11 日下午 7:40 #

            我在手动操作,有时我怀疑自己是否做错了,这就是我创建字符索引字典的方式。

            ch_ind = dict((c, i+1) for i, c in enumerate(s_chars))
            ind_ch = dict((i+1, c) for i, c in enumerate(s_chars))

            然后我这样创建我的独热编码,

            X = np.zeros((MAX_LEN, len(ch_ind)))

            for i, ch in enumerate(line[:MAX_LEN])
            X[i, (ch_ind[ch])] = 1

            return X

            这意味着我不会有以下编码,因为我在点 0 处没有字符,

            [1 0 0 0 …]

            但这真的能实现为填充保留点 0 吗?

            非常感谢您的时间!

  12. 萨蒂什·奇洛吉 2018 年 1 月 8 日上午 5:07 #

    嗨,Jason,

    如果我们的分类变量级别超过 500 个怎么办?如何处理这个问题,它是独热编码吗?这会反过来导致列数很高。

  13. 离子 2018 年 1 月 10 日上午 5:11 #

    当所有输入数据都是类别时如何处理?

    • Jason Brownlee 2018 年 1 月 10 日上午 5:31 #

      您可以使用标签编码器,甚至可以使用独热编码器对所有标签进行编码。

  14. 阿德瓦伊特·昌多卡尔 2018 年 1 月 15 日上午 6:54 #

    你好杰森博士,

    我有一个 CSV 数据集,其中一些值是浮点值,其余是标签。如果我对标签使用独热编码,它们将被转换为二进制向量。但是,其他值是浮点数。

    我想在这个数据上训练一个分类器。使用二进制向量和浮点值的组合数据集来训练分类器是否正确?数据集中的所有参数不都应该是相同的数据类型吗?

    • Jason Brownlee 2018 年 1 月 15 日上午 7:02 #

      是的,在组合的原始和编码变量上进行训练。

  15. 冈特 2018 年 1 月 26 日下午 5:32 #

    嗨,Jason,

    您的文章对于像我这样的新手来说是极好的资源!先生,非常感谢您为此投入的精力!
    我发现 pandas.Dataframe 有一个很好的方法可以进行独热编码,即使用 get_dummies,这非常方便(https://pandas.ac.cn/pandas-docs/stable/generated/pandas.get_dummies.html)。

  16. 萨沙·雅各布 2018 年 2 月 11 日上午 3:53 #

    亲爱的杰森,
    一旦我们使用 one_hot_encoder 来表示包含大量值的分类属性,我们最终可能会得到一个非常大的矩阵。您能解释一下神经网络中“嵌入”背后的思想,以克服这个问题吗?

    此致。

  17. 维什 2018 年 2 月 19 日上午 11:13 #

    嗨,Jason,
    一如既往的出色文章。由于分类(非数字)数据在大多数情况下必须进行独热编码,我只是想知道为什么没有直接方法可以获取分类数据并直接返回独热编码数据集,而不是用户总是必须首先调用标签编码器来获取数据整数编码?

    • Jason Brownlee 2018 年 2 月 19 日下午 3:06 #

      有时直接处理整数编码值会带来好处。

  18. 玛丽亚姆 2018 年 3 月 1 日上午 8:08 #

    嗨,Jason,
    我很欣赏您写的清晰教程,特别是对像我这样的新手。
    我想获得概率输出而不是类别标签作为输出。
    我知道我应该应用“model.add(Dense(2, activation='sigmoid'))”而不是应用“model.add(Dense(1, activation='sigmoid'))”,并且我还应该使用“One Hot Encode with Keras”中的命令。
    但我怀疑我是否应该将类标签放入 data = [1, 3, 2, 0, 3, 2, 2, 1, 0, 1] 中。我的意思是,我是否应该写入 data =[0,1] 而不是 data = [1, 3, 2, 0, 3, 2, 2, 1, 0, 1]。我有一个文本数据集的二元分类问题。
    您介意通过教程链接甚至通过编写命令来回答我吗?
    等待您的回复。

    • Jason Brownlee 2018 年 3 月 1 日下午 3:08 #

      您可以通过在模型上调用 predict_proba() 来进行概率预测。

      对于二元结果,您可以使用输出层中的单个节点,结果将是 0 或 1,而不是独热编码的类别。

      • 玛丽亚姆 2018 年 3 月 2 日上午 7:43 #

        亲爱的杰森,您好,
        感谢您花时间回复我。
        我不想得到 0,1 的结果。我想得到可能的结果,例如 90% 的“好”类,10% 的“坏”类。
        我不想得到标签作为输出,也不想得到 f-measure 或准确性。
        我想获得相似度度量 = lstm、cnn、rnn 的概率度量。我应该编写 k 折交叉验证来构建一个可以为每个标签实现相似度度量的模型。
        请给我一个教程,告诉我如何编写 k 折交叉验证命令,以及我想知道相似度度量在 Keras 中的作用。”

        “””如果我想简单地提一下,我想了解如何编写 k 折交叉验证命令,我还想知道相似度度量在 Keras 中的作用?”””
        感谢您如此清晰地帮助新手。
        祝好

        • Jason Brownlee 2018 年 3 月 2 日下午 3:19 #

          这是一个概率结果。您可以通过调用 predict() 并使用该值和 1 – 该值来获得类别 1 和类别 0 的概率,从而实现二进制结果。

          交叉验证仅用于估计模型的技能。在您估计模型技能后,CV 折叠和模型将被丢弃,您可以拟合一个最终模型以用于进行预测。在此处了解更多信息
          https://machinelearning.org.cn/train-final-machine-learning-model/

          • 玛丽亚姆 2018 年 3 月 2 日晚上 10:40 #

            嗨,Jason,
            感谢您抽出时间回复。
            希望解决问题。
            最美好的祝愿。
            Maryam

  19. 蒂姆·莱文 2018 年 3 月 2 日上午 4:35 #

    Jason,

    很棒的帖子。你正在把我变成一个机器学习忍者!你认为独热编码是表示“冷”、“暖”、“热”等序数数据的好选择吗?也就是说,通过编码成单独的列,你是否会失去这三者处于连续体中的关系。我认为数据准备的一般方法是向机器学习算法展示我对每个变量的了解。在这种情况下,独热编码似乎模糊了它。你认为将这三者保留为整数会是更好的选择吗?你推荐什么?

    谢谢,

    蒂姆

    • Jason Brownlee 2018 年 3 月 2 日上午 5:37 #

      它可以使算法的关系更简单,是向量化的而不是复合的。

      一般来说,测试并证明这种改变能提高模型技能。

  20. 贾拉德 2018 年 3 月 30 日上午 10:25 #

    你好 Jason,很棒的教程!你知道我如何组合不同长度的多个独热向量吗?假设除了每个字母的独热编码外,我还有其他类别,例如性别和国家。

    另外,如果我需要将这些与年龄等整数结合起来怎么办?

    干杯! 🙂

    • Jason Brownlee 2018 年 3 月 31 日上午 6:31 #

      如果我理解正确,您可以在独热编码输入旁边放置其他变量,以形成一个非常长的输入向量。

  21. 亚伯拉罕·照片 2018 年 4 月 7 日晚上 11:50 #

    多么伟大的工作,让机器学习方法变得更轻松

    你好 Jason,最近我正在处理一个有 921179 行和大约 32 列的数据。在 32 列中,22 列是 Object 类型,我尝试使用标签编码器和独热编码器对数据集进行编码。
    1,每列至少有 20 个唯一值。会有数百个类别在一起。
    2,对于如此大的数据,使用 labelEncoder 然后使用 one hot Encoder 进行编码是否正确。
    或者如果您能给我一个更简单的方法。

    提前致谢!

    • Jason Brownlee 2018 年 4 月 8 日上午 6:21 #

      也许可以尝试一系列方法,并根据它们对模型技能的影响进行评估。

      ——尝试整数编码。
      ——尝试独热编码
      ——尝试删除它们
      ——尝试分组标签,然后编码。
      – ……

      告诉我进展如何。

  22. 亚伯拉罕·照片 2018 年 4 月 8 日晚上 8:57 #

    谢谢您的快速回复!

    ——我使用 pandas 导入数据集:df = pd.read_csv(‘name.csv’)
    ——然后我只选择了对象类别:df = df.select_dtypes(include=[‘object’])
    - 标签编码 df1.apply(LabelEncoder().fit_transform) – 到目前为止运行良好。
    ——然后我尝试创建虚拟变量,这里出了问题
    —— df.apply(OneHotEncoder(categorical_features='all').fit_transform) – 我收到了这样的错误消息

    File “”, line 1, in
    X = one.fit_transform(X1)

    文件“/Users/afoto/anaconda2/lib/python2.7/site-packages/sklearn/preprocessing/data.py”,第 2019 行,在 fit_transform 中
    self.categorical_features, copy=True)

    文件“/Users/afoto/anaconda2/lib/python2.7/site-packages/sklearn/preprocessing/data.py”,第 1809 行,在 _transform_selected 中
    X = check_array(X, accept_sparse='csc', copy=copy, dtype=FLOAT_DTYPES)

    文件“/Users/afoto/anaconda2/lib/python2.7/site-packages/sklearn/utils/validation.py”,第 433 行,在 check_array 中
    array = np.array(array, dtype=dtype, order=order, copy=copy)

    ValueError: 无法将字符串转换为浮点数:否

    • Jason Brownlee 2018 年 4 月 9 日上午 6:10 #

      也许确认您是在整数编码变量而不是原始字符串变量上应用独热编码?

  23. 亚伯拉罕·照片 2018 年 4 月 10 日下午 7:47 #

    感谢您的回复。

    最近,我看到了一个关于处理许多分类属性的教程。该方法简单如下:

    1,遍历所有具有对象数据类型对象的属性,然后识别唯一的类别
    2,如果类别数量超过 15 或 20 个,例如一个名为 nationality 的特征,我们发现大多数是 4000 = 美国人,200 欧洲人,10 非洲人,50 印度人,2 中国人等等。
    3,我们为美国人和欧洲人以及其他(其中其他是剩余的国家)创建虚拟变量

    我发现这种方法直观且易于实现。
    期待您的宝贵意见和反馈。

    谢谢,干杯!

    • Jason Brownlee 2018 年 4 月 11 日上午 6:38 #

      是的,我喜欢这种方法。

    • 卡里贾图·德拉梅 2022 年 3 月 25 日下午 7:54 #

      你好,你能和我分享让你实现它的链接吗,因为我的项目也有同样的问题

  24. 安基特·特里帕蒂 2018 年 4 月 17 日上午 12:00 #

    嗨,Jason,

    这是一篇涵盖全面的优秀文章。不过,我有一个疑问。我使用了以下代码对一些分类变量进行独热编码,但是,在成功使用独热编码后,模型拟合会报错。如果我使用序数编码,则没有错误。以下是代码

    # 独热编码

    from sklearn.preprocessing import OneHotEncoder
    def one_hot_encode_features(df_train,df_test)
    features = ['Fare', 'Cabin', 'Age', 'Sex']
    #features = [ 'Cabin', 'Sex']
    df_combined = pd.concat([df_train[features], df_test[features]])
    for feature in features
    le = preprocessing.LabelEncoder()
    onehot_encoder = OneHotEncoder()
    le = le.fit(df_combined[feature])
    integer_encoding_train=le.transform(df_train[feature])
    integer_encoding_test=le.transform(df_test[feature])
    integer_encoding_train = integer_encoding_train.reshape(len(integer_encoding_train), 1)
    integer_encoding_test = integer_encoding_test.reshape(len(integer_encoding_test), 1)
    df_train[feature] = onehot_encoder.fit_transform(integer_encoding_train)
    df_test[feature] = onehot_encoder.fit_transform(integer_encoding_test)
    return df_train, df_test
    data_train, data_test = one_hot_encode_features(data_train, data_test)

    # 拟合模型
    from sklearn.naive_bayes import GaussianNB
    from sklearn.metrics import make_scorer, accuracy_score
    from sklearn.model_selection import GridSearchCV

    clf = GaussianNB()
    acc_scorer = make_scorer(accuracy_score)
    clf.fit(X_train, Y_train)

    • Jason Brownlee 2018 年 4 月 17 日上午 6:01 #

      抱歉,我无法调试您的代码。

      也许可以尝试将您的代码发布到 StackOverflow 上的开发者那里?

      • 安基特·特里帕蒂 2018 年 4 月 17 日晚上 10:05 #

        嗨,Jason,

        这里有一个与代码调试无关的问题,我按照本文中的步骤收到一个独热编码的稀疏矩阵。然而,我发现很难将其添加到我的训练数据框中。

        f_train[feature] = onehot_encoder.fit_transform(integer_encoding_train) 会用相同的值填充所有 n 行。如何正确实现这一点?

  25. 安基特·特里帕蒂 2018 年 4 月 17 日下午 5:22 #

    好的,谢谢杰森

  26. 阿达什 2018 年 5 月 4 日晚上 7:16 #

    这种方法是否建议用于大量分类变量,例如我有一个变量有 1500 个类别,使用独热编码是否可取

  27. diehumblex 2018 年 5 月 11 日晚上 11:44 #

    你好 Jason,我首先对类别进行整数编码,然后将其转换为独热编码。在预测过程中,我使用了反转并得到了类别。现在我还想要类别的置信度。我正在使用 Keras,在使用 predict_prob 时,我得到“Model”对象没有“predict_proba”属性,因为我没有使用 sequential。有什么建议可以获取类别的置信度吗?

    • Jason Brownlee 2018 年 5 月 12 日上午 6:33 #

      如果您在输出层使用 softmax 或 sigmoid 作为激活函数,您可以直接将值用作类似概率的值。

  28. 亚伯拉罕·照片 2018 年 5 月 14 日晚上 9:11 #

    当我们使用 sklearn 进行独热编码时,我们如何检查代码是否没有虚拟陷阱。
    我的意思是,如果我有很多具有数字分类值的特征,例如特征 x1:3,2,1,5,3,4,2
    和特征 x2:1,2,3,2,1,3 等等
    如果我一次性使用独热编码所有类别
    oneHot = OneHotEncode(category_feature=[要编码的数量] -> 例如特征 1,2,4
    特征 x1:有 4 个类别,独热编码后我们得到 4 个新特征还是 3 个特征。在 get dummy 中我们得到 3 个,因此没有虚拟陷阱,one hot encoder 怎么样

    • Jason Brownlee 2018 年 5 月 15 日上午 7:55 #

      您将在二进制向量中获得 n 个元素,其中 n 是唯一类别的数量。

  29. 沙伦德拉 2018 年 5 月 24 日下午 3:22 #

    我们如何将独热编码用于下一个词预测,是否有相关的文章?
    谢谢你

  30. 埃姆娜 2018 年 5 月 24 日晚上 9:47 #

    我有一个关于使用独热编码的小问题。我有一个标记列表,此列表包含字符串、数字甚至像“这样”的特殊字符。我已经对这个列表进行了独热编码,并将其输入到自动编码器模型中。然后,我将一个未知的独热编码列表输入到模型中。然后,自动编码器模型的输出被输入到反向独热编码函数中。尽管我的模型准确率为 0.9,但生成的列表与未知列表并不接近。您知道问题出在哪里吗?我使用了本教程中的独热编码函数。

    • Jason Brownlee 2018 年 5 月 25 日上午 9:24 #

      听起来您的实现中存在错误。我这里有一些想法

      – 考虑积极地将代码削减到最低限度。这将帮助您隔离问题并专注于它。
      – 考虑将问题削减到只有一个或几个简单示例。
      – 考虑寻找其他类似的代码示例,这些示例有效,并缓慢修改它们以满足您的需求。这可能会暴露您的错误。
      – 考虑将您的问题和代码发布到 StackOverflow。

  31. 阿达什 2018 年 6 月 26 日下午 7:05 #

    如何处理特征的新类别示例

    特征 x 在构建模型时具有这些类别
    2001
    2002
    2003
    在使用模型进行预测时,假设我得到 2004 作为该特征的值,我如何使用独热编码来处理它???同样,scikit-learn 方法也会有所帮助

    • Jason Brownlee 2018 年 6 月 27 日上午 8:15 #

      您必须规划编码以支持未来出现的新类别。

      如果问题定义发生变化,您可能需要忽略该变化或重建表示和模型。通常后者成本较低。

  32. 克拉森斯 2018 年 7 月 9 日晚上 8:20 #

    我从您的帖子中学到了很多东西,我想感谢您花时间解释这些概念。这对于我们这些刚开始接触机器学习的人来说真的很有帮助。我非常感激!

  33. 瓦伦 2018 年 7 月 18 日下午 2:48 #

    我的 pandas 数据框中有一列包含数千个唯一字符数据。如何对其执行独热编码?实际上我有 40 列。这样做会增加 1000 额外列。

    • Jason Brownlee 2018 年 7 月 18 日下午 2:48 #

      1000 列不算多,在自然语言处理问题中我们可能有数万甚至数十万列。

      • 瓦伦 2018 年 7 月 18 日下午 3:57 #

        有没有独热编码的替代方案?

  34. 奥拉 2018 年 8 月 8 日上午 5:36 #

    好帖子!

  35. cholzkorn 2018 年 8 月 21 日晚上 8:46 #

    你好!我非常喜欢您的代码(它帮了我很多!),我在此基础上进行了构建。这是一个将给定列转换为类别类型并正确命名输出列的函数。我想在这里分享它

  36. Emna 2018年9月15日 上午12:34 #

    我们可以将文本或 XML 元素字段编码成数组而不是单个值(整数)吗?

    • Jason Brownlee 2018年9月15日 上午6:10 #

      你可以将单词编码成数字,也可以将字母编码成数字。前者更常见也更有用。

  37. Kevin Swingler 2018年9月18日 下午11:54 #

    嗨,Jason,
    这是一篇很棒的文章,谢谢。你是否曾将独热编码作为多元线性回归的输入,并查看过结果系数?它们可能与你预期的不同,但我找不到讨论这个问题的来源。我想知道你是否遇到过相关内容?

    如果我们取一个包含 n 行和 p 列的随机二元矩阵,表示 n 个样本上的 p 个变量和一个系数向量 w,然后生成 y=Xw,我们就得到了输入 X 和输出 y 的数据集。如果然后我们使用多元线性回归来估计 w(在这个例子中我们已经知道了 w,因为我们用它来生成 y),我们得到的是我们最初使用的 w 值。这对于 X 中的几乎任何值(其中 n>p)都成立,但 X 是独热编码的表示时除外。在那种特定情况下,w 中系数的估计值与用于生成 y 的值不同。你遇到过这种现象吗?我怀疑这是因为每个系数的约束不足,但我从未见过对此的讨论。我认为,它对从独热编码变量构建的模型解释具有有趣的后果。

    • Jason Brownlee 2018年9月19日 上午6:21 #

      线性回归对于编码的分类变量效果不佳。也许可以尝试其他方法,比如决策树?

  38. Akshay Bhaskaran 2018年9月19日 上午6:49 #

    嗨,Jason,首先感谢你详细的解释。我有一个简短的问题(我是 scikit-learn 和整个机器学习的初学者)

    1. 我选择了一些输入特征列表 [X]
    2. 我发现特定列中存在缺失值
    3. 对于其中一个有缺失值的列,假设类别是 ['Fa', 'Gd', 'Ex', 'TA', Nan]
    4. 我已经完成了数字编码和二元(独热)编码来得到这个
    缺失值:[nan, 'Fa', 'TA', 'Ex', 'Gd']
    数字编码:[4 1 3 0 2]
    二元/独热编码
    [[0. 0. 0. 0. 1.]
    [0. 1. 0. 0. 0.]
    [0. 0. 0. 1. 0.]
    [1. 0. 0. 0. 0.]
    [0. 0. 1. 0. 0.]]
    5. 现在,我如何将这些值重新填充到它们缺失的列中?我需要进行插补吗?还是创建一个新的数据框?

    非常感谢你的帮助,提前感谢..

    • Jason Brownlee 2018年9月19日 下午1:44 #

      你删除原始列,然后将新列与其余数据连接起来。

      这有帮助吗?

      • Akshay Bhaskaran 2018年9月21日 上午1:28 #

        这很有帮助,谢谢 Jason。另一个问题是

        假设我有一些带有缺失值的分类列,例如:{nan, 'Gd', 'TA', 'Fa', 'Ex'}。现在我执行以下操作

        1. 从原始 X 数据框中删除该列
        2. 对分类数据进行数字编码:[4 2 3 1 0]
        3. 接下来,我对这些数据进行二元独热编码:[[0. 0. 0. 0. 1.]
        [0. 0. 1. 0. 0.]
        [0. 0. 0. 1. 0.]
        [0. 1. 0. 0. 0.]
        [1. 0. 0. 0. 0.]]

        4. 现在,我的问题是,我有一些数字可以在列中操作。我需要使用(strategy=mean/median/most_frequent)进行任何类型的插补吗?还是现在可以直接将这些带有数字值的列添加到原始数据框并开始我的模型?

        • Jason Brownlee 2018年9月21日 上午6:31 #

          很好的问题。

          你可以事先将缺失值作为分类值进行插补。
          你可以将 NaN 视为自己的值。
          你可以删除这些行。

          尝试几种方法,看看哪种方法能带来最佳的模型性能。

          • Akshay Bhaskaran 2018年9月21日 下午2:20 #

            酷…再次感谢 Jason…抱歉我的傻问题,我刚接触机器学习两周…

            > 我有两个数据集(train.csv 和 test.csv)。
            > 显然,我应该在“训练”数据上拟合和训练我的模型,并使用“测试”数据(验证)进行预测

            > 这是我的问题
            当我分割测试和验证数据时,如果只有一个数据框,很容易做到

            train_X, val_X, train_y, val_y = [X, y, random_state=0]

            > 现在,当我有两个数据框 – train.csv 和 test.csv 时,我该如何处理呢?我该如何在这里适当地分割数据

          • Jason Brownlee 2018年9月21日 下午2:22 #

            训练集被分成训练集和验证集。

            你可以在这里了解更多
            https://machinelearning.org.cn/difference-test-validation-datasets/

  39. Eugene 2018年10月5日 上午4:40 #

    感谢您的这篇文章。
    我正在使用你的代码转换一个具有以下结构的 DNA 序列列表:[[a,b,c,d,e],[f,g,h,i,j],[k,l,m,n]]。它基本上是一个包含字母的列表的列表。
    我对我的列表的列表使用了 np.array 函数,但是 fit_transform 给了我一个形状错误。
    你有什么建议?

  40. Mel 2018年10月11日 上午2:55 #

    你好,感谢这篇很棒的文章。
    我使用了你的代码进行标签编码和独热编码,但是当我调用 inverse_transform 时,我得到了这个错误

    inverted = label_encoder.inverse_transform([argmax(data_oh[0, :])])
    文件 "...ProgramsPythonPython36libsite-packagessklearnpreprocessinglabel.py", 第283行, in inverse_transform
    return self.classes_[y]
    TypeError: only integer scalar arrays can be converted to a scalar index

    你知道问题可能出在哪里吗?

    我的代码如下
    #整数编码
    label_encoder_dict = defaultdict(LabelEncoder) #将所有列的 LabelEncoder 保留为字典。
    integer_encoded = data_cat.apply(lambda x: label_encoder_dict[x.name].fit_transform(x))
    #二进制编码
    oh = OneHotEncoder(handle_unknown='ignore', sparse=False)
    integer_encoded = integer_encoded.as_matrix(integer_encoded.columns)
    data_oh = self.oh.fit_transform(integer_encoded)
    label_encoder = self.label_encoder_dict['DEST']
    inverted = label_encoder.inverse_transform([argmax(data_oh[0, :])])

    谢谢!

    • Jason Brownlee 2018年10月11日 上午8:00 #

      我以前从未见过这种情况。

      一个提示是,逆变换期望数据具有与 transform() 函数提供的数据相同的形状和形式。

  41. Eklil Khan 2018年11月3日 上午2:39 #

    感谢你的出色工作。我有一个数据集,其结构如下


    不接受
    我将你的数据集文件简化为

    A

    B

    C

    D

    E

    F

    我通过以下代码从这个数据集中提取了数据。

    import re

    with open (“test_dataset.log”, “r”) as myfile
    read_dataset = myfile.read()

    i_ident = []
    j_atr = []
    find_ident = re.findall(r'(.*?)’, read_dataset, re.S)
    ident_list = list(map(lambda x: x.replace(‘\n’, ‘ ‘), find_ident))
    for i in range(len(ident_list))
    i_ident.append(str(ident_list[i]))

    find_atr = re.findall(r'(.*?)’, read_dataset, re.S)
    atr_list = list(map(lambda x: x.replace(‘\n’, ‘ ‘), find_atr))
    #print(coref_list)
    for i in range(len(atr_list))
    j_atr.append(str(atr_list[i]))

    print(i_ident)
    print()
    print(j_atr)

    我将这些数据的值存储在 i 和 j 变量中。我想在决策树中进行共指消解。为了完成这项任务,我定义了一些函数,例如:

    distance_feature():根据句子数量计算 i 和 j 之间的距离。输出:0 或 1

    Ispronoun_feature():如果名词短语是代词,则此特征设置为 true。

    appositive_feature():此特征检查 j 是否是 i 的同位语。

    还有更多,大约有 12 个我提取的特征。现在,如果我想将数据更改为独热编码,我如何构建我的树?你看到了数据集结构,它都是非结构化的。那么在 sci-kit learn 中,我如何包含所有这些函数来决定 i 和 j 是否共指?如果你有一些想法,请告诉我。
    谢谢你

  42. Akshat Jain 2018年11月3日 上午6:56 #

    你好 Jason,

    我正在使用 Keras 的 to_categorical,上面你特别说过当序列从 0 开始时,但如果我想在一个从 1 开始的序列上使用它怎么办?那么我们该如何处理呢?

    我尝试过,它总是在最终编码中添加一个额外的 0 列,这不好,我还尝试过 num_classes 参数,但我遇到了“IndexError”。

  43. Sneha 2018年11月12日 上午1:21 #

    嗨,Jason,
    这是一篇很棒的文章。标签编码器会在测试集中遇到未见值时抛出错误,因此无法继续进行独热编码。在生产系统中如何解决这个问题?

    • Jason Brownlee 2018年11月12日 上午5:39 #

      确保它是在包含所有可能情况的数据上进行训练的,例如,具有代表性。

  44. Annur Syafiqah 2018年11月22日 下午5:33 #

    嗨,Jason 博士,

    目前我想对我的数据集进行特征选择。我的数据集包含 20 个特征,其中 7 个是分类特征,其余是连续特征。然而,我发现并非所有特征选择技术都适用于混合(分类+连续)数据集,例如 PCA。在我阅读了独热编码后,我觉得想用它来将所有分类特征转换为连续特征,这意味着标准化所有特征的类型。编码后,我将使用 PCA 来减少数据维度。这是一个好主意吗?

    • Jason Brownlee 2018年11月23日 上午7:46 #

      可能不是。也许可以分别处理所有分类变量,然后处理所有数值变量?

  45. Matt 2018年12月10日 下午12:19 #

    你好 Jason,很棒的文章。
    我有一些分类名义数据,需要对其应用某种降维技术。应用独热编码并运行 PCA 与应用多元对应分析 (MCA) 有何不同?我想你会得到相似的结果

    • Jason Brownlee 2018年12月10日 下午2:18 #

      独热编码是一种分布式表示,PCA(并选择最相关的组件)将消除输入之间的线性依赖性。

  46. Francisco Cuadra 2018年12月19日 上午3:46 #

    你好 Jason,

    首先,感谢这篇文章,它真的很有帮助。
    其次:我有一些问题,我现在正在开发一个 API,它从调查中获取数据并对其执行多元线性回归分析,这些数据可能包含数值和分类问题,考虑到这一点

    – 假设我已经有一种整数编码分类数据的方法,并且我的数值数据已经是整数形式,你认为对其中任何一部分进行独热编码更方便吗?

    – 你会如何对一系列排名式的答案进行独热编码?例如,每个受访者都必须将猫、狗和仓鼠作为他们最喜欢的宠物进行排名,给出如下答案
    A1:猫、仓鼠、狗。
    A2:狗、猫、仓鼠。
    A3:仓鼠、狗、猫。

    提前感谢。

  47. khiem 2019年1月18日 下午4:35 #

    非常感谢你出色的教程。我想知道我是否可以使用预测的独热编码形式来计算一些指标,如准确率、IoU、F1 分数,或者我必须将其转换回逆独热编码形式才能进行计算,因为这与混淆矩阵的实际负值和实际正值相关(例如,独热编码形式:[0,0,1,0] 和逆独热编码形式:[2])

    • Jason Brownlee 2019年1月19日 上午5:34 #

      独热编码仅用于建模。

      模型做出预测后,你可以使用 argmax() 将其转换回类别整数,然后计算准确性。

  48. Veena 2019年1月28日 下午10:35 #

    嗨,Jason,
    我正在处理一个问题,其中有一个序列列和另一个值列。数据如下:

    序列 CV
    AAAAGHKLYH 0.5
    AGLMcKAD 0.7
    WMGKAAASFAAKm 0.56

    我想将这些数据编码为数字形式,并尝试使用一些神经网络来预测 CV,但我不知道如何解码序列,序列的最大长度为 55。

    • Jason Brownlee 2019年1月29日 上午6:12 #

      如果你对输入序列中的每个字符进行独热编码,则无需解码,但你可以通过使用 argmax() 函数获取整数并将整数映射回字符来实现。

      • Veena 2019年1月30日 上午2:42 #

        感谢回复。
        抱歉,我的问题错了,我不知道如何将我的序列列输入到编码器,我尝试将列作为输入,但出现了内存错误,并尝试将其作为 numpy 数组,仍然出现了相同的错误。

  49. Håvard 2019年2月13日 下午5:49 #

    嗨,Jason,

    感谢您的有用指点。scikit-learn OneHotEncoder 似乎能够直接处理字符串标签,而无需像上面那样通过 LabelEncoder。那么,仍然使用两步方法的原因是什么?

    一些示例代码,用于说明字符串标记数据的标签的独热编码

    from sklearn.preprocessing import OneHotEncoder

    # 创建一个独热编码器并使用数据中的类别进行设置
    ohe = OneHotEncoder(dtype='int8',sparse=False)
    taxa_labels = np.unique(taxa[:,1])
    ohe.fit(taxa_labels.reshape(-1,1))

    # 为每个样本创建一个分类目标列表
    y = ohe.transform(taxa[:,1].reshape(-1,1))

    # 从独热编码器获取字符串标签,以后可能会有用
    labels= ohe.inverse_transform(y)

    • Jason Brownlee 2019年2月14日 上午8:39 #

      好建议,谢谢!

      也许那是一个新功能?

      • Håvard 2019年3月12日 上午12:47 #

        这似乎是从 sklearn 0.20.3 版本开始添加的。

        不过,了解这两种方法都很好。我最近在 Google Compute Engine 提供的现成深度学习镜像上运行测试,一些尴尬的依赖关系使得从默认版本升级 sklearn 变得困难。我不得不为了这个确切的原因重写我的一些代码,以使其向后兼容这个旧版本。

  50. CFlow 2019年2月27日 下午4:45 #

    这非常清晰,谢谢!
    根据 sklearn-onehotencoder,你能将结果列表放在 pandas 数据框中吗?

  51. Abhijit 2019年3月4日 下午2:40 #

    谢谢 Jason!一篇极其清晰的教程。我有一个问题——假设我们不是在处理序列数据——比如一个数据集中随机出现“狗”和“猫”作为宠物,这是输入的一部分。在这种情况下,尽管没有序数意义,但我认为整数编码应该可以工作。有必要实现独热编码吗?

    • Jason Brownlee 2019年3月5日 上午6:30 #

      这实际上取决于数据集(有多少个类别)和算法。

      通常,两个输出类别不会进行整数或独热编码,而是由模型预测两个类别值之间的 0 到 1 之间的值。

      • Abhijit 2019年3月6日 下午6:42 #

        谢谢;实际上它是其中一个输入——所以输入可以是猫(0)或狗(1),它们在数据集中出现的频率相同,并作为输入进入模型;显然没有序数意义。独热编码是必要的还是整数编码就足够了?

        • Jason Brownlee 2019年3月7日 上午6:44 #

          也许可以两者都尝试一下,看看编码如何影响模型性能?

          • Abhijit 2019年3月7日 下午2:59 #

            好的,我都会尝试……谢谢。本教程非常有帮助。

  52. Jim 2019年3月5日 下午5:11 #

    感谢这篇精彩的文章,Jason。我有一个关于如何处理数据框中实际是分类的数字的问题。

    假设我有两列名为“汽车类型”和“发动机类型”,每列都包含表示某种类型的整数。例如

    汽车类型 发动机类型
    1 3
    3 3
    2 2
    2 1

    当相同的数字出现在两者中时,我如何使用 OHC 替换这些 df 列?当值是字符串时,这不是问题,因为“福特”、“GMC”等只会变成值为 1 或 0 的列。但显然我们不能只有一个名为“2”的列,所以我不知道该怎么做。

    感谢您提供的任何建议!

    • Jim 2019年3月6日 上午4:38 #

      好的,我所做的,似乎有效的方法是

      car_type = df.pop(‘car_type’)
      engine_type = df.pop(‘engine_type’)

      df[‘car_type_1’] = (car_type == 1) * 1.0
      df[‘car_type_2’] = (car_type == 2) * 1.0
      df[‘car_type_3’] = (car_type == 3) * 1.0

      df[‘engine_type_1’] = (engine_type == 1) * 1.0
      df[‘engine_type_2’] = (engine_type == 2) * 1.0
      df[‘engine_type_3’] = (engine_type == 3) * 1.0

      这会删除原始列,然后创建 6 列,如果该类型,则值为 1,否则为 0。唯一的缺点是这效率不高,对于数百个特征来说会很繁琐,但这不是一个糟糕的开始。

    • Jason Brownlee 2019年3月6日 上午7:42 #

      你可以尝试将它们建模为零,或者尝试独热编码。也许可以两者都尝试一下,看看哪种方法能带来更好的性能。

      创建编码后,你可以将列添加回 numpy 数组 (hstack) 或数据框。

  53. Constantine 2019年3月29日 上午1:50 #

    嗨!很棒且内容丰富的文章。我只是想问你,我们是否必须在独热编码时删除一列以避免虚拟变量陷阱?我看到有些人说我们应该删除它们,而另一些人似乎不介意关注它,我有点困惑哪种方法是正确的。换句话说,例如,在使用 pandas 的“get_dummies()”时,我们何时应该指定“drop_first=True”。

    谢谢!

    • Jason Brownlee 2019年3月29日 上午8:40 #

      实际上,不用。

      • Constantine 2019年3月29日 下午8:04 #

        所以我们实际上不必这样做,谢谢。

        但是理论上什么时候这样做呢?我很好奇。

        • Constantine 2019年4月2日 上午4:52 #

          在没有正则化的线性回归模型中(理论上)不是这样做的吗?请告诉我!

  54. so 2019年6月13日 上午12:54 #


    在 scikit-learn 的独热编码中,编码后,我如何获得特定单词标签?

    例如,我想获取 (cold) 的整数代码 = ?然后打印 0

  55. rajendra prasad c 2019年7月27日 下午4:25 #

    嗨,Jason Brownlee,
    我发现“hello world”的示例存在问题。
    由于 hello 和 world 之间的空格(' '),出现了错误。

    integer_encoded = [char_to_int[char] for char in data]
    KeyError: ' '

    此致,
    拉詹德拉

  56. mallikarjun 2019年7月31日 下午6:13 #

    嗨,jason,我有一个数据,其中包含分类数据和整数数据。

    当我将分类数据转换为独热编码向量并将其输入到 KNN 聚类算法时

    我得到一个错误,说
    ValueError:使用序列设置数组元素。

    是不是因为我的数组现在包含整数和序列向量?

    如何解决这个问题?

    • Jason Brownlee 2019年8月1日 上午6:46 #

      也许与其使用 OHE,不如尝试对不同的变量类型使用不同的距离度量?

  57. Arthur Mugabi 2019年7月31日 下午8:03 #

    你好
    我如何使用独热编码为机器学习模型准备数据框中的 IP 地址

    • Jason Brownlee 2019年8月1日 上午6:47 #

      好问题。我相信有专门的方法来表示 IP 地址——你可能需要查阅相关文献。

  58. Alex 2019年8月18日 上午5:55 #

    你好 Jason,

    array= ([0, 2, 1, 2, 0])
    paff = to_categorical(array)

    --> 得到 3 个类别,正确

    array= ([3, 2, 1, 2, 3]) 得到 4 个类别(包括空向量)

    为什么会这样?(pd.get_dummies 正确地给我 3 个类别)

    • Jason Brownlee 2019年8月18日 上午6:52 #

      也许可以指定 num_classes 参数?
      https://keras.org.cn/utils/

      • Alex 2019年8月19日 上午4:39 #

        你好 Jason,

        并非如此
        array= ([3, 2, 1, 2, 3])
        paff = to_categorical(array, num_classes=4) #只在 num_classes=4 时有效

        print(paff)

        [[0. 0. 0. 1.]
        [0. 0. 1. 0.]
        [0. 1. 0. 0.]
        [0. 0. 1. 0.]
        [0. 0. 0. 1.]]

        我真的不明白。我既不需要额外的空向量,也不是训练数据总是恰好包含一个 0。这个解决方案总是生成一个带有额外空向量的矩阵,然后你会得到一个 keras 错误,因为你的矩阵比预期大一个维度。不知何故,我感觉我错过了 keras 关于独热编码的一些想法。

        • Jason Brownlee 2019年8月19日 上午6:16 #

          该函数假定类号从 0 开始。

          • Alex 2019年8月19日 下午5:21 #

            没错。我的结论:这是一个奇怪的函数,只有当数据包含 0 时才能正常工作(从逻辑上讲)。否则你必须记住会得到一个更大维度的矩阵。我还是坚持使用 pd.get_dummies() 😉

  59. Ziko 2019年8月18日 下午11:59 #

    嗨 Jason
    我有一个关于独热编码输入的问题,其中目标是连续的。
    为简单起见,假设我有一个连续输出,它线性地依赖于一个连续输入,但其线性依赖性取决于一个独热编码变量。我将非常感谢任何关于如何实现这种系统的帮助。

    • Jason Brownlee 2019年8月19日 上午6:08 #

      独热编码是用于分类数据,而不是实数值。

      如果你想探索编码数值,你可以先将其离散化 + 序数化。

  60. Ziko 2019年8月19日 上午12:05 #

    嗨,抱歉,只是为了确保我的问题被理解,输出=V*输入,而 V 取决于一些分类变量

  61. mRiddle 2019年9月18日 下午3:56 #

    我是唯一一个觉得 Python 作为数据科学和机器学习领域备受赞誉的语言,却不能自动转换简单类别,而 R 的机器学习算法对因子却处理得很好,这有点荒谬吗?

    (诚然,我不是程序员,我喜欢 R)

    • Jason Brownlee 2019年9月19日 上午5:51 #

      这与其说是语言问题,不如说是工具问题。

      R 非常有用,但也非常混乱。

      Python 更精简。我认为有空间为像 caret 这样的库,它封装了 pandas/sklearn/keras/xgboost/等中所有有用的东西。

  62. kumar 2019年9月20日 下午7:04 #

    先生,我如何将标记的 GT 图像作为 python 中的 train_label cnn 来训练我的模型,并使用 categorical_cross_entropy 作为损失函数

  63. Tanzila 2019年10月15日 上午4:05 #

    很棒的教程,Jason Brownlee。

    我按照你的教程,尝试对以下数据应用独热编码。但我对输出感到困惑。你能告诉我,独热编码后的输出是正确还是错误?

    X = [['A', 'G', 'T', 'G', 'T', 'C', 'T', 'A', 'A', 'C'],
    ['A', 'G', 'T', 'G', 'T', 'C', 'T', 'A', 'A', 'C'],
    ['G', 'C', 'C', 'A', 'C', 'T', 'C', 'G', 'G', 'T'],
    ['G', 'C', 'C', 'A', 'C', 'T', 'C', 'G', 'G', 'T'],
    ['G', 'C', 'C', 'A', 'C', 'T', 'C', 'G', 'G', 'T']]
    Y = np.array(X)
    # 独热编码
    print(Y)
    print(Y.shape)
    onehot_encoder = OneHotEncoder(sparse=False)
    onehot_encoded = onehot_encoder.fit_transform(Y)
    print(onehot_encoded)
    print(onehot_encoded.shape)

    输出

    [[1. 0. 0. 1. 0. 1. 0. 1. 0. 1. 1. 0. 0. 1. 1. 0. 1. 0. 1. 0.]
    [1. 0. 0. 1. 0. 1. 0. 1. 0. 1. 1. 0. 0. 1. 1. 0. 1. 0. 1. 0.]
    [0. 1. 1. 0. 1. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 1. 0. 1. 0. 1.]
    [0. 1. 1. 0. 1. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 1. 0. 1. 0. 1.]
    [0. 1. 1. 0. 1. 0. 1. 0. 1. 0. 0. 1. 1. 0. 0. 1. 0. 1. 0. 1.]]
    (5, 20)

    在应用独热编码之前,形状是 (5,10),在应用独热编码之后,数据的形状是 (5,20)。所以,我正在困惑于数据的形状。

    • Jason Brownlee 2019年10月15日 上午6:24 #

      不确定是否正确。

      看起来“一行”是一个字母序列。编码这些字母会为每个字母提供一个二进制向量,这些向量将连接成一个长向量来表示一行。

      因此,行数将保持在 5,每个字母将被编码为 4 元素向量(或其他什么),从而得到一个包含 4*10 个元素的行。

      • Tanzila 2019年10月15日 下午8:30 #

        谢谢 Jason Brownlee 的回复。我也这么认为。应用独热编码后,形状应该是 (5, 40) 而不是 (5,10)。你知道我如何处理这种二维数组进行独热编码吗?

        • Jason Brownlee 2019年10月16日 上午8:02 #

          是的,转换变量并连接结果。

          你可以使用 keras 或 scikit-learn 中的独热编码和 numpy 数组的 concat 函数。

          你具体遇到了什么问题?

          • Tanzila 2019年10月16日 下午4:40 #

            我没听懂你的回答。如何为这个数组的独热编码获得正确的形状?你能给我一个使用二维 numpy 数组进行独热编码的例子吗?

            这是我制作的演示数据。我必须从这样的基因型数据中预测表型。但在此之前,我必须处理数据。

          • Jason Brownlee 2019年10月17日 上午6:23 #

            上面教程中的例子应该有帮助?

            也许这里的一些教程
            https://machinelearning.org.cn/start-here/#nlp

  64. Rouzbeh 2020年1月27日 上午4:25 #

    你好 Jason,
    为了预测癌症生存率,我有很多属性。假设我有 20 个名义分类属性,经过独热编码后,这些列变成了 150 个特征。经过计算,我想知道哪些属性在计算中很重要。这里我只有一些数字,这些数字是属性的变量。我的问题是如何找出哪些特征是重要的。为了澄清我的问题,特征 21、45、56、74、84 是重要的。我如何确定这些数字属于哪里?

    • Jason Brownlee 2020年1月27日 上午7:08 #

      这很有挑战性。

      你可以通过简单的计数来解决,例如,每个变量的 n 个类别连接在一起。

      也许你可以使用 RFE,在你的建模管道中,RFE 在每个变量被独热编码之前使用。这将解决特征选择并提供特征重要性的想法。

  65. Mohrizi 2020年3月16日 下午1:48 #

    在查看了这篇文章后,我不得不面对这个错误,我解决了它,谢谢大家

  66. elisa 2020年5月10日 上午1:23 #

    在 Fashion MNIST 数据集中,我们将每个标签从整数转换为独热编码向量。这些向量的维度是多少?只输入整数值
    这将是什么答案

    • Jason Brownlee 2020年5月10日 上午6:13 #

      独热编码的长度将是类别的数量。10 个类别意味着一个包含 10 个元素的独热编码。

  67. als 2020年6月24日 上午12:05 #

    亲爱的 Jason,

    我们如何预测时间序列问题中分类变量的下一个时间步值?更具体地说,如果你的输入是多个分类变量,是否有可能预测这些多个分类变量在下一个时间步的值?如果是,请给我一个提示,我应该如何做?

    谢谢

    • als 2020年6月24日 上午2:24 #

      在上述问题的延续中,当我将变量转换为独热编码时,我的训练输入的形状将是 (362, 3, 5, 9),其中:(362 是样本数量),(3 是时间步数),(5 是特征数量),(9 是数组长度)。输入形状将如下所示:

      (362, 3, 5, 9)

      [[[[1. 0. 0. 0. 0. 0. 0. 0. 0.]
      [0. 0. 0. 0. 1. 0. 0. 0. 0.]
      [0. 1. 0. 0. 0. 0. 0. 0. 0.]
      [1. 0. 0. 0. 0. 0. 0. 0. 0.]
      [0. 1. 0. 0. 0. 0. 0. 0. 0.]]

      [[1. 0. 0. 0. 0. 0. 0. 0. 0.]
      [0. 0. 0. 0. 1. 0. 0. 0. 0.]
      [0. 1. 0. 0. 0. 0. 0. 0. 0.]
      [1. 0. 0. 0. 0. 0. 0. 0. 0.]
      [0. 1. 0. 0. 0. 0. 0. 0. 0.]]

      [[1. 0. 0. 0. 0. 0. 0. 0. 0.]
      [0. 0. 0. 0. 1. 0. 0. 0. 0.]
      [1. 0. 0. 0. 0. 0. 0. 0. 0.]
      [1. 0. 0. 0. 0. 0. 0. 0. 0.]
      [0. 1. 0. 0. 0. 0. 0. 0. 0.]]]]

      是否有可能将此 4D 数据输入到 CNN 或 LSTM 中,以预测每个特征的下一个时间步,同时考虑这些神经网络所需的 3D 输入?
      如果是,你能给我一个提示如何做到这一点吗?

    • Jason Brownlee 2020年6月24日 上午6:33 #

      yhat = model.predict(newX)

  68. priyanshi pradhan 2020年7月14日 下午8:31 #

    非常好的帖子,感谢分享这些信息。

  69. Sandy 2020年9月9日 上午5:42 #

    非常感谢 Jason。正好及时…

  70. Anton 2020年11月10日 上午9:17 #

    亲爱的 Jason,

    如果我有 3 个输出特征:Out1;Out2;Out3。它们每个的值都在 1 到 5 之间变化,如下所示

    [[0 4 0]
    [0 2 0]
    [1 0 0]
    [2 0 0]
    [2 0 0]
    [2 0 0]
    [1 0 1]
    [0 0 1]
    ……]

    我明白如果我使用 n_unique=5 的独热编码,它将是 15 个输出特征。这大于输入数量。结果很糟糕。

    我如何在这种情况下使用独热编码?

    非常感谢!!

    • Jason Brownlee 2020年11月10日 上午9:38 #

      是的,15 个输入变量。这并不多,有些问题可能有数千个。

      比较一组算法。
      使用相同的算法比较原始数据。
      与使用神经网络的嵌入进行比较。

  71. noureen zafar 2021年1月29日 上午4:03 #

    ValueError: y 应该是一个 1d 数组,但得到的是一个形状为 (7343360, 2) 的数组。
    当转换两个标签时

  72. SULAIMAN KHAN 2021年2月3日 上午3:11 #

    在多分类问题中,如何将上述方法应用于 y-train 和 y-test 中的整数?

  73. Gani 2021年6月16日 下午4:15 #

    你好亲爱的,非常感谢,这真的很有帮助,我有一个疑问,如果可能请澄清一下
    我有数千个文件,其中包含数组形式的总数字,我还有另外 5 个标签,它们分别与相同的数组相关联,每个标签与每个数组数据唯一相关,那么我如何才能实现将 5 个标签中的 1 个标签显示为 0,其余 4 个显示为 1 作为输出,通过加载该数组数据,如果可能,请帮助我。

    • Jason Brownlee 2021年6月17日 上午6:13 #

      抱歉,我不理解你的问题,也许你可以详细说明或重新措辞?

  74. Paulo B. 2021年7月4日 上午2:17 #

    亲爱的 Jason,帖子很棒!
    我从未完全理解的一个问题

    当我们向一个,比如说,普通的 Seq2Seq 模型输入独热向量表示时,到底会发生什么?
    说在训练期间,“黑盒”将独热向量表示“转换”为对应于顺序知识的密集向量表示是正确的吗?
    当我们从头开始训练模型时,向 Seq2Seq 输入密集向量而不是独热向量有什么优势吗?

    再次非常感谢,你的例子帮助了我很多!

    • Jason Brownlee 2021年7月4日 上午6:04 #

      LSTM 将输入作为 [样本、时间步、特征],独热编码输入将是独立的特征。

      密集输入,例如整数编码或嵌入,可能更有效。比较不同方法的性能。

  75. HackerCop 2021年8月29日 上午4:36 #

    谢谢,这真的很清晰易懂。谷歌经常带我到你的网站。

    • Adrian Tam
      Adrian Tam 2021年8月29日 下午12:28 #

      谢谢。很高兴你喜欢。

  76. Davide 2021年9月17日 下午6:31 #

    你好,

    在应用独热编码后,是否有办法执行 mutual_info_regression?如果没有,“排名问题”(LabelEncoder 的特点)是否也会影响 mutual_info_regression 的结果?

    谢谢你

    • Adrian Tam
      Adrian Tam 2021年9月19日 上午6:17 #

      mutual_info_regression 假设目标变量是连续的。如果独热编码应用于特征,我认为它仍然有用。但如果它应用于目标,我表示怀疑,因为误差可能会很大。

  77. korea_papago 2021年10月18日 下午9:28 #

    我读得很好。
    对于分类数据,机器学习无法识别。
    我知道你为什么要做独热编码。
    你为什么对整数进行独热编码?
    机器学习不能识别整数类型吗?

    • Adrian Tam
      Adrian Tam 2021年10月20日 上午9:46 #

      模型可以识别整数类型,但如果你不希望它将整数类型(比如我的电话号码)误解为字面意义上的东西,而实际上它只是一个名称,那么你就进行独热编码。

  78. Mario Garcés 2021年12月15日 下午7:17 #

    亲爱的 Jason。我发现当前的独热编码代码会产生错误的结果。原因是,当你创建字典(第 8 行和第 9 行)时,你使用了相同的“c”变量,并且在执行“ennumerate”函数时它似乎没有重新初始化。如果你在创建后打印这两个字典,你会发现结果是不对称的。
    我通过更改第二个字典中 ennumerate 变量的名称来解决了这个问题。

    非常感谢你非常有用和有趣的博客

    马里奥

    • Adrian Tam
      Adrian Tam 2021年12月17日 上午6:54 #

      感谢指出。但确切的行为应取决于 Python 的版本。最新版本应将“c”的作用域限制在字典推导语法之内,因此应该没问题。对于旧版本,你所说的可能是一个问题。

  79. Mario Garcés 2021年12月15日 下午7:24 #

    抱歉,是我修改代码时犯的错误…… 🙂

  80. Bobby 2022年2月21日 下午7:20 #

    array([1.9 , 1.635, 1.639, …, 1.704, 1.672, 1.596])

    array([[0., 0., 0., …, 0., 1., 0.],
    [0., 0., 0., …, 0., 1., 0.],
    [0., 0., 0., …, 0., 1., 0.],
    ……,
    [0., 0., 0., …, 0., 0., 1.],
    [0., 0., 0., …, 0., 0., 1.],
    [0., 0., 0., …, 0., 0., 1.]])

    我有一个想要预测的数字数组和已经独热编码的星期几

    我将如何创建一个序列并将其拟合到时间序列 LSTM 模型中

  81. Michael 2022年6月15日 上午7:40 #

    当编码器对某一列返回全为“1”的值时,这意味着什么?

  82. veday 2022年6月29日 上午12:32 #

    我有一个问题,假设我们在 RNN 结构中将序列分类为回文或非回文,我们如何在模型中使用独热编码?

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。