OneHotEncoder理解
作用
OneHotEncoder是一个常用的 数据预处理方法,它可以 将离散型变量转换为连续型变量,使之更适于机器学习模型的应用。通常我们会使用Pandas处理数据读入之后,使用OneHotEncoder对离散数据进行转换。
应用场景
OneHotEncoder可以处理多种类型的数据集,其中最具代表性的应用场景是:当我们使用线性回归、逻辑回归等模型时,我们需要对离散型变量进行编码,将其转换为连续型变量。
案例
先看代码
import numpy as np
from sklearn.preprocessing import OneHotEncoderenc = OneHotEncoder(handle_unknown='ignore')
X = [['Male', 1], ['Female', 3], ['Female', 2]]
#将所有的列都当成object类型进行处理,比如第2列的1,2,3,或者浮点数等等
enc.fit(X)# 打印数组
# array([[0., 1., 1., 0., 0.],
# [1., 0., 0., 0., 1.],
# [1., 0., 0., 1., 0.]])
print(enc.transform(X).toarray())# 打印稀疏矩阵
# (0, 1) 1.0
# (0, 2) 1.0
# (1, 0) 1.0
# (1, 4) 1.0
# (2, 0) 1.0
# (2, 3) 1.0
print(enc.transform(X))
one-hot值
为什么结果会是这样呢?先看数组形式
该数据一共有两个特征
-
第一个特征有两个值
['Male', 'Female']
,那么one-hot
应该有两个二进制位表示,按照字典序,Female在前,为(1,0)
,那么 Male 应当为(0,1)
也即是: -
- Female:(1, 0)
- Male: (0, 1)
-
第二个特征值有三个值
[1,3,2]
,同理,对应以下三个one-hot
值: -
- 1: (1, 0, 0)
- 2: (0, 1, 0)
- 3: (0, 0, 1)
数组形式
根据上面的分析,第一行为 ['Male', 1]
,对应的 one-hot
值为 (0, 1)
以及 (1, 0, 0)
,拼接后就是 (0, 1, 1, 0, 0)
,同理可以得到第二行为 (1, 0, 0, 0, 1)
,第三行为 (1, 0, 0, 1, 0)
,最终拼接后的结果就是
[[0., 1., 1., 0., 0.],[1., 0., 0., 0., 1.],1., 0., 0., 1., 0.]]
稀疏矩阵形式
OneHotEncoder默认是使用 稀疏矩阵作为结果返回的,下面介绍一下稀疏矩阵与数组返回如何转换
如果希望返回数组,可以使用以下方式
# 获取稀疏矩阵转化为 array
enc = OneHotEncoder(handle_unknown='ignore')
enc.transform(X).toarray()# 或者定义 OneHotEncoder 时指定参数 sparse_output为 False(默认为True)
# 老版本这个参数为 sparse,keras1.2 以后变为 sparse_output
enc = OneHotEncoder(handle_unknown='ignore', sparse_output=False)
enc.transform(X)
DictVectorizer理解
作用
将特征与值的映射字典组成的列表转换成向量
案例
from sklearn.feature_extraction import DictVectorizer# 设置sparse=False获得numpy ndarray形式的结果
v = DictVectorizer(sparse=False)
D = [{"foo": 1, "bar": 2}, {"foo": 3, "baz": 1}]# 对字典列表D进行转换,转换成特征矩阵
X = v.fit_transform(D)
# 特征矩阵的行代表数据,列代表特征,0表示该数据没有该特征
# [[2. 0. 1.]
# [0. 1. 3.]]
print(X)# 获取特征列名
# ['bar', 'baz', 'foo']
print(v.get_feature_names())# inverse_transform可以将特征矩阵还原成原始数据
# True
print(v.inverse_transform(X) == D)# 直接进行转换,不先进行拟合的话,无法识别新的特征
# [[0. 0. 4.]]
print(v.transform([{"foo": 4, "unseen_feature": 3}]))
说明
解释一下 fit_transform
后为什么会是
[[2. 0. 1.][0. 1. 3.]
]
观察列表中所有的字典,一共有三个 key,因此结果应当有三列
三个key分别为 foo、bar以及baz,按照字典序,对应的索引为别为:
- bar: 0
- baz: 1
- foo: 2
看看第一个字典,foo为1,那么索引值为2的地方的值为1,bar为2,那么索引为0的地方的值应当为2,因此第一行对应的值为 [2, 0, 1]
同理,第二行对应的值为 [0, 1, 3]
再看一个案例
当特征的值是字符串时,这个转换器将进行一个二进制One-hot编码。
One-hot编码是将特征所有可能的字符串值构造成布尔型值。例如: 特征f有一个值ham,一个值spam,转换后会变成两个特征f=ham和f=spam。
注意:
转换器只会将字符串形式的特征值转换成One-hot编码,数值型的不会转换。
一个字典中样本没有的特征在结果矩阵中的值是0。
#1)实例化一个转换器类 2)调用fir_transform()方法
from sklearn.feature_extraction import DictVectorizer#导包
#下面的data是数据
data=[{'city':'北京','tempreature':100},{'city':'上海','tempreature':60},{'city':'深圳','tempreature':30},]# 实例化一个转换器类
transfer=DictVectorizer(sparse=False)
# 调用一fit_transform()方法
data_new=transfer.fit_transform(data)# [[ 0. 1. 0. 100.]
# [ 1. 0. 0. 60.]
# [ 0. 0. 1. 30.]]
print("看一下转换的结果data_new:\n",data_new)# 这里 city对应的值是字符串,该转换器将会对 city 进行二进制One-hot编码
# 排序为 字符串的 ord 字典序
# ['city=上海', 'city=北京', 'city=深圳', 'tempreature']
print("看一下特征的名字:\n",transfer.get_feature_names())