sklearn中的几种二值化编码函数:OneHotEncoder, LabelEncoder , LabelBinarizer

1.自定义一些简单的数据集

定义3个特征, age 和 salary 都是数值型, pet 是字符串型

#coding=gbk
#几种sklearn 中的二值化编码函数,
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import LabelBinarizer
from sklearn.preprocessing import MultiLabelBinarizer

columns = ['pet','age','salary']
data = pd.DataFrame([['cat','dog','dog','fish'],[4,6,3,3],[4,5,1,1]])
data = data.T   #对二维数组进行转置
data.columns = columns
print(data)
#     pet age salary
# 0   cat   4      4
# 1   dog   6      5
# 2   dog   3      1
# 3  fish   3      1

2.对数值型变量二值化

使用OneHotEncoder 函数

注意: sklearn 的新版本中,OneHotEncoder 的输入必须是 2-D array

#1. OneHotEncoder 独热编码的使用
#True 则返回一个array, False 则返回matrix矩阵
onehot_age = OneHotEncoder(sparse=False).fit_transform(data[['age']]) 
 
print(data['age'].shape)    #(4,)
print(data[['age']].shape)  #(4, 1)
#由于 OneHotEncoder 的编码必须是 2-D array ,而data.age 即 data['age']返回的是 1-D array,所以要改成上述的双中括号
print(onehot_age)
# [[0. 1. 0.]
#  [0. 0. 1.]
#  [1. 0. 0.]
#  [1. 0. 0.]]

onehot_salary = OneHotEncoder(sparse= False)._fit_transform(data[['salary']])   #两个输出都是一样的
output = np.hstack((onehot_age, onehot_salary))  #记住括号是双括号,使其在列上合并
print(output)
# [[0. 1. 0. 0. 1. 0.]
#  [0. 0. 1. 0. 0. 1.]
#  [1. 0. 0. 1. 0. 0.]
#  [1. 0. 0. 1. 0. 0.]]
# onehot_pet = OneHotEncoder(sparse=False).fit_transform(data[['pet']]) 不能直接对字符串的类别进行编码
test = OneHotEncoder(sparse=False).fit_transform(data[['age','salary']])
print(test) #可以同时输入两个特征值,可以接受多列输入
# [[0. 1. 0. 0. 1. 0.]
#  [0. 0. 1. 0. 0. 1.]
#  [1. 0. 0. 1. 0. 0.]
#  [1. 0. 0. 1. 0. 0.]]

3.对字符型变量二值化

注意:OneHotEncoder无法直接对字符串型的类别变量编码

 无论 LabelEncoder() 还是 LabelBinarizer(),他们在 sklearn 中的设计初衷,都是为了解决标签 y的离散化,而非输入X, 所以他们的输入被限定为 1-D array,这恰恰跟OneHotEncoder() 要求输入 2-D array 相左。

 方法一 先用 LabelEncoder() 转换成连续的数值型变量,再用 OneHotEncoder() 二值化 
* 方法二 直接用 LabelBinarizer() 进行二值化 

#2,对字符串类型二值化
#方法1 使用 LabelEncoder + OneHotEncoder
le_pet = LabelEncoder().fit_transform(data.pet)
print(le_pet)   #[0 1 1 2]
print(le_pet.shape) # (4,) 是一维数组
print(le_pet.reshape(-1,1).shape) # (4, 1) 将其转换成 4 行 1列
oe_pet = OneHotEncoder(sparse=False).fit_transform(le_pet.reshape(-1,1))
print(oe_pet)
# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

#方法2 直接使用 labelBinarizer ,设计是为了解决y 的离散化的
lb_pet = LabelBinarizer().fit_transform(data.pet)
print(lb_pet)   #同样可以得到同样的输出,只是 dtype 不相同
# [[1 0 0]
#  [0 1 0]
#  [0 1 0]
#  [0 0 1]]

print('-----')
mb = MultiLabelBinarizer().fit_transform(data[['age','salary']].values)
print(mb)
# [[0 0 1 0 0]
#  [0 0 0 1 1]
#  [1 1 0 0 0]
#  [1 1 0 0 0]]

4使用 pandas 自带的 get_dummies 函数

#使用 pandas 自带的 get_dummies 函数
gd = pd.get_dummies(data, columns = columns)
print(gd)
#  pet_cat  pet_dog  pet_fish  age_3  age_4  age_6  salary_1  salary_4  \ .....
# 0        1        0         0      0      1      0         0         1   
# 1        0        1         0      0      0      1         0         0   
# 2        0        1         0      1      0      0         1         0   
# 3        0        0         1      1      0      0         1         0 

get_dummies的优势: 
* 1.本身就是 pandas 的模块,所以对 DataFrame 类型兼容很好. 
* 2.无论你的列是字符型还是数字型都可以进行二值编码. 
* 3.能根据用户指定,自动生成二值编码后的变量名. 

  get_dummies无法像 sklearn 的transformer一样可以输入到pipeline中 进行流程化地机器学习过程, 而且get_dummies 不像 sklearn 的 transformer一样,有 transform方法,所以一旦测试集中出现了训练集未曾出现过的特征取值,简单地对测试集、训练集都用 get_dummies 方法将导致数据错误。 

 参考:http://blog.csdn.net/haramshen/article/details/53169963

猜你喜欢

转载自blog.csdn.net/qq_40587575/article/details/81118610