【sklearn】数据预处理之独热编码(含两种实现方式+代码理解)

最近学习机器学习,接触到独热编码相关内容,参考了一些资料,加上自己的思考,做出了如下总结:

一、什么是独热编码

独热编码,即One-Hot编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。

说起来这么复杂,举个例子就很容易理解了:

比如爱吃的水果有3种:苹果、葡萄和橙子,转换成独热编码分别表示为(此时上述描述中的N=3):001, 010, 100。(当然转换成100, 010, 001也可以,只要有确定的一一对应关系即可)。

那么提出一个问题,苹果、葡萄和橙子分别转换成1, 2, 3行不行?

一般不这样处理,这样处理也不叫独热编码了,只能说是文本转换成数字,具体原因可以往下看。

二、为什么要进行独热编码

在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的。而常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。

使用独热编码(One-Hot Encoding),将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点。将离散型特征使用独热编码(One-Hot Encoding),会让特征之间的距离计算更加合理。

接下来举例说明:

我们选取离散型特征,共有五个取值,不使用独热编码(One-Hot Encoding),其表示分别是:

演员 =0;厨师 =1;公务员 =2;工程师 =3;律师 =4

两个工作之间的距离是:

d(演员,厨师) = 1
d(厨师,公务员) = 1
d(公务员,工程师) = 1
d(工程师,律师) = 1
d(演员,公务员) = 2
d(演员,工程师) = 3

显然这样的表示,计算出来的特征的距离是不合理。那如果使用独热编码(One-Hot Encoding),则得到d(演员,厨师) = 1与d(演员,公务员)都是1。那么,两个工作之间的距离就都是sqrt(2)。即每两个工作之间的距离是一样的,显得更合理。

此处参考文章为:

https://www.jianshu.com/p/42e93acacc52

三、如何用Python实现独热编码

方法1:get_dummies

将类别变量转换成虚拟变量/指示变量,也叫哑变量。

我们看一下它的定义:

pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, 
                   sparse=False, drop_first=False, dtype=None)

各参数的含义:

data: array-like, Series, or DataFrame

prefix: string, list of strings, or dict of strings, default None

prefix_sep: str, default ‘_’ (转换后列名的前缀)

dummy_na: bool, default False(增加一列表示空缺值,如果False就忽略空缺值)

columns: list-like, default None (指定需要实现类别转换的列名)

sparse: bool, default False

drop_first: bool, default False (获得k中的k-1个类别值,去除第一个)

dtype: dtype, default np.uint8

举例说明一下:

import numpy as np
import pandas as pd
s=pd.Series(list('abcd'))
s_=pd.get_dummies(s)
print(s_)

我们看一下结果:

   a  b  c  d
0  1  0  0  0
1  0  1  0  0
2  0  0  1  0
3  0  0  0  1

我们换一种表示方法:

import numpy as np
import pandas as pd
s=pd.Series(list('abcd'))
s_=pd.get_dummies(s,drop_first=True)
print(s_)
   b  c  d
0  0  0  0
1  1  0  0
2  0  1  0
3  0  0  1

再来看一个例子:

import numpy as np
import pandas as pd
df=pd.DataFrame({'city':['hang zhou','shang hai','bei jing'],'population':[20,32,51],'class':['A','A+','A+']})
print(df)
df_=pd.get_dummies(df)
print(df_)

首先看一下df的输出结果:

        city  population class
0  hang zhou          20     A
1  shang hai          32    A+
2   bei jing          51    A+

看一下df_的输出结果:

   population  city_bei jing  city_hang zhou  city_shang hai  class_A  class_A+
0          20              0               1               0        1         0
1          32              0               0               1        0         1
2          51              1               0               0        0         1

方法2:sklearn

Sklearn提供了一个编码器OneHotEncoder,用于将整数分类值转换成独热向量。

我们举一个例子:

from scipy.io import loadmat
from sklearn.preprocessing import OneHotEncoder

dataset=loadmat('neural_network_dataset.mat')
print('数据集展示为:\n',dataset)

展示一下数据集的样子:

数据集展示为:
 {'__header__': b'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Sun Oct 16 13:09:09 2011', '__version__': '1.0', '__globals__': [], 'X': array([[0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       ...,
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.]]), 'y': array([[10],
       [10],
       [10],
       ...,
       [ 9],
       [ 9],
       [ 9]], dtype=uint8)}

接下来我们把标签向量转换为独热向量:

X=dataset['X']
y=dataset['y']
encoder=OneHotEncoder(sparse=False)
y_onehot=encoder.fit_transform(y)
print(y[0])
print(y_onehot[0,:])

我们看一下输出结果:

[10]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]

你可能感兴趣的:(机器学习系列文章,sklearn,机器学习,独热向量)