【机器学习技巧】之特征工程:数字编码以及One-hot独热编码的几种方式(sklearn与pandas处理方式)

本文主要对OneHot独热编码进行了简单介绍,同时介绍了在sklearn与pandas中进行数字编码以及One-hot独热编码的几种方式。

目录

  • 1. OneHot独热编码介绍
    • 1.1 为什么要用One-hot编码?
    • 1.2 One-hot举例
    • 1.3 One-hot使用范围
  • 创建基础数据
  • 2. sklearn机器学习中Onehot编码方式
    • 2.1 将分类特征进行数字编码---LabelEncoder将分类特征数字化
    • 2.2 Onehot编码方法一:LabelEncoder后使用OneHotEncoder
    • 2.3 Onehot编码方法二:直接对文本使用LabelBinarizer
    • 2.4 Onehot编码方法三:DictVectorizer
  • 3. Pandas中Onehot编码方式
    • 3.1 Pandas将分类特征进行数字编码方式--pd.factorize()
    • 3.2 Onehot编码--pd.get_dummies()
  • 4. 总结

1. OneHot独热编码介绍

1.1 为什么要用One-hot编码?

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

1.2 One-hot举例

data = pd.DataFrame([
            [ 'M', 10.1], 
            [ 'L', 13.5], 
            [ 'XL', 15.3],
            [ 'XL', 16.3]])

One-hot编码后变为:

data = array([[0, 1, 0, 10.1],
[1, 0, 0, 13.5],
[0, 0, 1, 15.3],
[0, 0, 1, 16.3]])

1.3 One-hot使用范围

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

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

创建基础数据

import pandas as pd
import numpy as np
data = pd.DataFrame([
            ['yellow', 'M', 10.1, 'class1'], 
            ['red', 'L', 13.5, 'class2'], 
            ['blue', 'XL', 15.3, 'class1'],
            ['green', 'XL', 16.3, 'class3']])
 
data.columns = ['颜色', '大小', '价格', '类别标签']
data
颜色 大小 价格 类别标签
0 yellow M 10.1 class1
1 red L 13.5 class2
2 blue XL 15.3 class1
3 green XL 16.3 class3

2. sklearn机器学习中Onehot编码方式

2.1 将分类特征进行数字编码—LabelEncoder将分类特征数字化

from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
category = encoder.fit_transform(data['颜色'])
print("颜色编码:",category)
print("编码对应的颜色:",encoder.classes_)
颜色编码: [3 2 0 1]
编码对应的颜色: ['blue' 'green' 'red' 'yellow']

但是LabelEncoder一次只能处理一个属性,因此需要使用循环分别对属性进行处理

columns = ['颜色','大小','类别标签']
data2 = data.copy()
for column in columns:
    data2[column] = encoder.fit_transform(data[column])
    print("{}编码顺序:{}".format(column, encoder.classes_))
data2
颜色编码顺序:['blue' 'green' 'red' 'yellow']
大小编码顺序:['L' 'M' 'XL']
类别标签编码顺序:['class1' 'class2' 'class3']
颜色 大小 价格 类别标签
0 3 1 10.1 0
1 2 0 13.5 1
2 0 2 15.3 0
3 1 2 16.3 2

2.2 Onehot编码方法一:LabelEncoder后使用OneHotEncoder

from sklearn.preprocessing import OneHotEncoder
columns = ['颜色','大小','类别标签']
enc = OneHotEncoder()
# 将['颜色','大小','类别标签']这3列进行独热编码
enc.fit_transform(data2[columns]).toarray()
array([[0., 0., 0., 1., 0., 1., 0., 1., 0., 0.],
       [0., 0., 1., 0., 1., 0., 0., 0., 1., 0.],
       [1., 0., 0., 0., 0., 0., 1., 1., 0., 0.],
       [0., 1., 0., 0., 0., 0., 1., 0., 0., 1.]])

2.3 Onehot编码方法二:直接对文本使用LabelBinarizer

LabelBinarizer 每次也只能对一个特征进行独热编码,需要使用循环对每个特征进行编码

from sklearn.preprocessing import LabelBinarizer
enc = LabelBinarizer()
transform_data = enc.fit_transform(data['颜色'])
transform_data
array([[0, 0, 0, 1],
       [0, 0, 1, 0],
       [1, 0, 0, 0],
       [0, 1, 0, 0]])
transform_data = enc.fit_transform(data['大小'])
transform_data
array([[0, 1, 0],
       [1, 0, 0],
       [0, 0, 1],
       [0, 0, 1]])

2.4 Onehot编码方法三:DictVectorizer

from sklearn.feature_extraction import DictVectorizer
dict = DictVectorizer(sparse=False)
dict_data= dict.fit_transform(data.to_dict(orient="records"))
dict_data
array([[10.1,  0. ,  1. ,  0. ,  1. ,  0. ,  0. ,  0. ,  0. ,  0. ,  1. ],
       [13.5,  1. ,  0. ,  0. ,  0. ,  1. ,  0. ,  0. ,  0. ,  1. ,  0. ],
       [15.3,  0. ,  0. ,  1. ,  1. ,  0. ,  0. ,  1. ,  0. ,  0. ,  0. ],
       [16.3,  0. ,  0. ,  1. ,  0. ,  0. ,  1. ,  0. ,  1. ,  0. ,  0. ]])
# 查看各列标签名称
dict.get_feature_names()
['价格',
 '大小=L',
 '大小=M',
 '大小=XL',
 '类别标签=class1',
 '类别标签=class2',
 '类别标签=class3',
 '颜色=blue',
 '颜色=green',
 '颜色=red',
 '颜色=yellow']

3. Pandas中Onehot编码方式

3.1 Pandas将分类特征进行数字编码方式–pd.factorize()

data_category, data_class = pd.factorize(data['大小'])
print(data_category)
print(data_class)
[0 1 2 2]
Index(['M', 'L', 'XL'], dtype='object')

3.2 Onehot编码–pd.get_dummies()

data_oneHot = pd.get_dummies(data)
data_oneHot
价格 颜色_blue 颜色_green 颜色_red 颜色_yellow 大小_L 大小_M 大小_XL 类别标签_class1 类别标签_class2 类别标签_class3
0 10.1 0 0 0 1 0 1 0 1 0 0
1 13.5 0 0 1 0 1 0 0 0 1 0
2 15.3 1 0 0 0 0 0 1 1 0 0
3 16.3 0 1 0 0 0 0 1 0 0 1

4. 总结

综合上述方法:
个人认为下面两种方式转化为One_hot类型特征最方便:

  1. sklearn中使用DictVectorizer
  2. Pandas中使用pd.get_dummies

你可能感兴趣的:(机器学习实战,sklearn,python,Onehot编码,数字编码)