首先需要明确,哪些模型需要进行进行离散变量的哑变量编码。
模型名称 | 是否需要哑变量编码 |
---|---|
逻辑回归 | 需要 |
catboost | 明确要求不能进行哑变量编码,否则影响模型速度和效果 |
首先是自然数排序方法,该方法的过程较为简单,即先对离散字段的不同取值进行排序,然后对其进行自然数值取值转换,可以使用sklearn中的OrdinalEncoder转化器。
from sklearn import preprocessing
X1 = np.array([['F'], ['M'], ['M'], ['F']])
enc = preprocessing.OrdinalEncoder()
enc.fit(X1)
enc.transform(X1)
评估器的训练过程就相当于记录了原分类变量不同的取值和自然数之间的对应关系,我们可以调用转化器如下属性来查看映射关系:
enc.categories_
对于独热编码的使用,有一点需要额外注意,就是二分类离散变量来说,独热编码没有实际作用。因此 很多时候我们在独热编码转化的时候会考虑只对多分类离散变量进行转化,而保留二分类离散变量的原始取值。 此时就需要将OneHotEncoder中drop参数调整为'if_binary',以表示跳过二分类离散变量列。
默认是不带字段名的,字段名补齐需要封装函数:
# 将上述的流程封装成一个函数:
def cate_colName(Transformer, category_cols, drop='if_binary'):
"""
离散字段独热编码后字段名创建函数
:param Transformer: 独热编码转化器
:param category_cols: 输入转化器的离散变量
:param drop: 独热编码转化器的drop参数
"""
cate_cols_new = []
col_value = Transformer.categories_
for i, j in enumerate(category_cols):
if (drop == 'if_binary') & (len(col_value[i]) == 2):
cate_cols_new.append(j)
else:
for f in col_value[i]:
feature_name = j + '_' + f
cate_cols_new.append(feature_name)
return(cate_cols_new)
调用:
#category_cols 是离散列名的列表 df_cate是离散列的dataframe
enc = preprocessing.OneHotEncoder(drop='if_binary')
pd.DataFrame(enc.transform(df_cate).toarray(), columns=cate_colName(enc, category_cols))
在执行单独的转化器时,我们需要单独将要转化的列提取出来,然后对其转化,并且在转化完成后再和其他列拼接成新的数据集。尽管很多时候表格的拆分和拼接不可避免,但该过程显然不够“自动化”。在sklearn的0.20版本中,加入了ColumnTransformer转化流水线评估器,使得上述情况得以改善。该评估器和pipeline类似,能够集成多个评估器(转化器),并一次性对输入数据的不同列采用不同处理方法,并输出转化完成并且拼接完成的数据。
from sklearn.compose import ColumnTransformer
from sklearn import preprocessing
#numeric_cols 代表连续型的变量名列表 category_cols代表离散型变量名列表
preprocessing_col = ColumnTransformer([
('cat', preprocessing.OneHotEncoder(drop='if_binary'), category_cols),
('num', 'passthrough', numeric_cols)
])
而此时preprocess_col则表示对数据集的离散变量进行多分类独热编码处理,对连续变量不处理。如果从效果上看,preprocess_col和我们单独使用多分类独热编码处理离散变量过程并无区别,但实际上我们更推荐使用preprocess_col来进行处理,原因主要有以下几点:其一,通过preprocess_col处理后的数据集无需再进行拼接工作,preprocess_col能够直接输出离散变量独热编码+连续变量保持不变的数据集;其二,preprocess_col过程还能够对未选择的字段进行删除或者保留、或者统一再使用某种转化器来进行转化(默认是删除其他所有列),通过remainder参数来进行说明。例如,我们现在可以借助preprocess_col直接对tcc数据集进行离散变量独热编码、连续变量保留、以及剔除ID列和标签列的操作。
**说明1:**列在transformer中的列被自动剔除了。这个是根据remainder参数控制,'drop'代表剔除是默认值,'passthrough'是默认保留,也可以使用某种estimator去转化。
**说明2:**需要特别注意的是这个结果的字段顺序,是完全按照estimator的顺序来的。
同样,需要对字段名进行补齐:
# 转化后离散变量列的名称
category_cols_new = cate_colName(preprocessing_col.named_transformers_['cat'], category_cols)
# 所有字段的名称
cols_new = category_cols_new + numeric_cols
# 最终的dataframe
pd.DataFrame(preprocessing_col.transform(tcc), columns=cols_new)