独热编码(One-Hot)及其代码

       在机器学习算法中,常会遇到分类特征是非数值型的离散、无序的数据。例如,一组数据包含三个字段,分别为性别、地区、工作,性别字段包含“男”、“女”两个值,城市字段可能包括“北京”、“上海”、“深圳”等值。

       在训练算法前,可以将这些非数值型的离散字段值先转化为有序的整数。如将“性别”字段中所有可能出现字段值 ["男","女"] 对应地转化为 [0,1],将“地区”字段中所有可能出现的字段值 ["北京","上海,"深圳"] 对应地转化为 [ 0,1,2],将“工作”字段中所有可能出现的字段值 ["演员","厨师","公务员","工程师","律师"] 对应地转化为 [0,1,2,3,4]。比如,有一样本,其原始值为:(女,北京,工程师),则可以对应的转化为(1,0,3),但是,这样的特征处理并不能直接用来训练机器学习算法,因为,从非数值型转化为数值型,可能改变同一字段内各字段值之间的关系,具体原因在下面会分析。解决这类问题,一种解决方法是采用独热编码(One-Hot Encoding)。

什么是独热编码

        独热编码(One-Hot Encoding),又称一位有效编码,其方法是对针对某一个字段,若该字段有N个不同的状态值,则使用N位状态寄存器来对N个状态进行编码,每一位状态寄存器的值只能为0或1,每个状态都有它独立的寄存器位与之对应,即该状态对应的寄存器位置1,其它N-1位寄存器置0。 

       回到一开始的例子,性别字段只有 ["男","女"] 这两个不同的状态值(特征值),这时性别字段对应的独热编码就包括2位,性别字段中所有的“男”这个值转化后的独热编码为“10”,性别字段中所有的“女”这个值转化后的独热编码为“01”。

       地区字段只有 ["北京","上海,"深圳"] 这三个不同的状态值(特征值),这时地区字段对应的独热编码就包括3位,地区字段中所有的“北京”这个值转化后的独热编码为“100”,相应的所有“上海”这个值被转化为“010”,所有“深圳”这个值被转化为“001”

        同样的原理,工作字段只有 ["演员","厨师","公务员","工程师","律师"] 这5个同的状态值(特征值),这时工作字段对应的独热编码就包括5位,工作字段中所有的“演员”这个值转化后的独热编码为“10000”,相应的,“厨师”=>“ 01000”,“公务员” => “00100”,“工程师” => “00010”,“律师” => “00001”。

        所以,值为 ["女","北京","工程师"]的样本,独热编码(One-Hot Encoding)的结果为:
[0,1,10,0,00,0,1,0]

为什么要进行独热编码

       在机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的。而常用的距离或相似度的计算都是在欧式空间里进行计算。使用独热编码(One-Hot Encoding),将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征进行独热编码(One-Hot Encoding),会让特征之间的距离计算更加合理。比如,上面的工作特征,该离散型特征,共有五个取值,不使用独热编码(One-Hot Encoding),其表示分别是:

       演员 = (0) ,厨师 = (1) ,公务员 = (2),工程师 = (3) ,律师 = (4)

       基于以上表示,部分工作之间的距离为: d(演员,厨师) = 1,d(厨师,公务员) = 1,d(演员,公务员) = 2,d(演员,工程师) = 3,显然这样的表示,计算出来的特征的距离是不合理。

        那如果使用独热编码(One-Hot Encoding),演员=10000,厨师= 01000,公务员= 00100,工程师=00010,律师=00001,那么,任意两个工作之间的距离就都是sqrt(2)。即任意两个工作之间的距离是一样的,显得更合理。

使用独热编码相关注意事项
       缺点:当某字段里不同值的数量很多时,特征空间会变得非常大,成为一个高维稀疏矩阵。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。

       什么情况不用独热编码:进行one-hot编码的作用,是为了让距离计算更合理,但如果不用one-hot编码就可以很合理的计算出距离,那么就没必要进行one-hot编码。 有些基于树的算法在处理变量时,并不是基于向量空间度量,数值只是个类别符号,所以不用进行独热编码。  如果原本某字段的值是包含有顺序、级别信息的,如学历字段中“大专”、“本科”、“研究生”等字段值,工资字段中的“低收入”、“中收入”、“高收入”等字段值,本身就都包含了顺序与级别信息,这时就不能用独热编码了,因为会丢失顺序信息。

         总的来说,要是one hot encoding的类别数目不太多,建议优先考虑。 

使用独热编码相关代码

import numpy as np
Y = np.array([2,1,4,1,3,0])#Y代表为一个字段
class_num  = 5 #字段中不同状态值的数量
Y = np.eye(Y.shape[0], class_num)[Y.reshape(Y.shape[0])] #转化为独热编码
print(Y)

以上代码运行结果为

[0. 0. 1. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 1.]
 [0. 1. 0. 0. 0.]
 [0. 0. 0. 1. 0.]
 [1. 0. 0. 0. 0.]]

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值