关于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.

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

根据标签编码的类别值,我们的迷你数据集中小米> 华为> 中兴。比方说,假设模型内部计算平均值(神经网络中有大量加权平均运算),那么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。典型的例子就是LRSVM。二者的损失函数对数值大小是敏感的,并且变量间的数值大小是有比较意义的。而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)

运行结果:

关于Onehot编码的总结

上一篇:Cesium之鼠标事件绑定和移除


下一篇:Cesium加载天地图