特征工程

在本节我们将开发一个机器学习模型来预测客户是否会注册存款证 (certificate of deposit - CD)。该模型将在marketing数据集上进行训练,其中包含有关客户统计、对营销事件的响应和外部因素的信息。将使用XGBoost ML算法

为了方便,数据已被标记,数据集中的一列标识客户是否注册了银行提供的产品。由于数据已标记,我们使用监督学习。

img

特征工程 - feature engineering

有 3 个选项可以对数据集执行特征工程

  1. 使用SageMaker Data WranglerFeature Store

  2. 使用Numpy + Pandas

  3. 使用SageMaker Processing

环境准备

进入到SageMaker Studio Classic页面,创建一个新的Notebook:

image-20231229215113810

设置kernel,使用默认选项:

image-20231229215249616

将进入Untitled.ipynb笔记本,可以通过右键单击名称来重命名笔记本:

image-20231229215402410

image-20231229215430075

下载github库

在 SageMaker 笔记本中,启动终端(内核必须完全启动,Share按钮右侧的圆圈必须为空):

image-20231229215630646

在终端中,键入以下命令:

git clone https://github.com/aws-samples/amazon-sagemaker-immersion-day.git

image-20231229215801926

左侧面板中会出现amazon-sagemaker-immersion-day文件夹:

image-20231229215838309

Numpy + Pandas

单击“amazon-sagemaker-immersion-day”文件夹,然后双击笔记本xgboost_direct_marketing_sagemaker.ipynb

如果提示选择内核,请选择“Python 3 (Data Science 3.0)”内核并单击“选择”。

image-20231229221034036

然后将打开笔记本,在每个单元中按Shift+Enter执行前四个单元。此代码将导入一些库并在 Jupyter Notebook 环境中定义一些环境变量。

img

现在,让我们通过运行第 5 个单元来下载数据集:

# cell 05
!wget https://sagemaker-sample-data-us-west-2.s3-us-west-2.amazonaws.com/autopilot/direct_marketing/bank-additional.zip

with zipfile.ZipFile('bank-additional.zip', 'r') as zip_ref:
    zip_ref.extractall('.')

在下一个单元中,把数据集加载到 pandas dataframe中,并使用sagemaker_datawrangler库来探索数据并了解每个特征的数据分布:

image-20231229221644041

image-20231229222553222

我们可以看到:

  • 我们有超过 40K 的客户记录,每个客户有 20 个feature
  • 特征是混合的;一些是number类型,一些是category类型

每个字段的说明:

用户特性:

  • age:顾客的年龄(数字)
  • job:工作类型(类别:“admin”、“services”……)
  • marital:婚姻状况(类别:“已婚”、“单身”……)
  • education:教育水平(类别:‘basic.4y’、‘high.school’、…)

过去的客户活动:

  • default: 信用有违约吗?(分类:“否”、“未知”……)
  • housing: 有房贷吗?(分类:“否”、“是”……)
  • loan: 有个人贷款吗?(分类:“否”、“是”……)

过去的直接营销联系人:

  • contact:联系通信类型(类别:“蜂窝”、“电话”……)
  • month:一年中最后一次联系的月份(类别:“五月”、“十一月”……)
  • day_of_week:一周中的最后联系日(类别:“周一”、“周五”……)
  • duration:上次联系持续时间,以秒为单位(数字)。重要提示:如果持续时间 = 0,则y=“否”。

campaign信息:

  • campaign:在此活动期间为此客户进行的联系次数(数字,包括最后一次联系)
  • pdays:上次活动中最后一次联系客户后经过的天数(数字)
  • previous:在此活动之前以及为此客户进行的联系次数(数字)
  • poutcome:之前营销活动的结果(类别:“不存在”、“成功”、……)

外部环境因素:

  • emp.var.rate:就业变化率-季度指标(数字)
  • cons.price.idx:消费者价格指数-月度指标(数字)
  • cons.conf.idx:消费者信心指数-月度指标(数字)
  • euribor3m:Euribor 3 个月利率 - 每日指标(数字)
  • nr.employed:员工人数 - 季度指标(数字)

目标变量:

  • y:客户是否办理了定期存款?(二进制:“是”、“否”)

探索特征

现在让我们看看我们的特征如何与尝试预测的目标相关。首先,让我们了解一下特征是如何分布的。

