关于Onehot编码的总结

简介: 关于Onehot编码的总结

目录


一、什么是one-hot编码?


二、为什么要用onehot


三、什么情况下使用onehot


四、使用举例:


一、什么是one-hot编码?

One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。


One-Hot编码是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值。然后,每个整数值被表示为二进制向量,除了整数的索引之外,它都是零值,它被标记为1。


一句话概括:one hot编码是将类别变量转换为机器学习算法易于利用的一种形式的过程。


二、为什么要用onehot

假设我们有一个迷你数据集:


公司名


类别值


价格


小米


1


5000


华为


2


10011


中兴


3


50000


中兴


3


10000


在上面的表格中,类别值从1开始,更符合日常生活中的习惯。实际项目中,类别值从0开始(因为大多数计算机系统计数),所以,如果有N个类别,类别值为0至N-1.


sklear的LabelEncoder可以帮我们完成这一类别值分配工作。


根据标签编码的类别值,我们的迷你数据集中小米> 华为> 中兴。比方说,假设模型内部计算平均值(神经网络中有大量加权平均运算),那么1 + 3 = 4,4 / 2 = 2. 这意味着:VW和Honda平均一下是Acura。毫无疑问,这是一个糟糕的方案。该模型的预测会有大量误差。


我们使用one hot编码器对类别进行“二进制化”操作,然后将其作为模型训练的特征,原因正在于此。


当然,如果我们在设计网络的时候考虑到这点,对标签编码的类别值进行特别处理,那就没问题。不过,在大多数情况下,使用one hot编码是一个更简单直接的方案。如下表:


小米


华为


中兴


价格


1


0


0


5000


0


1


0


10011


0


0


1


50000


0


0


1


10000


注:如果原本的标签编码是有序的,那one hot编码就不合适了——会丢失顺序信息。


三、什么情况下使用onehot

对于定类类型的数据,建议使用one-hot encoding。定类类型就是纯分类,不排序,没有逻辑关系。比如性别分男和女,男女不存在任何逻辑关系,我们不能说男就比女好,或者相反。再者,中国各省市分类也可以用独热编码,同样各省不存在逻辑关系,这时候使用one-hot encoding会合适些。但注意,一般会舍去一个变量,比如男的对立面肯定是女,那么女就是重复信息,所以保留其中一个变量即可。

对于定序类型的数据,建议使用label encoding。定序类型也是分类,但有排序逻辑关系,等级上高于定类。比如,学历分小学,初中,高中,本科,研究生,各个类别之间存在一定的逻辑,显然研究生学历是最高的,小学最低。这时候使用Label encoding会显得更合适,因为自定义的数字顺序可以不破坏原有逻辑,并与这个逻辑相对应。

对数值大小敏感的模型必须使用one-hot encoding或者Dummy。典型的例子就是LR和SVM。二者的损失函数对数值大小是敏感的,并且变量间的数值大小是有比较意义的。而Label encoding的数字编码没有数值大小的含义,只是一种排序,因此对于这些模型都使用one-hot encoding。

对数值大小不敏感的模型(如树模型)不建议使用one-hot encoding。一般这类模型为树模型。如果分类类别特别多,那么one-hot encoding会分裂出很多特征变量。这时候,如果我们限制了树模型的深度而不能向下分裂的话,一些特征变量可能就因为模型无法继续分裂而被舍弃损失掉了。因此,此种情况下可以考虑使用Label encoding


四、使用举例:

from sklearn.preprocessing import OneHotEncoder
import pandas as pd
data =[['法师', 40, 14000],
 ['辅助', 30, 13000],
 ['坦克', 31, 12000],
 ['射手', 30, 14000],
 ['法师', 32, 11000]]
data = pd.DataFrame(data, columns=['role', 'changci', 'output'])
# print (data)
# 在One-Hot编码之前先将带中文的标称属性转换成数值型
# 用简单整数替代
listUniq = data.loc[:, 'role'].unique()  # 去重
# 对匹配的元素赋值,不匹配的元素保持原样
for j in range(len(listUniq)):
    data.loc[:, 'role'] = data.loc[:, 'role'].apply(lambda x: j if x == listUniq[j] else x)
print(data)
# 用数字给文本属性赋值,保证赋值过的不会重新再赋值
# lambda x:j if x == listUniq[j] else x
# 遍历len(listUniq)次 data.loc[:,'role']
# 发现data.loc[:,'role'] 中有元素与listUniq的元素相同,就赋相对应的整数值
# 开始One-Hot编码
temp = data[['role']]
enc = OneHotEncoder()
enc.fit(temp)
# 将Matrix类型转换为array类型
temp = enc.transform(temp).toarray()
tempdata = pd.DataFrame(temp,columns=['role1','role2','role3','role4'])
tempdata['changci']=data[['changci']]
tempdata['output']=data[['output']]
print(tempdata)

运行结果:

tt.png


目录
相关文章
|
8月前
|
JavaScript 数据安全/隐私保护
41 # 编码的问题
41 # 编码的问题
40 0
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
编码和解码的未来之路
编码和解码的未来之路
|
11月前
|
存储 Java 数据安全/隐私保护
什么是编码和解码
什么是编码和解码
234 0
|
JavaScript
编码
编码
71 0
数制与编码
十进制整数转换为二进制数 可以将十进制数逐次用2除,取余数,一直到商为0.然后把全部余数按相反的次序排列起来。(除二取余)
264 0
数制与编码
|
存储 算法 Java
【字符编码】字符编码 && Base64编码算法
  在前面的解决乱码的一文中,只找到了解决办法,但是没有为什么,说白了,就是对编码还是不是太熟悉,编码问题是一个很简单的问题,计算机从业人员应该也必须弄清楚,基于编码的应用有Base64加密算法,然后,这个问题一直放着,想找个机会解决。于是乎,终于逮到机会,开始下手。
185 0
【字符编码】字符编码 && Base64编码算法
|
Java
编码小结3
java中编码问题
1246 0
|
Java
编码小结2
编码小结2
1268 0

热门文章

最新文章