目录:OneHot与Dummy
一、前言
在模型的训练过程中,我们会对数据集的连续特征进行离散化操作,如使用简单的线性模型,然后对离散化后的特征进行OneHot编码或哑变量编码。这样通常会使得我们模型具有较强的非线性能力。
二、OneHot编码
思想:
将离散化特征的每一种取值都成是一种状态,若你的这一特征中有N个不同的取值,那么我们就可以将这些特征抽象成N种不同的状态,OneHot编码保证了每一个取值只有一种状态处于“激活态”,也就是说N种状态中只有一个状态值为1,其他状态为0。
假设我们以学历为例,现有小学、中学、大学、硕士、博士五种类别,使用OneHot编码就会得到:
小学 -> [1,0,0,0,0]
中学 -> [0,1,0,0,0]
大学 -> [0,0,1,0,0]
硕士 -> [0,0,0,1,0]
博士 -> [0,0,0,0,1]
Python中的OneHot用法:
from sklearn import preprocessing
array = np.array([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])
print(array)
enc = preprocessing.OneHotEncoder()
enc.fit(array)
print(enc.n_values_) #每个特征对应的最大位数
print(enc.transform([[0,1,3]]).toarray())
array([[0, 0, 3],
[1, 1, 0],
[0, 2, 1],
[1, 0, 2]])
array是一个4行3列的矩阵,每一列对应于一个样本的特征序列,即一个样本有三个特征,4行表示传入了4个样本
[2 3 4]
每个特征对应的位数:观察第一列可知,第一个特征有两个取值0,1;第二个特征有三个取值0,1,2;第三个特征有四个取值0,1,2,3
[[1. 0. 0. 1. 0. 0. 0. 0. 1.]]
故第一个特征的onehot编码是一个两位的0、1串,第二个特征是一个三位0、1串,第三个特征是一个四位的0,1串
在对非数值型特征进行onehot编码时需要先通过LabelEncoder()将分类变量转换成整数形式,然后通过OneHotEncoder()进行编码,否则会报错误如下:
ValueError: could not convert string to float: '小学'。另外再用OneHotEncoder()进行编码时需为2D array,否则会有如下错误:ValueError: Expected 2D array, got 1D array instead:
array=[3. 0. 2. 4. 1.].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
三、Dummy编码
哑变量编码直观的解释就是任意的将一个状态去除,如学位信息,使用哑变量可以用4个状态就足以反映上述5个类别的信息,也就是我们仅使用前四个状态位就可以表示博士了。因为对于我们的一个研究样本,他如果不是小学生,也不是中学生,大学生、研究生,那他便默认为博士了。所以,用哑变量可以将上述5类表示成:
小学 -> [1,0,0,0]
中学 -> [0,1,0,0]
大学 -> [0,0,1,0]
硕士 -> [0,0,0,1]
博士 -> [0,0,0,0]
Python中的实现如下:
data = ["小学","初中","大学","硕士","博士"]
pd.get_dummies(data,prefix="data")
data_初中 data_博士 data_大学 data_小学 data_硕士
0 0 0 0 1 0
1 1 0 0 0 0
2 0 0 1 0 0
3 0 0 0 0 1
4 0 1 0 0 0