你的特征很重要吗? 这并不意味着它们很好 - KDnuggets

你的特征很重要吗? 这并不意味着它们很好 – KDnuggets

源节点: 2893531

你的特征很重要吗? 这并不意味着他们很好
[图片由作者提供]

 

“特征重要性”的概念作为最基本的模型可解释性类型广泛应用于机器学习中。 例如,它用于递归特征消除(RFE),以迭代方式删除模型中最不重要的特征。

然而,人们对此有一个误解。

某个特征很重要这一事实并不意味着它对模型有益!

事实上,当我们说某个特征很重要时,这仅仅意味着该特征对模型的预测有很大的贡献。 但我们应该考虑到 这样的贡献可能是错误的.

举一个简单的例子:数据科学家不小心忘记了其模型特征之间的客户 ID。 该模型使用客户 ID 作为高度预测的特征。 因此,即使该特征实际上使模型变得更糟,它也将具有很高的特征重要性,因为它不能很好地处理看不见的数据。

为了让事情更清楚,我们需要区分两个概念:

  • 预测贡献:预测的哪一部分是由于该特征造成的; 这相当于特征重要性。
  • 错误贡献:预测误差的哪一部分是由于模型中存在该特征而导致的。

在本文中,我们将了解如何计算这些数量以及如何使用它们来获得有关预测模型的有价值的见解(并改进它)。

注意:本文重点讨论回归案例。 如果您对分类案例更感兴趣,可以阅读 “哪些特征对你的分类模型有害?”

假设我们建立了一个模型来根据人们的工作、年龄和国籍来预测他们的收入。 现在我们使用该模型对三个人进行预测。

因此,我们得到了基本事实、模型预测以及由此产生的误差:

 

你的特征很重要吗? 这并不意味着他们很好
地面实况、模型预测和绝对误差(单位:千美元)。 [图片由作者提供]

 

当我们有了预测模型时,我们总是可以将模型预测分解为单个特征带来的贡献。 这可以通过 SHAP 值来完成(如果您不知道 SHAP 值如何工作,可以阅读我的文章: SHAP 价值观的解释正是您希望别人向您解释的方式).

因此,假设这些是相对于我们三个人的模型的 SHAP 值。

 

你的特征很重要吗? 这并不意味着他们很好
我们模型预测的 SHAP 值(以千美元为单位)。 [图片由作者提供]

 

SHAP 值的主要属性是它们是可加的。 这意味着,通过计算每一行的总和,我们将获得模型对该个体的预测。 例如,如果我们取第二行:72k $ +3k $ -22k $ = 53k $,这正是模型对第二个个体的预测。

现在,SHAP 值可以很好地指示某个特征对于我们的预测有多重要。 事实上,(绝对)SHAP 值越高,该特征对该特定个体的预测影响力就越大。 请注意,我谈论的是绝对 SHAP 值,因为这里的符号并不重要:如果某个特征将预测向上或向下推,则它同样重要。

因此, 特征的预测贡献等于该特征的绝对SHAP值的平均值。 如果您将 SHAP 值存储在 Pandas 数据框中,则非常简单:

prediction_contribution = shap_values.abs().mean()

在我们的示例中,结果如下:

 

你的特征很重要吗? 这并不意味着他们很好
预测贡献。 [图片由作者提供]

 

正如您所看到的,工作显然是最重要的特征,因为它平均占最终预测的 71.67 美元。 国籍和年龄分别是第二和第三最相关的特征。

然而,给定特征占最终预测的相关部分这一事实并不能说明该特征的性能。 为了考虑这个方面,我们需要计算“错误贡献”。

假设我们要回答以下问题:“如果模型没有该特征,它会做出什么预测 工作?” SHAP 值让我们能够回答这个问题。 事实上,由于它们是可加的,因此减去相对于特征的SHAP值就足够了 工作 根据模型的预测。

当然,我们可以对每个功能重复此过程。 在熊猫中:

y_pred_wo_feature = shap_values.apply(lambda feature: y_pred - feature)

这是结果:

 

你的特征很重要吗? 这并不意味着他们很好
如果我们删除相应的特征,我们将获得的预测。 [图片由作者提供]

 

这意味着,如果我们没有这个功能 工作,那么模型将预测第一个个体的收益为 20k $,第二个个体的收益为 -19k $,第三个个体的收益为 -8k $。 相反,如果我们没有这个功能 年龄,模型将预测第一个个体的收入为 73k $,第二个个体的收入为 50k $,依此类推。

