专栏 | 基于 Jupyter 的特征工程手册:数据预处理(二)

简介: 专栏 | 基于 Jupyter 的特征工程手册:数据预处理(二)

基于 Jupyter 的特征工程手册:数据预处理的上一篇:


专栏 | 基于 Jupyter 的特征工程手册:数据预处理(一)


项目地址:

https://github.com/YC-Coder-Chen/feature-engineering-handbook


本项目将探讨数据预处理部分:介绍了如何利用 scikit-learn 处理静态的连续变量,利用 Category Encoders 处理静态的类别变量以及利用 Featuretools 处理常见的时间序列变量。


目录


特征工程的数据预处理我们将分为三大部分来介绍:


  • 静态连续变量
  • 静态类别变量
  • 时间序列变量


本文将介绍 1.2 静态类别变量的数据预处理(上部分,即1.2.1-1.2.6)。下面将结合 Jupyter,使用 sklearn,进行详解。


image.png

1.2 Static Categorical Variables 静态类别变量


真实世界的数据集还往往包含类别特征。但是由于scikit-learn中的模型只能处理数值特征,因此我们需要将类别特征编码为数值特征但是,很多新的模型开始直接提供类别变量支持,例如lightGBM和Catboost。这里我们使用category_encoders包,因为它涵盖了更多的编码方法。


1.2.1 Ordinal Encoding 序数编码


序数编码将类别变量转化为一列序数变量,包含从1到类别数量之间的整数

import numpy as np
import pandas as pd
from category_encoders import OrdinalEncoder
# 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

image.png

encoder = OrdinalEncoder(cols = ['Sex', 'Type'], 
                         handle_unknown = 'value', 
                         handle_missing = 'value').fit(train_set,train_y) # 在训练集上训练
# 将 handle_unknown设为‘value’,即测试集中的未知特征值将被标记为-1
# 将 handle_missing设为‘value’,即测试集中的缺失值将被标记为-2
# 其他的选择为:‘error’:即报错;‘return_nan’:即未知值/缺失之被标记为nan 
encoded_train = encoder.transform(train_set) # 转换训练集
encoded_test = encoder.transform(test_set) # 转换测试集
# 以测试集结果为例
encoded_test
# 在序数编码中:
# 变量Sex中: 'male' => 1.0, 'female' => 2.0, 未知 => -1.0, 缺失值 => -2.0
# (事实上,测试集中完全有可能出现未知与缺失情况)
# 在我们的例子中, Sex这一变量中的'other' 类别从未在训练集中出现过
# 变量 Type 中: 10 => 1.0, 20 => 2.0, 15 => 3.0, 未知 => -1.0, 缺失值 => -2.0

image.png


1.2.2 One-hot Encoding 独热编码


Scikit-learn中也提供来独热编码函数,其可以将具有n_categories个可能值的一个分类特征转换为n_categories个二进制特征,其中一个为1,所有其他为0在category_encoders中,它包含了附加功能,即指示缺失或未知的值。在这里,我们继续使用category_encoders

import numpy as np
import pandas as pd
from category_encoders import OneHotEncoder
# 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

image.png

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];

image.png

import numpy as np
import pandas as pd
from category_encoders.hashing import HashingEncoder
# 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

image.png

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

image.png

1.2.4 Helmert Encoding Helmert 编码


Helmert编码通常在计量经济学中使用。在Helmert编码(分类特征中的每个值对应于Helmert矩阵中的一行)之后,线性模型中编码后的变量系数可以反映在给定该类别变量某一类别值的情形下因变量的平均值与给定该类别其他类别值的情形下因变量的平均值的差值。在category_encoders包中实现的Helmert编码为反向Helmert编码。更多信息:


https://www.statsmodels.org/devel/contrasts.html

import numpy as np
import pandas as pd
from category_encoders import HelmertEncoder
# 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

image.png

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.];

image.pngimage.png


1.2.5 Sum (Deviation) Encoding 偏差编码


