生成精确召回曲线的置信区间

我有一个经过训练的模型的预测,并且我可以很容易地为数据生成精确召回曲线,因此也可以生成精确召回曲线下面积(AUPRC)。然而,我试图为数据生成95%的置信区间,这方面我很难找到相关资料。我查看了Python的sklearn和R的pROC包(后者确实有一些关于PR的使用,但没有关于AUPRC的),但除了我看不太懂的一些高级学术论文外,我没找到其他内容。

有谁知道好的库或者能帮我找到计算AUPRC的95%置信区间的代码吗?

感谢任何能帮助的人!


回答:

我没看到现有的库能做到这一点,所以我认为你需要自己实现。别担心,这并不难。

我看到三种可能的方法:

  1. 精确置信区间:将FN/FP解释为从具有精确度或召回率概率的二项分布中采样。使用二项分布的累积分布函数(CDF)来估计精确区间。这是最繁琐的,但即使样本较小也能工作。
  2. 使用正态近似:基本与之前相同,但使用正态分布的分位数而不是二项分布。如果有100个以上数据点,将生成与(1)几乎相同的结果
  3. 在1000个随机留出集上重复分类,使用经验精确度和召回率分布来计算置信区间。这是最容易实现的,但需要更多的计算量。

更新: 关于实现的一些提示:

  • 精确度是TP/(TP+FP),即对正预测的真实正例的概率
  • 召回率是TP/(TP+FN),即对真实正例的正预测的概率。

由于下文将涉及多个概率,我将这两个概率称为PR(精确度或召回率)

为两者获取置信区间的任务是完全相同的。我们基本上是在尝试估计一个伯努利变量的p(如抛硬币正面的几率)。在两种情况下,正面结果的数量(TP)是相同的。唯一的区别是尝试的数量(分母,我将在下文中称为n)。

因此,我们需要将PR的值与观察到的结果的概率联系起来。我们希望找到一些PR值的区间,使得观察到的结果的概率高于某个alpha。使用伯努利分布,我们可以根据正面翻转的几率PR(p)估计观察到结果的概率(P):

P = (n! / (tp! * (n-tp)!)) * (p ** tp) * ((1-p) ** (n-tp))

对其进行累积并反转以求出p就是上面提到的选项1。正如我提到的,这很繁琐(但并非不可能)。

方法2是使用中心极限定理,它基本上说随机变量的总和紧密跟随正态分布。鉴于伯努利分布的方差是p * (1-p),而总和的方差与n成反比,我们可以找到总和的标准偏差。现在,以1-alpha的概率,p应该在范围p_hat +/- z_score * standard_deviation_of_sum内。

最后,实现:

# 我们需要这个来计算z-scorefrom scipy.stats import normdef ci(tp, n, alpha=0.05):    """ 估计伯努利p的置信区间    Args:      tp: 正面结果的数量,在本例中为TP      n: 尝试的数量,精确度为TP+FP,召回率为TP+FN      alpha: 置信水平    Returns:      Tuple[float, float]: 置信区间的下限和上限    """    p_hat = float(tp) / n    z_score = norm.isf(alpha * 0.5)  # 两侧,所以每侧alpha/2    variance_of_sum = p_hat * (1-p_hat) / n    std = variance_of_sum ** 0.5    return p_hat - z_score * std, p_hat + z_score * std

更新2: 计算AUC的置信区间

sklearn.metrics.auc需要两个向量,xy值。在这里,精确度和召回率可以互换使用。即,x是一个估计精确度值的向量,y是召回率的上限/下限,或者反之——x是估计的召回率值,y是精确度的上限或下限。

如果没有sklearn,可以大致按以下方式近似计算:

# 假设data是一个列表,包含(upper_precision, precision, lower precision, upper_recall, recall, lower_recall)auc = 0sort(data, key=lambda x: x[1])  # 按精确度排序last_point = (0, 0)  # 最后的x,y值for up, p, lp, ur, r, lr in data:    # 用于排序的应该首先    new_point = (p, ur)  # 或(r, up)用于上限;(p, lr), (r, lp)用于下限    dx = new_point[0] - last_point[0]    y = last_point[1]    auc += dx * last_point[1] + dx * (new_point[1] - last_point[1]) * 0.5        

Related Posts

在使用k近邻算法时,有没有办法获取被使用的“邻居”?

我想找到一种方法来确定在我的knn算法中实际使用了哪些…

Theano在Google Colab上无法启用GPU支持

我在尝试使用Theano库训练一个模型。由于我的电脑内…

准确性评分似乎有误

这里是代码: from sklearn.metrics…

Keras Functional API: “错误检查输入时:期望input_1具有4个维度,但得到形状为(X, Y)的数组”

我在尝试使用Keras的fit_generator来训…

如何使用sklearn.datasets.make_classification在指定范围内生成合成数据?

我想为分类问题创建合成数据。我使用了sklearn.d…

如何处理预测时不在训练集中的标签

已关闭。 此问题与编程或软件开发无关。目前不接受回答。…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注