正如您所看到的,如果我们删除不同的特征,每个人的预测会有很大差异。 因此,预测误差也会有很大不同。 我们可以轻松计算它们:

abs_error_wo_feature = y_pred_wo_feature.apply(lambda feature: (y_true - feature).abs())

结果如下:

 

你的特征很重要吗? 这并不意味着他们很好
如果我们删除相应的特征,我们将获得绝对错误。 [图片由作者提供]

 

这些是如果我们删除相应的功能就会出现的错误。 直观上,如果误差很小,那么删除该特征对于模型来说不是问题,甚至是有益的。 如果误差很高,那么删除该功能并不是一个好主意。

但我们可以做的不止于此。 事实上,我们可以计算完整模型的误差与没有该特征时获得的误差之间的差异:

error_diff = abs_error_wo_feature.apply(lambda feature: abs_error - feature)

这是:

 

你的特征很重要吗? 这并不意味着他们很好
模型的错误与没有该特征时我们会出现的错误之间的差异。 [图片由作者提供]

 

如果这个数字是:

  • 负数,则该特征的存在会导致预测误差减少,因此该特征非常适合该观察!
  • 正,则该特征的存在会导致预测误差增加,因此该特征对该观察不利。

我们可以计算每个特征的“误差贡献”作为这些值的平均值。 在熊猫中:

error_contribution = error_diff.mean()

这是结果:

 

你的特征很重要吗? 这并不意味着他们很好
错误贡献。 [图片由作者提供]

 

如果该值为正,则意味着平均而言,模型中该特征的存在会导致更高的误差。 因此,如果没有这个功能,预测通常会更好。 换句话说,该功能弊大于利!

相反,该值越负,该特征对预测越有利,因为它的存在会导致更小的误差。

让我们尝试在真实数据集上使用这些概念。

此后,我将使用取自的数据集 派克雷特 (Python 库位于 MIT许可证)。 该数据集被称为“Gold”,它包含金融数据的时间序列。

 

你的特征很重要吗? 这并不意味着他们很好
数据集样本。 这些特征均以百分比表示,因此-4.07 表示回报率为-4.07%。 [图片由作者提供]

 

特征在于观察时刻前22天、14天、7天、1天的金融资产收益率(“T-22”、“T-14”、“T-7”、“T-1”)。 以下是用作预测特征的所有金融资产的详尽列表:

 

你的特征很重要吗? 这并不意味着他们很好
可用资产列表。 每个资产在时间 -22、-14、-7 和 -1 被观察。 [图片由作者提供]

 

我们总共有 120 个特征。

目标是提前 22 天预测黄金价格(回报)(“Gold_T+22”)。 我们来看看目标变量。

 

你的特征很重要吗? 这并不意味着他们很好
变量的直方图。 [图片由作者提供]

 

加载数据集后,我执行了以下步骤:

  1. 随机分割完整数据集:训练数据集中 33% 的行,验证数据集中另外 33% 的行,测试数据集中剩余的 33%。
  2. 在训练数据集上训练 LightGBM 回归器。
  3. 使用上一步训练的模型对训练、验证和测试数据集进行预测。
  4. 使用 Python 库“shap”计算训练、验证和测试数据集的 SHAP 值。
  5. 使用我们在上一段中看到的代码计算每个数据集(训练、验证和测试)上每个特征的预测贡献和误差贡献。

我们来比较一下训练数据集中的误差贡献和预测贡献。 我们将使用散点图,因此点标识模型的 120 个特征。

 

你的特征很重要吗? 这并不意味着他们很好
预测贡献与错误贡献(在训练数据集上)。 [图片由作者提供]

 

训练集中的预测贡献和误差贡献之间存在高度负相关。

这是有道理的: 由于模型在训练数据集上学习,因此它倾向于将高重要性(即高预测贡献)归因于那些导致预测误差大大减少(即高度负误差贡献)的特征.

但这并不能增加我们的知识,对吗?

事实上,对我们来说真正重要的是验证数据集。 事实上,验证数据集是我们可以拥有的关于我们的特征如何在新数据上表现的最佳代理。 那么,我们在验证集上进行同样的比较。

 

你的特征很重要吗? 这并不意味着他们很好
预测贡献与错误贡献(在验证数据集上)。 [图片由作者提供]

 