偏差编码也通常在计量经济学中被使用。偏差编码后,线性模型的系数可以反映该给定该类别变量值的情况下因变量的平均值与全局因变量的平均值的差异。更多信息:


https://www.statsmodels.org/devel/contrasts.html

import numpy as np
import pandas as pd
from category_encoders.sum_coding import SumEncoder
# 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

image.png

encoder = SumEncoder(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.  0.  0.];
#                                      'female' => [ 1.  0.  1.  0.];
#                                       未知 =>  [ 1. -1. -1. -1.];
#                                       缺失 => [ 1.  0.  0.  1.];
# 变量 Type => 变为了5个新变量(包含常数项): 10 => [ 1.  1.  0.  0.  0.];
#                                        20 => [ 1.  0.  1.  0.  0.];, 
#                                        15 => [ 1.  0.  0.  1.  0.];
#                                        未知 =>  [ 1. -1. -1. -1. -1.];
#                                        缺失 => [ 1.  0.  0.  0.  1.];

image.png

image.png

1.2.6 Target Encoding 目标编码


目标编码是一种不仅基于特征值本身,还基于相应因变量的类别变量编码方法。对于分类问题:将类别特征替换为给定某一特定类别值的因变量后验概率与所有训练数据上因变量的先验概率的组合。对于连续目标:将类别特征替换为给定某一特定类别值的因变量目标期望值与所有训练数据上因变量的目标期望值的组合。该方法严重依赖于因变量的分布,但这大大减少了生成编码后特征的数量。


公式:


image.png

其中min_samples_leaf和smoothing是用户定义的参数;
min_samples_leaf:计算类别平均值时的最小样本数(即若该类别出现次数少,则将被忽略),用以控制过拟合;
smoothing:平衡分类平均值与先验平均值的平滑系数。其值越高,则正则化越强;
𝑋′𝑘是类别特征X中类别为k的编码值;
Prior Prob:目标变量的先验概率/期望;
n:类别特征X中,类别为k的样本数;
𝑛+:不仅在类别特征X中具有类别k,而且具有正结果的样本数(分类问题);


参考文献: Micci-Barreca, D. (2001). A preprocessing scheme for high-cardinality categorical attributes in classification and prediction problems. ACM SIGKDD Explorations Newsletter, 3(1), 27-32.

import numpy as np
import pandas as pd
from category_encoders.target_encoder import TargetEncoder
# 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

image.png

encoder = TargetEncoder(cols=['Sex','Type'], 
                        handle_unknown='value',  
                        handle_missing='value').fit(train_set,train_y) # 在训练集上训练
encoded_train = encoder.transform(train_set) # 转换训练集
encoded_test = encoder.transform(test_set) # 转换测试集
# handle_unknown 和 handle_missing 被设定为 'value'
# 在目标编码中,handle_unknown 和 handle_missing 仅接受 ‘error’, ‘return_nan’ 及 ‘value’ 设定
# 两者的默认值均为 ‘value’, 即对未知类别或缺失值填充训练集的因变量平均值
encoded_test # 编码后的变量数与原类别变量数一致

image.png

# 验证一下计算的结果,在测试集中,‘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/n
male_encode # return 0.4731058578630005,与要验证的值吻合

image.png

好了,以上就是关于静态类别变量(上部分)的数据预处理介绍。建议读者结合代码,在 Jupyter 中实操一遍。


目前该项目完整中文版正在制作中,请持续关注哦~


中文版 Jupyter 地址:


http://localhost:8888/notebooks/feature-engineering-handbook-master/%E4%B8%AD%E6%96%87%E7%89%88/1.%20%E6%95%B0%E6%8D%AE%E9%A2%84%E5%A4%84%E7%90%86.ipynb#Ordinal-Encoding-%E5%BA%8F%E6%95%B0%E7%BC%96%E7%A0%81

