【机器学习】特征编码OneHot与Dummy的区别与联系

文章介绍了在模型训练中对离散特征进行OneHot编码和Dummy编码的方法。OneHot编码将每个特征的每个取值转化为独立的二进制列,而Dummy编码通过去除一个状态来表示所有类别。Python中使用sklearn库的OneHotEncoder进行OneHot编码,使用pandas的get_dummies进行Dummy编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

在模型的训练过程中,我们会对数据集的连续特征进行离散化操作,如使用简单的线性模型,然后对离散化后的特征进行OneHot编码或哑变量编码。这样通常会使得我们模型具有较强的非线性能力。

二、OneHot编码

思想:

将离散化特征的每一种取值都成是一种状态,若你的这一特征中有N个不同的取值,那么我们就可以将这些特征抽象成N种不同的状态,OneHot编码保证了每一个取值只有一种状态处于“激活态”,也就是说N种状态中只有一个状态值为1,其他状态为0。

假设我们以学历为例,现有小学、中学、大学、硕士、博士五种类别,使用OneHot编码就会得到:

小学 -> [1,0,0,0,0]
中学 -> [0,1,0,0,0]
大学 -> [0,0,1,0,0]
硕士 -> [0,0,0,1,0]
博士 -> [0,0,0,0,1]

Python中的OneHot用法:

from sklearn import preprocessing
array = np.array([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])
print(array)
enc = preprocessing.OneHotEncoder()
enc.fit(array)
print(enc.n_values_) #每个特征对应的最大位数
print(enc.transform([[0,1,3]]).toarray())
 
array([[0, 0, 3],
       [1, 1, 0],
       [0, 2, 1],
       [1, 0, 2]])
array是一个43列的矩阵,每一列对应于一个样本的特征序列,即一个样本有三个特征,4行表示传入了4个样本
[2 3 4]
每个特征对应的位数:观察第一列可知,第一个特征有两个取值0,1;第二个特征有三个取值0,1,2;第三个特征有四个取值0,1,2,3
[[1. 0. 0. 1. 0. 0. 0. 0. 1.]]
故第一个特征的onehot编码是一个两位的01串,第二个特征是一个三位01串,第三个特征是一个四位的0,1

在对非数值型特征进行onehot编码时需要先通过LabelEncoder()将分类变量转换成整数形式,然后通过OneHotEncoder()进行编码,否则会报错误如下:

ValueError: could not convert string to float: '小学'。另外再用OneHotEncoder()进行编码时需为2D array,否则会有如下错误:ValueError: Expected 2D array, got 1D array instead:
array=[3. 0. 2. 4. 1.].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample. 

三、Dummy编码

哑变量编码直观的解释就是任意的将一个状态去除,如学位信息,使用哑变量可以用4个状态就足以反映上述5个类别的信息,也就是我们仅使用前四个状态位就可以表示博士了。因为对于我们的一个研究样本,他如果不是小学生,也不是中学生,大学生、研究生,那他便默认为博士了。所以,用哑变量可以将上述5类表示成:

小学 -> [1,0,0,0]
中学 -> [0,1,0,0]
大学 -> [0,0,1,0]
硕士 -> [0,0,0,1]
博士 -> [0,0,0,0]

Python中的实现如下:

data = ["小学","初中","大学","硕士","博士"]
pd.get_dummies(data,prefix="data")
 
   data_初中  data_博士  data_大学  data_小学  data_硕士
0        0        0        0        1        0
1        1        0        0        0        0
2        0        0        1        0        0
3        0        0        0        0        1
4        0        1        0        0        0
### 关于独热编码的概念 独热编码是一种常见的数据预处理技术,在机器学习数据分析领域被广泛采用。其核心目的是将离散型特征变量转换为连续型特征变量,从而使得这些特征能够更好地适应各种机器学习算法的需求[^1]。 通过独热编码,可以有效地避免数值大小关系对模型的影响。例如,对于类别型数据(如颜色、性别),如果直接将其映射到整数上,则可能引入不必要的顺序或权重意义。而独热编码则会将每个类别转化为独立的二进制向量表示,消除了这种潜在的误导性影响[^3]。 --- ### 独热编码的应用场景 独热编码通常适用于以下几种情况: 1. **分类属性的数据** 当输入数据包含一些具有有限类别的字段时,比如“国家”、“职业”等,可以通过独热编码来扩展成多个布尔类型的列,每列表示该样本是否属于某一特定类别[^2]。 2. **无序多值特性** 如果某些特征本身并没有天然的数量级含义或者逻辑上的先后次序,此时就应该考虑使用 one-hot 编码而不是简单的标签化(Label Encoding)。 3. **增强模型表现力** 对于基于树结构的学习器来说,虽然它们可以直接接受原始形式下的字符串类型输入并自行划分区间;但对于线性回归之类的参数估计方法而言,经过 onehot 处理后的稀疏矩阵往往能带来更好的拟合效果[^4]。 需要注意的是,并不是所有的离散特征都需要做 OneHot 转换——只有当存在上述需求时才应该执行此操作。另外还要注意维度爆炸问题以及内存消耗等问题。 --- ### 实现方式 以下是两种主流编程语言中如何实现独热编码的具体例子: #### Python 中的实现 Python 提供了多种库支持快速完成这项工作,其中最常用的就是 `pandas` `sklearn.preprocessing.OneHotEncoder`. ```python import pandas as pd from sklearn.preprocessing import OneHotEncoder # 示例 DataFrame data = {'color': ['red', 'blue', 'green']} df = pd.DataFrame(data) # 方法一:Pandas get_dummies() pd.get_dummies(df['color']) # 方法二:Sklearn 的 OneHotEncoder encoder = OneHotEncoder(sparse=False) encoded_data = encoder.fit_transform(df[['color']]) print(encoded_data) ``` 这段代码展示了利用 Pandas 函数 `get_dummies()` 或者 Scikit-Learn 类 `OneHotEncoder` 来生成新的特征集合的过程。 #### R 语言中的实现 同样地,在统计分析软件包 R 上也有相应的解决方案可供选用: ```r library(dplyr) library(caret) # 创建测试数据框 colors <- c('red','blue','yellow') df_r <- data.frame(color=colors) # 使用 dummies 包创建虚拟变量 dummy_df <- dummyVars(~ ., data=df_r)$transform(df_r) head(dummy_df) ``` 这里采用了两个不同的途径分别介绍了基础版 (dplyr) 及高级版本 (caret),两者都能达到相同的目的即把原来的因子转变成为若干个0/1标志位组成的宽表布局。 --- ### 总结 综上所述,独热编码是一项非常重要的技能点,它帮助我们解决了许多实际建模过程中遇到的问题。然而也要记住并非任何时候都适合运用这一手段,具体情况具体对待才是王道!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

旅途中的宽~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值