Sklearn之One-hot编码(编码方式、作用、适用场景)

  • Post author:
  • Post category:其他



(作者:陈玓玏)

一、为什么要用做One-hot编码?

在建模过程中,我们通常会碰到各种类型的属性,如果是标称型属性,也就是不具备序列性、不能比较大小的属性,通常我们不能用简单的数值来粗暴替换。因为属性的数值大小会影响到权重矩阵的计算,不存在大小关系的属性,其权重也不应该发生相应的变化,那么我们就需要用到One-hot编码(也有人称独热编码)这种特殊的编码方式了。

二、One-hot编码是什么?

来看一个简单的例子:假设我们有一个特征是自有房和无自有房,样本情况如下:

 data = [['自有房',40,50000],
        ['无自有房',22,13000],
        ['自有房',30,30000]]

编码后的样本矩阵变为:

 data = [[1,0,40,50000],
        [0,1,22,13000],
        [1,0,30,30000]]

也就是说,一个属性如果有N个可取值,它就可以扩充为N个属性,每个样本的这N个属性中,只能有一个为1,表示该样本的该属性属于这个类别,其余扩展属性都为0。

三、Sklearn实现One-hot编码

one-hot编码属于变量预处理,所以需要在sklearn.preprocessing包中先引入。

from sklearn.preprocessing import OneHotEncoder
import pandas as pd

#原始数据集
data = [['自有房',40,50000],
        ['无自有房',22,13000],
        ['自有房',30,30000]]
data = pd.DataFrame(data,columns=['house','age','income'])
print(data)

#把带中文的标称属性转换为数值型,因为one-hot编码也需要先转换成数值型,用简单整数代替即可
listUniq = data.ix[:,'house'].unique()
for j in range(len(listUniq)):
    data.ix[:,'house'] = data.ix[:,'house'].apply(lambda x:j if x==listUniq[j] else x)
print(data)

#进行one-hot编码
tempdata = data[['house']]
print(tempdata)
enc = OneHotEncoder()
enc.fit(tempdata)

#one-hot编码的结果是比较奇怪的,最好是先转换成二维数组
tempdata = enc.transform(tempdata).toarray()
print(tempdata)
print('取值范围整数个数:',enc.n_values_)

#再将二维数组转换为DataFrame,记得这里会变成多列
tempdata = pd.DataFrame(tempdata,columns=['house']*len(tempdata[0]))
print(tempdata)

#每一步都输出结果看一看

四、One-hot编码适用算法

据我现在的经验,one-hot用在GBDT、XGBoost这些模型里面都挺好的,但是用在逻辑回归里不行。因为逻辑回归要求变量间相互独立,如果你只有一个属性需要做one-hot编码还好,如果你有多个属性需要做one-ont编码,那么当某个样本的多个one-hot属性同时为1时,这两个属性就完全相关了,必然会导致singular error,也就是非奇异矩阵不能求解唯一解,得不出唯一的模型,但是你又不可能把同一个属性的某一个one-hot延伸变量删除。

如果在逻辑回归中入模标称属性,可以直接替换成数值,然后做woe变换,用每个类别的woe值来代替原来的数值,这样既能够避免生成相关性强的变量,又能避开类别间大小无法比较的问题。



版权声明:本文为weixin_39750084原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。