互联网资讯 / 人工智能 · 2023年12月5日 0

机器学习特征选择的Python工具

特征选择是从数据集中识别和挑选最重要特征的过程,这是机器学习工作流程中的一个重要环节。冗余特征不仅会降低训练速度,还会影响模型的可解释性,最关键的是,它会损害测试集的泛化能力。

出于对机器学习问题中不断重复应用特征选择方法的沮丧,我在Python中创建了一个特征选择类,并将其上传至GitHub。这个FeatureSelector类包含了一些常见的特征选择方法:

1. 缺失值比例过高的特征
2. 共线性(高度相关)的特征
3. 在基于树的模型中无重要性的特征
4. 重要性较低的特征
5. 只有单一唯一值的特征

在这篇文章中,我们将使用一个示例机器学习数据集来演示FeatureSelector的功能。我们将探讨它如何帮助我们快速实现这些特征选择技术,从而提高工作效率。

样例数据集

本示例将使用Kaggle上的“Home Credit Default Risk”机器学习竞赛数据。整个数据集可以进行下载,而我们将选取其中的一个示例进行演示。

样例数据集中的TARGET为分类标签。

该比赛是一个监督分类问题,数据集十分优秀,包含了大量缺失值和高度相关的特征,以及一些不相关的特征,这些特征对机器学习模型的构建没有帮助。

创建实例

要创建FeatureSelector类的实例,我们需要提供一个结构化数据集,其中包含特征的行和列。虽然我们可以使用一些仅依赖特征的方法,但基于特征重要性的方法则需要训练标签。由于这是一个监督分类任务,我们将使用一组特征和对应的标签。

方法

特征选择器提供了五种方法来识别需要删除的特征。用户可以手动从数据中删除任何识别出的特征,或者使用FeatureSelector中的Remove函数。

接下来,我们将逐一介绍每种识别方法,并展示如何同时运行这五种方法。FeatureSelector还提供了一些可视化功能,因为可视化数据是机器学习的重要组成部分。

第一种查找待删除特征的方法是检查哪些特征的缺失值比例超过某个阈值。下面的调用将标识缺失值超过60%的特征。

我们可以查看数据框中每一列的缺失值比例:

要查看待删除特征,我们可以访问FeatureSelector的ops属性,这是一个包含特征列表的Python字典。

最后,我们绘制了所有特征缺失值的分布图:

共线性特征

共线性特征是彼此高度相关的特征。在机器学习中,这会导致方差增大、模型可解释性降低,从而影响测试集的泛化性能。

方法identify_collinear根据指定的相关系数值查找共线特征。对于每对相关特征,它会识别出需要删除的特征之一(因为我们只需删除一个):

如前所述,我们可以访问将被删除的相关特征的完整列表,或者查看数据框中高度相关的特征对。

零重要性特征

前两种方法适用于任何结构化数据集,并且是确定性的——对于给定的阈值,结果一致。下一种方法仅适用于有监督的机器学习问题,其中包含训练模型的标签,并且结果是随机的。identify_zero_importance函数利用梯度提升机(GBM)学习模型来查找不重要的特征。

使用基于树的机器学习模型,如增强集成,可以获得特征的重要性。特征的重要性绝对值并不重要,重要的是相对值,这可以帮助我们确定任务中最相关的特征。通过删除零重要性的特征,我们也能进行特征选择。在基于树的模型中,零重要性的特征不会用于分割任何节点,因此可以在不影响模型性能的前提下删除它们。

FeatureSelector使用LightGBM库中的梯度提升机来计算特征重要性。为了减少方差,我们对GBM进行10次训练并计算特征重要性平均值。此外,使用带有验证集的早期停止(可选择关闭验证集)来训练模型,以防止过拟合。

以下代码调用该方法来提取零重要性特征:

我们传入的参数如下:

