精度和召回率是否应该与分类阈值单调

机器算法验证 机器学习 精确召回
2022-03-20 01:53:46

我迈出了机器学习的第一步。我使用 python sklearn 模块创建了一个简单的模型,但我无法弄清楚一个基本的东西。我希望准确率和召回率应该是预测概率阈值的单调函数。这些是我预测的概率值和标签:

p = [ 0.689,  0.816,  0.846,  0.19 ,  0.527,  0.846,  0.846,  0.73 ,
    0.846,  0.762,  0.22 ,  0.958,  0.223,  0.658,  0.481,  0.846,
    0.134,  0.77 ,  0.57 ,  0.846,  0.482,  0.846,  0.846,  0.846,
    0.846,  0.846,  0.757,  0.457,  0.934,  0.902,  0.846,  0.326,
    0.846,  0.205,  0.396,  0.143,  0.553,  0.683,  0.846,  0.706,
    0.91 ,  0.18 ,  0.591,  0.769,  0.   ,  0.112,  0.546,  0.449,
    0.195,  0.2  ,  0.689,  0.883,  0.692,  0.812,  0.213,  0.843,
    0.846,  0.155,  0.514,  0.59 ,  0.495,  0.846,  0.717,  0.74 ,
    0.121,  0.866,  0.266,  0.925,  0.915,  0.151,  0.846,  0.531,
    0.846,  0.176,  0.846,  0.849,  0.813,  0.846,  0.543,  0.19 ,
    0.875,  0.846,  0.846,  0.466,  0.846,  0.197,  0.583,  0.646,
    0.186,  0.683,  0.841,  0.205,  0.725,  0.846,  0.302,  0.134,
    0.846,  0.846,  0.993,  0.437,  0.663,  0.559,  0.421]

v = [False, False, False,  True, False, False,  True, False, False,
       False,  True, False,  True, False, False, False,  True, False,
        True, False,  True, False, False,  True, False, False,  True,
        True,  True, False, False,  True, False,  True,  True,  True,
        True,  True, False, False, False,  True,  True,  True,  True,
        True, False, False,  True,  True, False, False, False, False,
        True, False, False,  True,  True,  True, False, False, False,
       False,  True, False,  True, False, False,  True,  True, False,
       False,  True, False, False,  True, False,  True,  True, False,
       False,  True,  True, False,  True, False, False,  True,  True,
       False,  True,  True, False,  True,  True, False, False, False,
        True, False, False,  True]

我现在计算精度和召回值:

pre, rec, thr = metrics.precision_recall_curve(v, p)

...并绘制它们:

plt.plot(thr, pre[:-1], '-', label='precition')
plt.plot(thr, rec[:-1], '-', label='recall')
plt.legend()

这就是我得到的:

我的精确召回图

到底是怎么回事?为什么这张图不像我们在这里看到的更相似?是我的模型有问题还是我如何使用该precision_recall_curve功能?

2个回答

这可能违反直觉,但就分类阈值而言,精度不一定是单调递减的。另一方面,召回率是单调递增的。(我假设您根据降低的分类器分数对数据进行排名,这似乎与您的示例相反,但不会改变结论)

精度和召回率的定义是: with TP , FP 和 FN 分别为真阳性、假阳性和假阴性的数量。

precision=TPTP+FP,recall=TPTP+FN,

假设通过对应的分类器分数对真实标签进行排序后,我们得到以下结果:

[False,True,False,True,True,True,False,False],

这导致精确召回空间中的以下几点:

precision=[0,12,13,24,35,46,47,48],recall=[0,14,14,24,34,44,44,44].

如您所见,召回率是单调递增的,但准确率在排名中间的某个位置有最大值 (阈值方面的精度形状可以采用任何形式,但通常在高阈值时您将具有高精度,反之亦然。46)

请注意,在高于我们观察到的最高值 (0/0) 的截止值处精度未定义,但通常我们说这是 0,例如在计算精度-召回曲线下的面积时。

为了补充 Marc Claessen 的答案,我想指出precision_recall_curvescikit-learn 的方法将 ( recall=0, precision=1) 的一个额外数据点附加到返回的数组中。相应描述中所述:

最后的精度和召回值分别为 1. 和 0.,并且没有相应的阈值。这可确保图形从 y 轴开始。

如果计算出的召回率和准确率分数包括一对 ( precision=0, recall=0)。recall=0(0和)会有两个相互冲突的精度值1,这可能会导致伪影。