【机器学习】一文读懂one-hot和哑变量编码的区别和联系

🔻 one-hot编码

独热编码即 One-Hot 编码,又称一位有效编码。其方法是使用N位状态寄存器来对 N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。

举例如下:

假设我们有四个样本(行),每个样本有三个特征(列),如下:

Feature_1Feature_2Feature_3
Sample_1143
Sample_2232
Sample_3122
Sample_4211

上述feature_1有两种可能的取值,比如是男/女,这里男用1表示,女用2表示。feature_2 和 feature_3 各有4种取值(状态)。

one-hot 编码就是保证每个样本中的单个特征只有1位处于状态1,其他的都是0。

上述状态用 one-hot 编码如下表所示:

Feature_1Feature_2Feature_3
Sample_10 11 0 0 01 0 0
Sample_21 00 1 0 00 1 0
Sample_30 10 0 1 00 1 0
Sample_41 00 0 0 10 0 1

具体一般使用方法B = pd.get_dummies(A)实现。

这个方法其实意思为获得哑变量,但是它可以用于产生one-hot编码,也可以用于产生哑变量编码。

当drop_first=True时为哑变量编码,当为False时为one-hot编码。

🔻one-hot编码和哑变量编码的区别

那么哑变量编码是什么呢?我们可以从两者区别对比来看,如下:

Feature_1one-hotdummy
Sample_110 0 10 1
Sample_220 1 01 0
Sample_331 0 00 0
Sample_440 0 10 1

可以看出:

  • 哑变量编码的生成的特征值比one-hot少一个,也就是比对应特征的种类取值要少1个;
  • 哑变量编码中有(0,0)出现,即可以不出现1,而one-hot编码中每个区值对应的编码有且仅有一个是1。

哑变量编码的这些特征其实是对应的,因为生成的特征比原有的特征种类少一个,所以用(0,0)来表示sample3的feature1既不为1也不为2,默认feature1的值为3。

但是one-hot编码中的特征是二值性的,上述例子代表的意义是:feature1是否为3,feature1是否为2,feature1是否为1。

🔻哑变量编码的优势

哑变量编码其实比较聪明,因为这样的做法避免了多重共线性 (Multicollinearity)问题。

也就是说如果特征变量之间有相关性,模型将很难说出某个变量对目标的影响有多大。


比如说如上图所示,当gender特征变成gender_male和gender_female的时候,这两个特征之间其实是冗余的。因为我们如果gender_male=1,那么gender_female=0,反过来也一样。这个问题在数学中称为多重共线性,在pandas处理的时候有人也叫它虚拟变量陷阱(Dummy Variable Trap)。
对于两个变量以上的情况也一样:

🔻为什么可以用get_dummies(),drop_first=true代替one-hot编码

那么drop_first是什么呢?drop_first的意思是是否删除第一个类别,只保留其他类别的哑变量编码。一般情况下drop_first的默认值是false,也就是说直接把B = pd.get_dummies(A)这个方法当作one-hot编码使用是可行的。

具体看代码:

```#
# one-hot编码
import pandas as pd
from sklearn.preprocessing import OneHotEncoder

# 创建一个示例DataFrame
data = {'color': ['red', 'blue', 'green', 'red', 'blue']}
df = pd.DataFrame(data)

onehot = OneHotEncoder(sparse_output=False)
data_encoded = onehot.fit_transform(df[['color']])

print("one-hot编码结果如下:")
print(data_encoded)
print(type(data_encoded))

# 哑变量编码
# pd.get_dummies()方法即可以用于产生One-Hot编码,也可以用于产生哑变量编码
# 当drop_first=True时为哑变量编码,当为False时为One-Hot编码
data = pd.get_dummies(df['color'], drop_first=True)

print("哑变量编码结果如下:")
print(data)
print(type(data))

运行结果分别是:

在这里插入图片描述

当drop_first=True时,get_dummies()删除了例子中的第一个类别’blue’,保留了’green’和’red’ (第一个类别不是’red’,因为原始输出应该长这样:)

在这里插入图片描述

其中’red’是第一个样本,它的特征’red’为True;对于第二个样本’blue’,它的两个特征均为False,删去的’blue’为True…

当drop_first=False时,可以看到输出结果类似one-hot编码:

data_dummies2 = pd.get_dummies(df['color',drop_first=False])
print("当drop_first=False时,哑变量编码结果如下:")
print(data_dummies2)
print(type(data_dummies2))

在这里插入图片描述
所以get_dummies()方法本体就是one-hot编码,当drop_first=True时,回归了哑变量编码。

🔻如何取舍one-hot编码和哑变量编码

在实际的应用中,比如说模型在这里插入图片描述

其中自变量满足在这里插入图片描述

(模型是one-hot获得的,只有一个状态位为1,其余都为0),所以在这里插入图片描述
,代入得

在这里插入图片描述

在这里插入图片描述

这两个参数是等价的。

为了解决模型的稳定性问题,可以采取三种手段:L2正则化、去除偏置项和使用哑变量代替one-hot编码。

1)L2正则化,给参数的选择加一个限制:选择参数元素值小的为最终参数,这样得到的参数就唯一,模型也就稳定了;

2)去除偏置项在这里插入图片描述
,此时有

在这里插入图片描述

由于去除了偏置项,变成了两个模型,也就不存在参数等价的问题了。

3)在加上偏置项的前提下,使用哑变量代替one-hot编码,这时去除了在这里插入图片描述
,也就不存在前面说的一种特征可以用其他特征表示的问题了。这种方法的好处是保留了固有属性,即偏置项。

🔻总结

当我们使用one-hot编码时,我们的模型不加bias项(或者加bias后用L2正则化约束参数);

当我们使用哑变量编码时,通常我们的模型都会加bias项,因为不加bias项会导致固有属性的丢失。

🔻参考

pandas的get_dummies方法在机器学习中的应用及其陷阱 | 数据学习者官方网站(Datalearner)

离散型特征编码方式:one-hot与哑变量* - ML小菜鸟 - 博客园 (cnblogs.com)


个人学习整理,欢迎大佬指正。

感谢看到这里的你,一起进步!🤞🤞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值