一个很隐晦的问题
特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间,所以往往默认数据数据是连续的(可以计算距离?),并且是有序的。但是有时用数字表示的数据并不是有序的,而是随机分配的。
举个例子:有一个离散型特征,代表工作类型,该离散型特征,共有三个取值,不使用one-hot编码,其表示分别是x_1 = (1), x_2 = (2), x_3 = (3)。两个工作之间的距离是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那么x_1和x_3工作之间就越不相似吗?显然这样的表示,计算出来的特征的距离是不合理。那如果使用one-hot编码,则得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那么两个工作之间的距离就都是sqrt(2).即每两个工作之间的距离是一样的,显得更合理。
独热编码是啥
独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。独热编码恰好是一种解决上述问题的好办法。不过数据也因此变得稀疏。
独热编码的好处:
解决了分类器不好处理属性数据的问题,让特征之间的距离计算更加合理
在一定程度上也起到了扩充特征的作用,比如性别本身是一个特征,经过one hot编码以后,就变成了男或女两个特征。
将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。
什么时候不适合编码呢?
离散数据也可以归一化?
离散特征进行one-hot编码后,编码后的特征,其实每一维度的特征都可以看做是连续的特征。就可以跟对连续型特征的归一化方法一样,对每一维特征进行归一化。比如归一化到[-1,1]或归一化到均值为0,方差为1。
独热编码实现方法比较
1、pandas自带的get_dummies()【适合含有字符串类型的数据】
问题:get_dummies 没有sklearn 的 transformer方法,所以一旦测试集中出现了训练集未曾出现过的特征取值,简单地对测试集、训练集都用 get_dummies 方法将导致数据错误也无法像 sklearn 的transformer一样可以输入到pipeline中 进行流程化地机器学习过程。
2、sklearn的OneHotEncoder()【适合只含数值型的数据】
通过 OneHotEncoder() 自带的 feature_indices_ 可以知道哪几列对应哪个原来的特征
LabelEncoder() + OneHotEncoder() 可实现,但需数据格式转换)