从这个图中,我们可以提取一些更有趣的信息。

该图右下部分的特征是我们的模型正确分配高度重要性的特征,因为它们实际上减少了预测误差。

另请注意,与模型赋予它的重要性相比,“Gold_T-22”(观察期前 22 天的黄金回报)效果非常好。 这意味着 该功能可能不适合。 这条信息特别有趣,因为黄金是我们试图预测的资产(“Gold_T+22”)。

另一方面, 误差贡献高于 0 的特征使我们的预测变得更糟。 例如,“美国债券 ETF_T-1”平均将模型预测改变了 0.092%(预测贡献),但它导致模型的预测比没有该功能时的预测平均差 0.013%(误差贡献) 。

我们可以假设 所有具有高误差贡献(与其预测贡献相比)的特征都可能过度拟合 或者,一般来说,它们在训练集和验证集中有不同的行为。

让我们看看哪些特征具有最大的错误贡献。

 

你的特征很重要吗? 这并不意味着他们很好
按错误贡献递减排序的功能。 [图片由作者提供]

 

现在是错误贡献最低的功能:

 

你的特征很重要吗? 这并不意味着他们很好
按错误贡献的增加对功能进行排序。 [图片由作者提供]

 

有趣的是,我们可以观察到,所有具有较高误差贡献的特征都相对于T-1(观察时刻前1天),而几乎所有具有较小误差贡献的特征都相对于T-22(观察时刻之前22天) )。

这似乎表明 最近的特征容易过度拟合,而时间较远的特征往往具有更好的泛化能力.

请注意,如果没有错误贡献,我们永远不会知道这一见解。

传统的递归特征消除(RFE)方法基于删除不重要的特征。 这相当于先去掉预测贡献小的特征。

然而,根据我们在上一段中所说的,首先删除错误贡献最高的特征会更有意义。

为了检查我们的直觉是否得到验证,让我们比较一下这两种方法:

  • 传统 RFE:首先删除无用的功能 (最低预测贡献)。
  • 我们的 RFE:删除有害功能 第一 (最高错误贡献)。

让我们看看验证集上的结果:

 

你的特征很重要吗? 这并不意味着他们很好
验证集上两种策略的平均绝对误差。 [图片由作者提供]

 

每种方法的最佳迭代已被圈出:它是传统 RFE 的具有 19 个特征的模型(蓝线),以及我们的 RFE 的具有 17 个特征的模型(橙色线)。

总的来说,我们的方法似乎效果很好:与删除具有最高预测贡献的特征相比,删除具有最高误差贡献的特征会导致始终较小的 MAE。

然而,您可能认为这很有效,只是因为我们过度拟合了验证集。 毕竟,我们对在测试集上获得的结果感兴趣。

那么让我们在测试集上进行相同的比较。

 

你的特征很重要吗? 这并不意味着他们很好
测试集上两种策略的平均绝对误差。 [图片由作者提供]

 

结果与前一个类似。 即使两条线之间的距离较小,通过删除最高误差贡献者获得的 MAE 也明显优于通过删除最低预测贡献者获得的 MAE。

由于我们选择了验证集上 MAE 最小的模型,让我们看看它们在测试集上的结果:

  • RFE-预测贡献(19 个功能)。 测试集上的 MAE:2.04。
  • RFE-错误贡献(17 个功能)。 测试集上的 MAE:1.94。

因此,使用我们的方法得到的最佳 MAE 比传统 RFE 好 5%!

特征重要性的概念在机器学习中起着基础作用。 然而,“重要性”的概念常常被误认为是“善”。

为了区分这两方面,我们引入了两个概念:预测贡献和误差贡献。 这两个概念都基于验证数据集的 SHAP 值,在本文中我们已经看到了计算它们的 Python 代码。

我们还在真实的金融数据集(其中的任务是预测黄金价格)上进行了尝试,并证明与基于预测贡献的传统 RFE 相比,基于误差贡献的递归特征消除的平均绝对误差提高了 5%。

本文使用的所有代码都可以在 这个笔记本.

谢谢你的阅读!

 
 
塞缪尔·马赞蒂 是 Jakala 的首席数据科学家,目前居住在罗马。 他毕业于统计学,主要研究兴趣涉及行业中的机器学习应用。 他也是一名自由内容创作者。

 
原版。 经许可重新发布。
 

时间戳记:

更多来自 掘金队