最近学习机器学习,接触到独热编码相关内容,参考了一些资料,加上自己的思考,做出了如下总结:
独热编码,即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
将类别变量转换成虚拟变量/指示变量,也叫哑变量。
我们看一下它的定义:
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
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.]