可视化模型预测概率的校准


23

假设我有一个预测模型,该模型为每种情况下产生每个类别的概率。现在,我认识到,如果我想使用这些概率进行分类(精确度,召回率等),则有很多方法可以评估这种模型。我也认识到,ROC曲线及其下的区域可用于确定模型在各类之间的区分程度。这些不是我要问的。

我有兴趣评估模型的校准我知道,一个评分规则,如布来得分可以完成这个任务非常有用。没关系,我可能会沿这条线合并一些内容,但是我不确定这样的指标对外行人有多直观。我正在寻找更直观的东西。我希望解释结果的人能够看到模型预测某事发生的概率是70%的可能性是它会在约70%的时间实际发生,等等。

我听说过(但从未使用过)QQ图,起初我以为这是我想要的。但是,看来这确实是为了比较两个概率分布。那不是我直接拥有的。对于一堆实例,我有我的预测概率,然后是事件是否实际发生:

Index    P(Heads)    Actual Result
    1          .4            Heads
    2          .3            Tails
    3          .7            Heads
    4         .65            Tails
  ...         ...              ...

那么QQ情节真的是我想要的,还是我在寻找其他东西?如果我应该使用QQ图,将数据转换为概率分布的正确方法是什么?

我想我可以按预测的概率对两列进行排序,然后创建一些垃圾箱。这是我应该做的事情,还是我想念某个地方?我熟悉各种离散化技术,但是有没有一种具体的方法可以将离散化到这种情况下的垃圾箱中?

Answers:


19

你的想法很好。

约翰·图基(John Tukey)建议按一半进行分箱:将数据分成上下两半,然后将这些两半分开,然后递归地将极端两半分开。与等宽合并相比,这可以目视检查尾部行为,而无需在大量数据(中间)中使用过多的图形元素。

这是Tukey方法的示例(使用R)。(这并不完全相同:他的实现方式mletter有所不同。)

首先,让我们创建一些预测和一些符合这些预测的结果:

set.seed(17)
prediction <- rbeta(500, 3/2, 5/2)
actual <- rbinom(length(prediction), 1, prediction)
plot(prediction, actual, col="Gray", cex=0.8)

该图不是非常有用,因为所有actual值当然都是(未发生)或(已发生)。(在下面的第一个图中,它显示为灰色空心圆圈的背景。)此图需要平滑。为此,我们对数据进行bin。函数进行一半拆分。它的第一个参数是介于1和(第二个参数)之间的等级数组。它为每个容器返回唯一的(数字)标识符:01个mletterrn

mletter <- function(r,n) {
    lower <-  2 + floor(log(r/(n+1))/log(2))
    upper <- -1 - floor(log((n+1-r)/(n+1))/log(2))
    i <- 2*r > n
    lower[i] <- upper[i]
    lower
}

使用此方法,我们将预测和结果进行分箱,并在每个分箱内取平均值。在此过程中,我们计算箱体总数:

classes <- mletter(rank(prediction), length(prediction))
pgroups <- split(prediction, classes)
agroups <- split(actual, classes)
bincounts <- unlist(lapply(pgroups, length)) # Bin populations
x <- unlist(lapply(pgroups, mean))           # Mean predicted values by bin
y <- unlist(lapply(agroups, mean))           # Mean outcome by bin

为了有效地对图形进行符号化,我们应使符号面积与箱数成正比。稍微改变一下符号颜色也可能会有所帮助:

binprop <- bincounts / max(bincounts)
colors <- -log(binprop)/log(2)
colors <- colors - min(colors)
colors <- hsv(colors / (max(colors)+1))

有了这些,我们现在可以增强前面的图:

abline(0,1, lty=1, col="Gray")                           # Reference curve
points(x,y, pch=19, cex = 3 * sqrt(binprop), col=colors) # Solid colored circles
points(x,y, pch=1, cex = 3 * sqrt(binprop))              # Circle outlines

数字

作为不良预测的一个示例,让我们更改数据:

set.seed(17)
prediction <- rbeta(500, 5/2, 1)
actual <- rbinom(length(prediction), 1, 1/2 + 4*(prediction-1/2)^3)

重复分析,将产生以下图表,其中的偏差显而易见:

图2

该模型往往过于乐观(50%至90%范围内的预测平均结果太低)。在少数情况下预测较低(小于30%)时,该模型过于悲观。


(+1)很好,谢谢。我认为颜色可能会偏离目标,但其余部分是一个不错的主意,并且非常好解释。
Michael McGowan

迈克尔,我发现必须使用一些颜色才能帮助看到两端出现的很小的圆圈。当然,恒定的颜色可以做到这一点。只需替换col=colors为所需的颜色,例如col="Red"
ub

+1,这非常好。但是,我不太理解为什么参考线是简单的45度直线,而不是适当的逻辑回归线或黄土?我认为这些将是判断预测质量的更适当参考。
gung-恢复莫妮卡

pp±[01个]×[01个]
15:04

@gung(第2步)我想您可能会想到的是改进可视化效果,以解决残差的预期变化。该变化应与成正比p1个-p/ñpñ

4

另一个选择是等渗回归。它与whuber的答案类似,不同的是,垃圾箱是动态生成的,而不是通过分成两半来生成的,这要求输出严格增加。

等渗回归的主要用途是重新校准您的概率,如果它们显示的校准不佳,那么它也可以用于可视化。基本上,如果等渗回归线大致遵循Y = X线,则您的概率已正确校准。

等渗回归概率

这是等渗回归,适用于Whuber显示的问题。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.isotonic import IsotonicRegression

prediction = np.random.beta(3.0/2.0, 5.0/2.0, size=500)
actual = np.random.binomial(1,prediction, len(prediction))
plt.scatter(prediction, actual,  facecolors='none', edgecolors=[0.3,0.3,0.3], label='Data')

ir = IsotonicRegression()
isotonic = ir.fit_transform(prediction, actual)
plt.plot(prediction, isotonic,'ok', label='Isotonic Fit')

plt.xlabel('Prediction')
plt.ylabel('Actual')
plt.plot([0,1],[0,1], '--k', label='y=x line')
plt.legend(loc = 'center left')

http://fa.bianp.net/blog/2013/isotonic-regression/

http://stat.wikia.com/wiki/Isotonic_regression


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.