相关文章
|
机器学习/深度学习 数据采集 算法
【完结篇】专栏 | 基于 Jupyter 的特征工程手册:特征降维
【完结篇】专栏 | 基于 Jupyter 的特征工程手册:特征降维
178 0
【完结篇】专栏 | 基于 Jupyter 的特征工程手册:特征降维
|
机器学习/深度学习 数据采集
专栏 | 基于 Jupyter 的特征工程手册:特征选择(五)
专栏 | 基于 Jupyter 的特征工程手册:特征选择(五)
159 0
专栏 | 基于 Jupyter 的特征工程手册:特征选择(五)
|
数据采集 机器学习/深度学习 数据挖掘
专栏 | 基于 Jupyter 的特征工程手册:数据预处理(三)
专栏 | 基于 Jupyter 的特征工程手册:数据预处理(三)
214 0
专栏 | 基于 Jupyter 的特征工程手册:数据预处理(三)
|
机器学习/深度学习 数据采集 算法
专栏 | 基于 Jupyter 的特征工程手册:数据预处理(一)
专栏 | 基于 Jupyter 的特征工程手册:数据预处理(一)
382 0
专栏 | 基于 Jupyter 的特征工程手册:数据预处理(一)
|
6月前
|
数据采集 机器学习/深度学习 数据可视化
使用Jupyter Notebook进行数据分析:入门与实践
【6月更文挑战第5天】Jupyter Notebook是数据科学家青睐的交互式计算环境,用于创建包含代码、方程、可视化和文本的文档。本文介绍了其基本用法和安装配置,通过一个数据分析案例展示了如何使用Notebook进行数据加载、清洗、预处理、探索、可视化以及建模。Notebook支持多种语言,提供直观的交互体验,便于结果呈现和分享。它是高效数据分析的得力工具,初学者可通过本文案例开始探索。
|
4月前
|
Python
Jupyter Notebook又一利器nbterm,在终端玩notebook!
Jupyter Notebook又一利器nbterm,在终端玩notebook!
|
6月前
|
文字识别 异构计算 Python
关于云端Jupyter Notebook的使用过程与感想
在自学Python时,由于家庭电脑使用冲突和设备老旧,转向云端平台。体验了多个服务:1. 魔搭modelscope(最喜欢,赠送资源丰富,社区活跃),2. Colaboratory(免费GPU,但有时重启,建议用阿里云),3. Deepnote(免费环境有限,但GPT-4代码生成功能强大),4. 飞桨aistudio(适合PaddlePaddle用户),5. ModelArts(曾有免费实例,现难找)。综合来看,阿里云的稳定性与服务更优,尤其是魔搭的自动代码修正功能。对于AIGC,推荐魔搭和付费版PAI-DSW。欢迎分享更多云端Jupyter平台体验。
294 1
|
6月前
|
Python 数据挖掘 数据可视化
Python数据分析——Pandas与Jupyter Notebook
【6月更文挑战第1天】 本文探讨了如何使用Python的Pandas库和Jupyter Notebook进行数据分析。首先,介绍了安装和设置步骤,然后展示了如何使用Pandas的DataFrame进行数据加载、清洗和基本分析。接着,通过Jupyter Notebook的交互式环境,演示了数据分析和可视化,包括直方图的创建。文章还涉及数据清洗,如处理缺失值,并展示了如何进行高级数据分析,如数据分组和聚合。此外,还提供了将分析结果导出到文件的方法。通过销售数据的完整案例,详细说明了从加载数据到可视化和结果导出的全过程。最后,讨论了进一步的分析和可视化技巧,如销售额趋势、产品销售排名和区域分布,以及
219 2
|
7月前
|
JSON 数据可视化 数据挖掘
适合数据分析的ide---Jupyter Notebook的安装使用
适合数据分析的ide---Jupyter Notebook的安装使用
117 2
|
7月前
|
Ubuntu 网络安全 数据安全/隐私保护
使用SSH隧道将Ubuntu云服务器Jupyter Notebook端口映射到本地
这样,你就成功地将Ubuntu云服务器上的Jupyter Notebook端口映射到本地,使你能够通过本地浏览器访问并使用Jupyter Notebook。
474 1