用sklearn.preprocessing做数据预处理(四)——OneHotEncoder

机器学习时,对于离散的特征基本就是按照one-hot(独热)编码,该离散特征有多少取值,就用多少维来表示该特征。

from sklearn import preprocessing
enc = preprocessing.OneHotEncoder()
enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])    # fit来学习编码
enc.transform([[0, 1, 3]]).toarray()    # 进行编码

array([[1., 0., 0., 1., 0., 0., 0., 0., 1.]])

数据矩阵是4*3,即4个数据,3个特征维度。

0 0 3       观察左边的数据矩阵,第一列为第一个特征维度,有两种取值0\1. 所以对应编码方式为10 、01

1 1 0       同理,第二列为第二个特征维度,有三种取值0\1\2,所以对应编码方式为100、010、001

0 2 1       同理,第三列为第三个特征维度,有四中取值0\1\2\3,所以对应编码方式为1000、0100、0010、0001

1 0 2    

再来看要进行编码的参数[0 , 1,  3], 0作为第一个特征编码为10,  1作为第二个特征编码为010, 3作为第三个特征编码为0001.  故此编码结果为 1,0,      0,1,0,       0,0,0,1 

enc.transform([[0,0,3]]).toarray()

array([[1., 0., 1., 0., 0., 0., 0., 0., 1.]])

enc.transform([[1,1,0]]).toarray()

array([[0., 1., 0., 1., 0., 1., 0., 0., 0.]])

为类别特征编码
我们知道特征可能是连续型的也可能是类别型的变量,比如说:[“male”, “female”], [“from Europe”, “from US”, “from Asia”], [“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”].这些类别特征无法直接进入模型,需要用LabelEncoder把它们转换成整数来表征[“male”, “from US”, “uses Internet Explorer”] 转换成 [0, 1, 3] ,[“female”, “from Asia”, “uses Chrome”] 转换成 [1, 2, 1]。
但是上面这种表征的方式仍然不能直接为scikit-learn的模型所用,因为模型会把它们当成序列型的连续变量。要想使得类别型的变量能最终被模型直接使用,可以使用one-of-k编码或者one-hot编码。
这些都可以通过OneHotEncoder实现,它可以将有n种值的一个特征变成n个二元的特征。
特征1中有(0,1)两个值,特征2中有(0,1,2)3个值,特征3中有(0,1,2,3)4个值,所以编码之后总共有9个二元特征。

enc = preprocessing.OneHotEncoder()
enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])
enc.transform([[0,1,3]]).toarray()

array([[1., 0., 0., 1., 0., 0., 0., 0., 1.]])

但是呢,也会存在这样一种情况,某些特征中可能对一些值有缺失,比如明明有两个性别,样本数据中却都是男性,这样会默认被判别为只有一类值,这个时候我们可以向OneHotEncoder传入参数N_values,用来指明每个特征中值的总个数。

enc = preprocessing.OneHotEncoder(n_values=[2,3,4])   #指明每个特征中值的总个数为2 3 4
enc.fit([[1,2,3],[0,2,0]])
enc.transform([[1,0,0]]).toarray()

array([[0., 1., 1., 0., 0., 1., 0., 0., 0.]])

OneHotEncoder不仅对label可以编码,还可以对categorical feature进行编码

from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])

OneHotEncoder(categorical_features=None, categories=None,
       dtype=<class 'numpy.float64'>, handle_unknown='error',
       n_values=None, sparse=True)

# 对象enc的n_values_成员变量,记录着每一个属性的最大取值数目
# 如第一个属性:0 1 0 1 ==> 2
# 如第二个属性:0 1 2 0 ==> 3
# 如第三个属性:3 0 1 2 ==> 4
enc.n_values_

array([2, 3, 4])

对象enc的feature_indices_ 则记录对n_values_的累积值 不过feature_indices_的首位是0

enc.feature_indices_

array([0, 2, 5, 9], dtype=int32)

猜你喜欢

转载自blog.csdn.net/weixin_44530236/article/details/88077991