基于 Jupyter 的特征工程手册之数据预处理二.docx
《基于 Jupyter 的特征工程手册之数据预处理二.docx》由会员分享,可在线阅读,更多相关《基于 Jupyter 的特征工程手册之数据预处理二.docx(17页珍藏版)》请在冰豆网上搜索。
![基于 Jupyter 的特征工程手册之数据预处理二.docx](https://file1.bdocx.com/fileroot1/2022-12/1/28290e2b-972f-418c-9710-81374a6c9b07/28290e2b-972f-418c-9710-81374a6c9b071.gif)
基于Jupyter的特征工程手册之数据预处理二
本项目将探讨数据预处理部分:
介绍了如何利用scikit-learn处理静态的连续变量,利用CategoryEncoders处理静态的类别变量以及利用Featuretools处理常见的时间序列变量。
特征工程的数据预处理我们将分为三大部分来介绍:
∙静态连续变量
∙静态类别变量
∙时间序列变量
本文将介绍静态类别变量的数据预处理(上部分,即1.2.1-1.2.6)。
下面将结合Jupyter,使用sklearn,进行详解。
1.2 StaticCategoricalVariables静态类别变量
真实世界的数据集还往往包含类别特征。
但是由于scikit-learn中的模型只能处理数值特征,因此我们需要将类别特征编码为数值特征但是,很多新的模型开始直接提供类别变量支持,例如lightGBM和Catboost。
这里我们使用category_encoders包,因为它涵盖了更多的编码方法。
1.2.1 OrdinalEncoding序数编码
序数编码将类别变量转化为一列序数变量,包含从1到类别数量之间的整数
1.2.2 One-hotEncoding独热编码
Scikit-learn中也提供来独热编码函数,其可以将具有n_categories个可能值的一个分类特征转换为n_categories个二进制特征,其中一个为1,所有其他为0在category_encoders中,它包含了附加功能,即指示缺失或未知的值。
在这里,我们继续使用category_encoders
encoder=OneHotEncoder(cols=['Sex','Type'],
handle_unknown='indicator',
handle_missing='indicator',
use_cat_names=True).fit(train_set,train_y)#在训练集上训练
encoded_train=encoder.transform(train_set)
#转换训练集
encoded_test=encoder.transform(test_set)
#转换测试集#将handle_unknown设为‘indicator’,即会新增一列指示未知特征值#将handle_missing设为‘indicator’,即会新增一列指示缺失值#其他的handle_unknown/handle_missing的选择为:
#‘error’:
即报错;‘return_nan’:
即未知值/缺失之被标记为nan;‘value’:
即未知值/缺失之被标记为0
#以测试集结果为例
encoded_test
#在独热编码中:
#变量Sex=>变为了4个新变量:
'male'=>[1,0,0,0];
#'female'=>[0,1,0,0];
#未知=>[0,0,0,1];
#缺失=>[0,0,1,0];
#变量Type=>变为了5个新变量:
10=>[1,0,0,0,0];
#20=>[0,1,0,0,0];,
#15=>[0,0,1,0,0];
#未知=>[0,0,0,0,1];
#缺失=>[0,0,0,1,0];
1.2.3 HashingEncoding哈希编码
哈希编码基于特征哈希的方法。
它将哈希函数应用于变量,将任意数量的变量以一定的规则映射到给定数量的变量。
特征哈希可能会导致要素之间发生冲突。
但哈希编码的优点是它不需要制定和维护原变量与新变量之间的映射关系。
因此,哈希编码器的大小及复杂程度不随数据类别的增多而增多。
importnumpyasnp
importpandasaspd
fromcategory_encoders.hashing
importHashingEncoder#category_encoders直接支持dataframe
#随机生成一些训练集
train_set=pd.DataFrame(np.array([['male',10],['female',20],['male',10],['female',20],['female',15]]),
columns=['Sex','Type'])
train_y=np.array([False,True,True,False,False])
#随机生成一些测试集,并有意让其包含未在训练集出现过的类别与缺失值
test_set=pd.DataFrame(np.array([['female',20],['male',20],['others',15],
['male',20],['female',40],['male',25]]),
columns=['Sex','Type'])
test_set.loc[4,'Type']=np.nan
train_set#原始训练集
test_set#原始测试集
encoder=HashingEncoder(cols=['Sex','Type'],n_components=5).fit(train_set,train_y)
encoded_train=encoder.transform(train_set)
#转换训练集
encoded_test=encoder.transform(test_set)
#转换测试集
#将两列的数据集哈希编码为5列
#哈希编码结果与训练集/测试集中的内容无关#只要列名匹配,我们就可以在任何新数据集上使用哈希编码方法#编码结果仅由哈希函数确定
#通常哈希编码应用于更高和更稀疏的维空间,这里以两个变量作为哈希编码的例子#以测试集结果为例
encoded_test
encoded_train#训练集结果
1.2.4 HelmertEncodingHelmert编码
Helmert编码通常在计量经济学中使用。
在Helmert编码(分类特征中的每个值对应于Helmert矩阵中的一行)之后,线性模型中编码后的变量系数可以反映在给定该类别变量某一类别值的情形下因变量的平均值与给定该类别其他类别值的情形下因变量的平均值的差值。
在category_encoders包中实现的Helmert编码为反向Helmert编码。
train_set#原始训练集
test_set#原始测试集
encoder=HelmertEncoder(cols=['Sex','Type'],handle_unknown='indicator',handle_missing='indicator').fit(train_set,train_y)
#在训练集上训练
encoded_train=encoder.transform(train_set)
#转换训练集
encoded_test=encoder.transform(test_set)
#转换测试集#将handle_unknown设为‘indicator’,即会新增一列指示未知特征值#将handle_missing设为‘indicator’,即会新增一列指示缺失值#其他的handle_unknown/handle_missing的选择为:
#‘error’:
即报错;‘return_nan’:
即未知值/缺失之被标记为nan;‘value’:
即未知值/缺失之被标记为0
#以测试集结果为例
encoded_test
#在Helmert编码中:
#变量Sex=>变为了4个新变量(包含常数项):
'male'=>[1.-1.-1.-1.];
#'female'=>[1.1.-1.-1.];
#未知=>[1.0.0.3.];
#缺失=>[1.0.2.-1.];#变量Type=>变为了5个新变量(包含常数项):
10=>[1.-1.-1.-1.-1.];
#20=>[1.1.-1.-1.-1.];,
#15=>[1.0.2.-1.-1.]
;#未知=>[1.0.0.0.4.];
#缺失=>[1.0.0.3.-1.];
#可以通过如下代码计算变量Type的Helmert矩阵
frompatsy.contrastsimportHelmert
levels=[1,2,3,4,5]
#3个变量值+1个未知值+1个缺失值
contrast=Helmert().code_with_intercept(levels)
print(contrast.matrix)
#第一列为常数项
encoded_train#训练集结果
1.2.5 Sum(Deviation)Encoding偏差编码
偏差编码也通常在计量经济学中被使用。
偏差编码后,线性模型的系数可以反映该给定该类别变量值的情况下因变量的平均值与全局因变量的平均值的差异。
train_set#原始训练集
test_set#原始测试集
#可以通过如下代码计算变量Type的Deviation矩阵
frompatsy.contrastsimportSumlevels=[1,2,3,4,5]
#3个变量值+1个未知值+1个缺失值
contrast=Sum().code_with_intercept(levels)
print(contrast.matrix)
#第一列为常数项
encoded_train#训练集结果
1.2.6 TargetEncoding目标编码
目标编码是一种不仅基于特征值本身,还基于相应因变量的类别变量编码方法。
对于分类问题:
将类别特征替换为给定某一特定类别值的因变量后验概率与所有训练数据上因变量的先验概率的组合。
对于连续目标:
将类别特征替换为给定某一特定类别值的因变量目标期望值与所有训练数据上因变量的目标期望值的组合。
该方法严重依赖于因变量的分布,但这大大减少了生成编码后特征的数量。
公式:
其中min_samples_leaf和smoothing是用户定义的参数;
min_samples_leaf:
计算类别平均值时的最小样本数(即若该类别出现次数少,则将被忽略),用以控制过拟合;
smoothing:
平衡分类平均值与先验平均值的平滑系数。
其值越高,则正则化越强;
𝑋′𝑘是类别特征X中类别为k的编码值;
PriorProb:
目标变量的先验概率/期望;
n:
类别特征X中,类别为k的样本数;
𝑛+:
不仅在类别特征X中具有类别k,而且具有正结果的样本数(分类问题);
importnumpyasnp
importpandasaspd
fromcategory_encoders.target_encoder
importTargetEncoder
#category_encoders直接支持dataframe
#随机生成一些训练集
train_set=pd.DataFrame(np.array([['male',10],['female',20],
['male',10],['female',20],['female',15]]),columns=['Sex','Type'])
train_y=np.array([False,True,True,False,False])
#随机生成一些测试集,并有意让其包含未在训练集出现过的类别与缺失值
test_set=pd.DataFrame(np.array([['female',20],['male',20],['others',15],['male',20],['female',40],['male',25]]),
columns=['Sex','Type'])
test_set.loc[4,'Type']=np.nan
train_set#原始训练集
test_set#原始测试集
#验证一下计算的结果,在测试集中,‘male’类别的编码值为0.473106
prior=train_y.mean()
#先验概率
min_samples_leaf=1.0
#默认为1.0
smoothing=1.0
#默认为1.0
n=2
#训练集中,两个样本包含‘male’这个标签
n_positive=1
#在训练集中,这两个包含‘male’标签的样本中仅有一个有正的因变量标签
𝑠𝑚𝑜𝑜𝑣𝑒=1/(1+np.exp(-(n-min_samples_leaf)/smoothing))
male_encode=prior*(1-𝑠𝑚𝑜𝑜𝑣𝑒)+𝑠𝑚𝑜𝑜𝑣𝑒*n_positive/nmale_encode
#return0.4731058578630005,与要验证的值吻合
encoded_train#训练集结果