特征工程中的OneHotEncoder与DictVectorizer

OneHotEncoder理解

作用

OneHotEncoder是一个常用的 数据预处理方法,它可以 将离散型变量转换为连续型变量,使之更适于机器学习模型的应用。通常我们会使用Pandas处理数据读入之后,使用OneHotEncoder对离散数据进行转换。

应用场景

OneHotEncoder可以处理多种类型的数据集,其中最具代表性的应用场景是:当我们使用线性回归、逻辑回归等模型时,我们需要对离散型变量进行编码,将其转换为连续型变量。

案例

先看代码

import numpy as np
from sklearn.preprocessing import OneHotEncoder

enc = 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默认是使用 稀疏矩阵作为结果返回的,下面介绍一下稀疏矩阵与数组返回如何转换

po_bhbcaffjabifha

如果希望返回数组,可以使用以下方式

# 获取稀疏矩阵转化为 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())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值