【问题标题】:Rank samples from a pool of predictions based on each score根据每个分数对预测池中的样本进行排名
【发布时间】:2021-07-04 23:53:05
【问题描述】:

我有一个从s1s100 的样本池,我想在AB 两个不同类别之间进行分类

在这个问题中,我不能对每个样本单独执行预测,而是以 10 个为一组进行预测,并且每个预测都会返回预测的标签和每个标签的 置信度。比如:

[s1,s21,s3,s15,s5,s62,s90,s13,s9,s100];A;0.9
[s1,s5,s12,s20,s53,s89,s27,s42,s76,s55];A;0.4
...

每个预测向量都是随机设置的,我可以根据需要执行尽可能多的组合。此外,样本可以在池中重复多次。

我想要完成的是使用 置信度 标签对每个 category 预测的每个 sample 重要性进行排名

搜索类似的问题我最终认为计算shaply values 将是一个很好的解决方案,但这些被认为是针对特征而不是样本的实现。

有什么想法可以实现吗?

编辑:

按照建议,我将尝试添加一个最小的问题示例,每组 4 个样本和 2 个样本。比如:

Sample_group;Prediction;Confidence
[s1,s2];A;0.7
[s3,s4];A;0.6
[s1,s3];A;0.9
[s2,s4];A;0.5
[s1,s4];A;0.7
[s2,s3];A;0.6

尽管所有对都给出了相同的预测,但查看 confidence 值显示 [s1,s3] 对具有最高值,[s2,s4] 具有最低值。检查其余对可以推断出s1 值似乎是与s3 与其他两个配对时提供最高置信度的值。那么,结果应该是这样的:

Sample;rank
s1;0
s3;1
s2;2
s4;3

【问题讨论】:

标签: python machine-learning game-theory shap


【解决方案1】:
  1. 第一种方法:

您可以尝试重新构建您的问题:您实际上有一个模型,它采用 100 个特征向量并返回一个预测。每个单独的特征都是布尔值(如果样本 i 是包含的 10 个样本之一,则特征 i 为 1,而 0 不是;当然,此框架可以支持任何样本混合,而不仅仅是 10 个组)。

您的预测有两个组成部分可以通过将其替换为单个值来处理,该值是预测 A 和 B 的置信度乘以 1 或 -1,因此您的预测在 [ -1 1](其中 -1 以最高置信度预测 A,1 以最高置信度预测 B,等等)。这只是一个建议,还有其他方法可以将 2D 输出减少到 1D,但这个方法似乎最简单。

现在您基本上有了一个简单的回归模型,该模型包含 100 个特征并返回一个数字,您可以计算每个特征的 SHAP 值(在您的情况下,这将转化为“样本重要性” - 即包含用于预测的样本)。至于如何计算 SHAP 值,我认为如果您实际上使用包含预测的 .predict 方法实现一个类,您可以使用 SHAP 的 KernelExplainer。您的下一个问题将是 KernelExplainer 为每个特征提供您的 shap 值以进行特定预测(并运行 .predict 100K 次来执行此操作,因此您的方法最好更快)。因此,您可能需要针对不同的样本组多次执行此操作并对结果进行平均。

  1. 第二种方法:

另一个可能需要更多工作才能实现但更直接的解决方案是实现您自己的 Shapley 计算版本。 Shapley 值的原始博弈论公式实际上似乎更符合您的问题,而不是机器学习的采用。也就是说,如果您将每个样本视为“贡献者”,并将最终输出(如上所述减少为单个数字)视为“结果”,那么 Shapley 公式正是旨在估计每个贡献者的贡献存在,存在于其他贡献者的所有其他排列中。

在一般情况下,如果您有 N 个贡献者,则存在 2^N 个组合,但在您的情况下,您可以说只有 100 个样本中存在 10 个样本的组合是合法的。因此,您可以采用 Shapley 公式,而不是遍历所有可能的组合,只需查看合法的组合即可。有 100 个选择 10 个,这仍然是一个巨大的数字(万亿),因此您可能需要从其中随机抽样以获得合理的运行时间。据我了解公式背后的想法,它将为您提供您所需要的。

【讨论】:

  • 感谢您的精彩解释。我想第二个方法将是我想要实施的方法。虽然我猜想 compute_shapley_values 函数从这里 (github.com/edden-gerber/radical-shapley-values/blob/master/…) 将是一个很好的开始,但我不太确定如何重新格式化以满足我的需要。任何代码提示:-)?
  • 从快速浏览到提醒自己我在那里做了什么,您似乎需要修改两个主要内容。一个是,您需要在可能的联盟上定义自己的循环,而不是运行所有 2^M 可能的联盟,因为您只使用可能联盟的子空间(我的代码使用将联盟编号转换为二进制的小技巧,例如联盟 5 将是 (000...)101 表示玩家 1 和 3 参与)。
  • 其次,我的函数被设计为采用支付函数,该函数接受输入并返回支付,并且每次只传递给该函数参与的特征(例如 partial_X)。您可以硬编码自己的支付函数,而不是每次都传递 10 个特征,而是始终传递 100 个元素的向量,相关的 10 个元素设置为 1,其余元素设置为 0。
猜你喜欢
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 2020-05-07
  • 2017-10-01
  • 2019-12-31
  • 2021-07-22
  • 2015-08-26
  • 1970-01-01
相关资源
最近更新 更多