任务:对应问题的“分类”或“回归”
eval_metric:用于早期停止的指标(如果禁用了早期停止,则不需要使用该指标)
n_iteration:训练次数,用于特征重要性取平均
early_stop:是否使用早期停止来训练模型

这次我们得到了两个图,带有plot_feature_importances:

左侧是plot_n最重要的特征(按归一化重要性绘制,总和为1),右侧则是相对于特征数量的累积重要性。垂直线显示累积重要性的“阈值”,在本例中为99%。

使用基于重要性的方法时,有两个注意事项值得关注:

1. 梯度提升机的训练是随机的,这意味着每次运行模型时特征输入都会发生变化。
2. 这不应导致重大影响(最重要的特征不会突然变得不重要),但可能会改变某些特征的顺序,也可能影响识别到的零重要性特征的数量。如果特征的重要性每次都发生变化,不必感到惊讶!

在训练机器学习模型之前,首先要对特征进行“独热编码”。这意味着一些重要性为0的特征可能是在建模过程中添加的独热编码特征。

当我们进行特征删除时,可以选择删除任何添加的独热编码特征。然而,如果在特征选择后进行机器学习,我们仍需对特征进行一次独热编码!

低重要性特征

下一个方法基于零重要性函数,利用模型的特征输入进行进一步选择。函数identify_low_importance查找对总重要性贡献较小的特征。

例如,下面的调用找到了那些对99%总重要性不必要的最不重要特征:

根据累积重要性图和其他信息,梯度提升机认为许多特征与学习无关。同样,这种方法的结果将在每次训练时发生变化。

要查看数据框中的所有重要特征:

low_importance方法借鉴了主成分分析(PCA)的一种方法,通常只保留需要保留一定百分比的方差(如95%)的主成分。特征占总重要性的百分比是基于相同的思路。

基于特征重要性的方法仅在我们使用基于树的模型进行预测时才真正适用。除了随机性,这些方法也是黑箱方法,因为我们无法得知模型为何将这些特征视为无关特征。如果使用这些方法,建议多次运行以查看结果变化,或许可以创建多个使用不同参数的数据集进行测试!

单一唯一值的特征

最后一个方法相对简单:查找任何只有一个唯一值的列。只有一个唯一值的特征对机器学习无用,因为该特征的方差为零。例如,基于树的模型无法对只有一个值的特征进行分割(因为没有分组来划分观察结果)。

这里没有参数选择,与其他方法不同:

我们可以绘制每个类别中唯一值数量的直方图:

需要注意的是,在默认情况下,pandas在计算唯一值之前会先删除NaNs。

去除特征

一旦确定了要丢弃的特征,我们有两个选项来删除它们。所有待删除的特征都存储在FeatureSelector的ops字典中,用户可以手动使用列表删除特征。另一种选择是使用内置函数“Remove”。

对于该方法,我们需要传入用于删除特征的方法。如果希望使用所有实现的方法,只需传入methods=’all’。

该方法返回一个已删除特征的数据框。此外,还可以删除机器学习过程中创建的独热编码特征:

在继续操作之前,检查将被删除的特征可能是个好主意!原始数据集存储在FeatureSelector的data属性中作为备份!

一次运行所有方法

我们可以使用identify_all,而不是单独调用这些方法。这需要每个方法的参数字典:

请注意,由于我们重新运行模型,总特征的数量将会变化。随后可以调用“Remove”函数来删除这些特征。

总结

在训练机器学习模型之前,Feature Selector类实现了多种常见的特征删除操作。它提供了识别待删除特征的能力以及可视化功能。这些方法可以单独执行,也可以一次性全部运行,以实现高效的工作流程。

缺失值、共线性和单一唯一值方法是确定性的,而基于特征重要性的方法则会随着每次运行而变化。特征选择,正如机器学习领域一样,往往是经验性的,需要多次测试不同组合以找到最佳解决方案。在工作流程中尝试多种配置是最佳实践,而特征选择器提供了一种快速评估特征选择参数的方法。