当前位置: 首页 > news >正文

【深度学习】独热编码(One-Hot Encoding)

独热编码(One-Hot Encoding)

在机器学习中,数据预处理是不可或缺的关键一步。面对各种非数值类型的分类数据(Categorical Data),如何将其转换为机器学习模型能够“理解”的语言呢?独热编码(One-Hot Encoding)便是解决这一问题的方法之一。本文将从独热编码的定义、原理出发,详细介绍其优缺点,并通过Python中的pandasscikit-learn库进行实战演示,助你轻松掌握这一数据预处理技术。

文章目录

  • 独热编码(One-Hot Encoding)
    • 1 什么是独热编码?
    • 2 为什么需要独热编码?
    • 3 独热编码与Softmax输出:从预测概率到最终决策
      • 3.1 分类模型的推理
      • 3.2 分类模型推理中独热编码的应用
      • 3.3 分类模型训练中独热编码的应用
    • 4 独热编码的优缺点
      • 4.1 优点
      • 4.2 缺点
    • 5 Python实战:玩转独热编码
      • 5.1 使用 `pandas.get_dummies()`
      • 5.2 使用 `scikit-learn.preprocessing.OneHotEncoder`
    • 6 何时选择独热编码?
    • 7 总结
  • 参考资料

1 什么是独热编码?

独热编码(One-Hot Encoding),又称一位有效编码,是一种将分类变量转换为数值形式的常用方法。其核心思想是,将一个具有N个不同类别的分类特征转换为N个二元(0或1)特征,其中每个新特征对应原始特征中的一个类别。对于每一个样本,只有代表其原始类别的那个新特征值为1,其余所有新特征值均为0。

举个例子:

假设我们有一个图像分类的任务,其标签有“猫”、“狗”、“兔”。

样本ID类别
1
2
3

经过独热编码后,这个“类别”特征会被转换成三个新的二元特征:“类别猫类别_猫”、“类别狗类别_狗”和“类别兔类别_兔”。

样本ID类别猫类别_猫类别狗类别_狗类别兔类别_兔
1100
2010
3001

正如其名“One-Hot”,在每一行数据中,只有一个新特征是“热”的(值为1)。

2 为什么需要独热编码?

在机器学习中,许多算法,特别是线性模型(如线性回归、逻辑回归)和距离度量相关的算法(如K近邻),都是基于数值计算的。如果直接将“猫”、“狗”、“兔”用数字1、2、3来表示(这种方法称为标签编码 Label Encoding),模型可能会错误地学习到这些类别之间存在有序关系,例如“兔”(3)是“猫”(1)的三倍,或者“狗”(2)大于“猫”(1)。这显然是荒谬的,因为不同类别之间并不存在这样的序数/倍数关系。

独热编码通过将每个类别独立表示为一个特征,完美地解决了这个问题。每个类别都处于一个正交的向量空间中,它们(例如 [1, 0, 0]、[0, 1, 0] 和 [0, 0, 1])之间的距离是相等的,从而消除了标签编码可能引入的虚假顺序关系,让模型能够更准确地学习特征与目标之间的关系。

3 独热编码与Softmax输出:从预测概率到最终决策

3.1 分类模型的推理

假设我们的模型已经训练好,用于对测试集中的猫、狗、兔图片进行三分类的推理(Inference)。
模型最后一层通常会使用Softmax激活函数,它会输出一个概率分布,表示该数据点属于每个类别的概率。
假设某一轮推理得到的Softmax得分(scores)如下:

softmax_scores=[0.1,0.2,0.7]\text{softmax\_scores} = [0.1, 0.2, 0.7]softmax_scores=[0.1,0.2,0.7]

这个列表的四个值分别对应了模型预测该图片为“猫”、“狗”、“兔”的概率。我们可以清晰地看到:

  • P(猫)=0.1(10%)P(\text{猫}) = 0.1 \quad (10\%)P()=0.1(10%)
  • P(狗)=0.2(20%)P(\text{狗}) = 0.2 \quad (20\%)P()=0.2(20%)
  • P(兔)=0.7(70%)P(\text{兔}) = 0.7 \quad (70\%)P()=0.7(70%)

为了得到一个确定的预测结果,我们通常会选择概率最高的那个类别。这通过一个简单的argmax操作即可完成,即找到最大值所在的索引。

argmax(softmax_scores)=2\text{argmax}(\text{softmax\_scores}) = 2argmax(softmax_scores)=2

这个索引 2 正好对应我们类别列表中的第三个类别“兔”。因此,模型的最终预测结果就是“兔”。

3.2 分类模型推理中独热编码的应用