请注意:

  • 我们的目标变量几乎 90% 的值为y“否”,因此大多数客户没有办理定期存款。
  • 许多预测特征具有“未知”值。有些比其他更常见。我们应该仔细思考是什么导致了“未知”的值(这些客户在某种程度上不具有代表性吗?)以及我们应该如何处理。
  • 许多预测特征都有一些category,其中的观察结果很少。如果我们发现一个小的category可以高度预测我们的目标结果,我们是否有足够的证据来对此进行概括?
  • 接触时间尤其不平衡。5 月份几乎占三分之一,12 月份不到 1%。这对于预测明年 12 月的目标变量意味着什么?
  • 我们的数字特征中没有缺失值。或者缺失值已经被估算。
    • pdays对于几乎所有客户都是999。可能是一个占位符值,表示以前没有联系过。
  • 一些数字特征有长尾。我们是否需要以不同的方式处理这些具有极大值的少数观测值?
  • 一些数字特征(特别是宏观经济特征)出现在不同的桶中。这些应该被视为category类型的吗?

接下来,让我们看看我们的特征与我们尝试预测的目标有何关系。

img

image-20231229223952826

transformation

清理数据几乎是每个机器学习项目的一部分。如果做得不正确,它可以带来最大的风险。几种常见的技术包括:

  • 处理缺失值:一些机器学习算法能够处理缺失值,但大多数算法不愿意处理。选项包括:
    • 删除缺失值的观测值:如果只有一小部分观测值具有不完整的信息,则此方法很有效。
    • 删除具有缺失值的特征:如果存在少量缺失值的特征,则此方法效果很好。
    • 估算缺失值:常见的选择是将缺失值替换为该列非缺失值的众数或平均值。
  • 将分类转换为数字:最常见的方法是一种热编码,对于每个特征,该特征将该列的每个不同值映射到其自己的特征,当分类特征等于该值时,该特征的值为 1,否则为 0。
  • 奇怪的分布数据:虽然对于像梯度提升树这样的非线性模型来说影响非常有限,但是当输入高度倾斜的数据时,像回归这样的参数模型可能会产生非常不准确的估计。在某些情况下,简单地取特征的自然对数就足以产生更正态分布的数据。在其他情况下,将值分入离散范围是有帮助的。然后,这些桶可以被视为分类变量,并在进行热编码时包含在模型中。
  • 处理更复杂的数据类型:以不同的粒度来处理图像、文本或数据留给其他笔记本模板。

现在我们将使用一种热编码转换所有分类变量:

# cell 09

# Note: These transformations can be done through the graphical widget that we generated above. The data prep widget will automatically generate code for transformations that you do.
data['no_previous_contact'] = np.where(data['pdays'] == 999, 1, 0)                                 # Indicator variable to capture when pdays takes a value of 999
data['not_working'] = np.where(np.in1d(data['job'], ['student', 'retired', 'unemployed']), 1, 0)   # Indicator for individuals not actively employed

# cell 10
model_data = pd.get_dummies(data)                                  # Convert categorical variables to sets of indicators

get_dummies 是利用pandas实现one hot encode的方式,例如:

image-20231229232127785

数据在one-hot编码后,将由原来的23列变为67列:

image-20231229232254267

在构建模型之前要问自己的另一个问题是某些feature是否会在最终用例中增加价值。

按照这个逻辑,让我们去掉经济特征和duration,因为它们需要进行高精度预测才能用作未来预测的输入。

我们将删除一些不需要的功能:

img

我们将数据集分为 3 个通道:训练集、测试集、验证集:

img

Amazon SageMaker XGBoost 算法要求数据采用 libSVM 或 CSV 格式(无标题),并且第一列必须是目标变量。所以在这一步我们相应地转换数据

# cell 13
pd.concat([train_data['y_yes'], train_data.drop(['y_no', 'y_yes'], axis=1)], axis=1).to_csv('train.csv', index=False, header=False)
pd.concat([validation_data['y_yes'], validation_data.drop(['y_no', 'y_yes'], axis=1)], axis=1).to_csv('validation.csv', index=False, header=False)

现在我们将最终数据上传到 Amazon S3 存储桶中:

img

现在通过控制台检查 S3 存储桶,确保已上传 train.csv 和 validation.csv。

单击“sagemaker/”,然后单击“DEMO-xgboost-dm/”。将看到“train/”和“validation/”文件夹。

image-20231229224417773

现在已成功准备好数据来训练 XGBoost 模型。

在本实验中,我们已经完成了所需的环境设置和数据工程的过程,以清理和准备用于模型构建和训练的数据。在下一个实验中,我们将学习如何使用 SageMaker 的内置 XGBoost 算法训练、调整和部署 XGBoost 模型。