定义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
使用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.]]
注意: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]]
#使用 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