关键点来了:可以将3.1中所述的预测结果也表示为独热编码的形式:[0, 0, 1]

在模型评估时,我们会将这个预测的独热编码 [0, 0, 1] 与真实的标签(Ground Truth)进行比较。如果这个地点的真实标签就是‘广州’(其独热编码也是 [0, 0, 1]),那么这次预测就是正确的。

3.3 分类模型训练中独热编码的应用

在训练过程中,像交叉熵损失函数(Cross-Entropy Loss)这样的工具,也正是通过比较Softmax输出的概率分布(如 [0.1, 0.2, 0.7])和真实的独热编码标签(如 [0, 0, 1])来计算损失,并指导模型进行优化的。

分类模型训练中独热编码的应用

关于对交叉熵损失函数(Cross-Entropy Loss) 的介绍,可以参见我的这一篇文章:【深度学习】深入理解交叉熵损失函数 (Cross-Entropy Loss Function) 。

所以,独热编码也为多分类模型的输出提供了一个清晰、明确的比较基准和目标格式。

4 独热编码的优缺点

4.1 优点

  1. 消除序数关系:如上所述,独热编码能够有效处理没有内在顺序的分类数据,避免模型做出错误的假设。
  2. 提升模型性能:对于线性模型等对特征数值大小敏感的算法,使用独热编码通常能带来更准确的预测结果。
  3. 易于理解和实现:其概念直观,并且在主流的Python数据科学库中都有非常便捷的实现。

4.2 缺点

  1. 维度灾难(Curse of Dimensionality):当一个分类特征的类别数量非常多(即高基数特征,High Cardinality),独热编码会产生大量的稀疏特征(大部分值为0),导致数据集的维度急剧膨胀。这不仅会增加计算复杂度和内存消耗,还可能降低模型的性能,尤其是在树模型中。
  2. 信息冗余:由于N个新特征中,只要知道了前N-1个的值,最后一个的值就可以推断出来(例如,如果“类别猫类别_猫”和“类别狗类别_狗”都为0,那么“类别兔类别_兔”必然为1)。这种现象被称为“虚拟变量陷阱”(Dummy Variable Trap),可能导致多重共线性问题。在实践中,通常会通过丢弃其中一列来解决。

5 Python实战:玩转独热编码

接下来,我将通过两个最常用的Python库——pandasscikit-learn来演示如何实现独热编码。

5.1 使用 pandas.get_dummies()

pandas库提供了get_dummies()函数,这是实现独热编码最简单快捷的方式之一。

import pandas as pd# 创建一个示例DataFrame
data = {'city': ['北京', '上海', '广州', '深圳', '北京'],'temperature': [25, 30, 28, 32, 26]}
df = pd.DataFrame(data)print("原始数据:")
print(df)# 对 'city' 列进行独热编码
df_dummies = pd.get_dummies(df, columns=['city'])print("\n使用 get_dummies 进行独热编码后的数据:")
print(df_dummies)# 为了避免多重共线性,可以设置 drop_first=True
df_dummies_dropped = pd.get_dummies(df, columns=['city'], drop_first=True)
print("\n使用 get_dummies (drop_first=True) 后的数据:")
print(df_dummies_dropped)

代码解析:

  • pd.get_dummies(df, columns=['city']) 会自动识别city列中的所有唯一类别,并为每个类别创建一个新的二元列。
  • 设置drop_first=True参数会自动丢弃第一个类别(按字母顺序,这里是“广州”)对应的列,从而解决了虚拟变量陷阱的问题。

5.2 使用 scikit-learn.preprocessing.OneHotEncoder

scikit-learn是专业的机器学习库,其OneHotEncoder提供了更强大和灵活的功能,尤其是在构建机器学习流水线(Pipeline)时。与pandas不同,scikit-learn的编码器通常需要先对分类数据进行整数编码。

import pandas as pd
from sklearn.preprocessing import OneHotEncoder, LabelEncoder# 创建一个示例DataFrame
data = {'city': ['北京', '上海', '广州', '深圳', '北京'],'temperature': [25, 30, 28, 32, 26]}
df = pd.DataFrame(data)# 步骤1: 使用 LabelEncoder 将分类文本转换为整数
label_encoder = LabelEncoder()
df['city_encoded'] = label_encoder.fit_transform(df['city'])print("LabelEncoder 转换后的数据:")
print(df)# 步骤2: 使用 OneHotEncoder 进行独热编码
# 需要将数据转换为二维数组
onehot_encoder = OneHotEncoder(sparse_output=False) # sparse_output=False 返回numpy数组
encoded_data = onehot_encoder.fit_transform(df[['city_encoded']])# 将编码后的数据转换回 DataFrame,并添加有意义的列名
encoded_df = pd.DataFrame(encoded_data, columns=onehot_encoder.get_feature_names_out(['city']))# 合并回原始DataFrame (并删除临时列)
df_final = df.join(encoded_df).drop(columns=['city_encoded'])print("\n使用 scikit-learn OneHotEncoder 后的数据:")
print(df_final)

