独热编码(one-hot coding)

1 为什么需要独热编码?
    直接上案例,一份数据,特征为["颜色", "尺码", "喜欢度", "类别"],具体数据为[['green','M', 10.1,'class1'], ['red','L', 13.5,'class2'], ['blue','XL', 15.3,'class1']]。
    这几项中,喜欢度直接是数值型,不用管。类别是label,先不说。对于颜色与尺码这两项,应该如何编码?
    先说尺码,尺码的编码形式应该是{"M": 1, "L": 2, "XL": 3},直接转换成数字的形式。那么颜色这一项是否可行?直接将颜色字段编码为{"green":1, "red": 2, "blue": 3},这样似乎否可行?
    先上结论,这样不行。我们在模型训练的时候,会对特征做什么?无非就是计算距离。那现在计算green,red,blue三个的距离。d(green, red)=2-1=1,d(red, blue)=3-2=1,d(green, blue)= 3-1=2。问题来了,这几个颜色之间的差距,应该是一样的。都是不同的颜色,不应该映射到欧氏空间,距离不等。这就是这种编码的问题所在。颜色这个离散特征之间没有大小的意义,应该使用独热编码。
    那么型号这个字段可以吗?回答是可以的。同样计算距离。d(M,L)=2-1=1,d(L, XL)=3-2=1,d(M,XL)=3-1=2。XL是真的比M大两号的。当离散特征的取值有大小的意义,就应该使用这种数值映射。

2 独热编码现成的包
     现成的包有不少,我就说一个,这个简单,能用就行了。pandas自带了独热编码的方法,get_dummies()。用起来很简单。还是以上边的例子。

import pandas as pd

data = pd.DataFrame([['green', 'M', 10.1, 'class1'], ['red', 'L', 13.5, 'class2'], ['blue', 'XL', 15.3, 'class1']])
data.columns = ['color', 'size', 'prize', 'class label']
size_d = {"M": 1, "L": 2, "XL": 3}
data["size"] = data["size"].map(size_d )
lable = {"class1": 1, "class2": 2}
data["class label"] = data["class label"].map(lable)
df = pd.get_dummies(data)
df.head()
   size  prize  class label  color_blue  color_green  color_red
0     1   10.1            1           0            1          0
1     2   13.5            2           0            0          1
2     3   15.3            1           1            0          0

3 独热编码的优缺点

优点:独热编码解决了分类器不好处理属性数据的问题,在一定程度上也起到了扩充特征的作用。它的值只有0和1,不同的类型存储在垂直的空间。
缺点:当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hot encoding+PCA这种组合在实际中也非常有用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。