代码解析与对比:

  • LabelEncoder:首先将’北京’、'上海’等字符串映射为0、1、2等整数。
  • OneHotEncoder:接着将这些整数转换为独热编码。fit_transform方法需要一个二维数组作为输入,因此我们使用df[['city_encoded']]
  • sparse_output=False:默认情况下,OneHotEncoder返回一个稀疏矩阵以节省内存。在这里我们设置为False以便于观察,它将返回一个标准的NumPy数组。
  • get_feature_names_out():这个方法可以帮助我们获取编码后新特征的名称。
  • 为何使用scikit-learn 虽然pandas的方法更直接,但在机器学习工作流中,scikit-learn的编码器更具优势。例如,你可以在训练集上fit一个编码器,然后用这个相同的编码器transform测试集,这可以保证训练集和测试集上特征的一致性,避免因类别不匹配而导致的错误。它还可以无缝集成到sklearn.pipeline.Pipeline中,实现数据预处理和模型训练的自动化。

6 何时选择独热编码?

  • 当分类特征的类别数量较少时(通常建议在15个以下),独热编码是一个非常好的选择。
  • 当特征是名义类别(Nominal Category),即类别之间没有顺序关系时(如颜色、城市、性别),应该使用独热编码。
  • 对于树模型(如决策树、随机森林、梯度提升树),虽然它们对特征的数值大小不敏感,但高维度的稀疏数据可能会影响其分裂点的选择效率。因此,当类别数非常多时,可以考虑其他编码方式(如目标编码、频率编码等)。

7 总结

独热编码是数据预处理武器库中一件强大而基础的工具。它通过将分类数据转换为模型友好的数值格式,解决了序数假设问题,为许多机器学习算法的成功应用铺平了道路。通过掌握pandasget_dummiesscikit-learnOneHotEncoder,你将能够根据不同的场景和需求,灵活高效地处理数据,为构建高性能的机器学习模型打下坚实的基础。在实际应用中,请务必注意其可能带来的维度灾难问题,并结合业务理解选择最合适的编码策略。


参考资料

  1. 深入浅出 one-hot
http://www.lryc.cn/news/603270.html

相关文章:

  • 怎么提升服务器的防攻击能力!
  • day064-kodbox接入对象存储与配置负载均衡
  • 「源力觉醒 创作者计划」 百度AI的战略“惊蛰”,一场重塑格局的“破壁行动”
  • JSON在java中的使用
  • 力扣热题100--------240.搜索二维矩阵
  • 半导体企业选用的跨网文件交换系统到底应该具备什么功能?
  • Spring Boot 请求限流实战:基于 IP 的高效防刷策略
  • Qt 并行计算框架与应用
  • 重塑浏览器!微软在Edge加入AI Agent,自动化搜索、预测、整合
  • [明道云]-基础教学2-工作表字段 vs 控件:选哪种?
  • nodejs 实现Excel数据导入数据库,以及数据库数据导出excel接口(核心使用了multer和node-xlsx库)
  • 架构实战——互联网架构模板(“用户层”和“业务层”技术)
  • 向量内积:揭示方向与相似性的数学密码
  • 瑞盟NFC芯片,MS520
  • 网上买卖订单处理手忙脚乱?订单处理工具了解一下
  • Radash.js 现代化JavaScript实用工具库详解 – 轻量级Lodash替代方案
  • python优秀案例:基于机器学习算法的景区旅游评论数据分析与可视化系统,技术使用django+lstm算法+朴素贝叶斯算法+echarts可视化
  • 机器学习、深度学习与数据挖掘:三大技术领域的深度解析
  • uipath数据写入excel的坑
  • perf工具在arm上的安装记录
  • 机器学习、深度学习与数据挖掘:核心技术差异、应用场景与工程实践指南
  • p5.js 从零开始创建 3D 模型,createModel入门指南
  • 新升级超值型系列32位单片机MM32G0005
  • p5.js 三角形triangle的用法
  • 逻辑回归算法
  • [源力觉醒 创作者计划]_文心大模型4.5开源:从技术突破到生态共建的国产AI解读与本地部署指南
  • 单片机学习笔记.PWM
  • hive专题面试总结
  • 墨者:SQL过滤字符后手工注入漏洞测试(第1题)
  • 2.oracle保姆级安装教程