25 votos

La visualización de la calibración de predecir la probabilidad de un modelo de

Supongamos que tengo un modelo predictivo que produce, para cada instancia, una probabilidad para cada clase. Ahora reconozco que hay muchas maneras de evaluar un modelo que si quiero usar esas probabilidades para la clasificación (precisión, recall, etc.). También reconozco que una curva ROC y el área debajo de ésta se puede utilizar para determinar qué tan bien el modelo distingue entre clases. Esas no son lo que te estoy preguntando acerca de.

Estoy interesado en la evaluación de la calibración del modelo. que una regla de puntuación como la de Brier score puede ser útil para esta tarea. Que bien, y que probablemente incorporar algo a lo largo de esas líneas, pero no estoy seguro de cómo intuitiva de tales indicadores serán para el laico. Estoy buscando algo más visual. Quiero que la persona que la interpretación de los resultados a ser capaz de ver si es o no cuando el modelo predice que algo es de un 70% de probabilidades de ocurrir que lo que realmente sucede, ~70% del tiempo, etc.

He oído hablar de (pero nunca) Q-Q parcelas, y al principio pensé que esto era lo que yo estaba buscando. Sin embargo, parece que realmente está destinado a la comparación de dos distribuciones de probabilidad. Que no es directamente lo que tengo. Tengo, por un montón de instancias, mi predice la probabilidad y, a continuación, si el evento ocurrido realmente:

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

Así que es una Q-Q plot realmente lo que quiero, o me estoy buscando algo más? Si un Q-Q plot es lo que yo debería estar usando, ¿cuál es la forma correcta para transformar mis datos a distribuciones de probabilidad?

Me imagino que podría ordenar ambas columnas por predice la probabilidad y, a continuación, crear algunos cajones. Es que el tipo de cosas que debería estar haciendo, o estoy fuera de mi pensamiento en algún lugar? Estoy familiarizado con las diversas técnicas de discretización, pero hay una manera específica de discretización en bandejas que es estándar para este tipo de cosas?

20voto

jldugger Puntos 7490

Su pensamiento es bueno.

John Tukey recomienda el agrupamiento por mitades: dividir los datos en mitades superior e inferior, a continuación, dividir dichas mitades, luego se divide el extremo mitades de forma recursiva. En comparación con igual anchura binning, esto permite la inspección visual de la cola de comportamiento sin dedicar demasiados elementos gráficos para la mayor parte de los datos (en el medio).

He aquí un ejemplo (con R) de Tukey enfoque. (No es exactamente el mismo: se implementó mletter un poco diferente.)

En primer lugar, vamos a crear algunas de las predicciones y algunos resultados que se ajustan a las predicciones:

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

La trama no es muy informativo, ya que todos los actual valores son, por supuesto, o $0$ (no se produjo) o $1$ (ocurrió). (Aparece como el fondo de color gris círculos abiertos en la primera figura a continuación.) Esta parcela necesidades de suavizado. Para ello, hemos de reciclaje de los datos. La función mletter hace la división por mitades. Su primer argumento r es una matriz de rangos entre 1 y n (el segundo argumento). Devuelve único (numérico) de identificadores para cada bin:

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
}

El uso de esta, nos bin tanto las predicciones y los resultados y el promedio de cada uno dentro de cada grupo. A lo largo del camino, se calcula bin poblaciones:

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

Para simbolizar la trama de manera efectiva debemos hacer el símbolo de áreas proporcionales a bin cuenta. Puede ser útil para variar el símbolo de colores un poco, demasiado, de donde:

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

Con estos en la mano, ahora podemos mejorar la anterior parcela:

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

Figure

Como un ejemplo de una mala predicción, vamos a cambiar los datos:

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

Repitiendo el análisis se produce esta trama en la que las desviaciones son claras:

Figure 2

Este modelo tiende a ser optimista (promedio de los resultados de las predicciones en el 50% a 90% de la gama son muy bajas). En los pocos casos donde la predicción es bajo (menos de 30%), el modelo es demasiado pesimista.

7voto

Bscan Puntos 131

Otra opción es isotónica de regresión. Es similar a whuber la respuesta, excepto los contenedores que se generan de forma dinámica en lugar de por división en mitades, con un requisito de que los resultados son estrictamente creciente.

Este uso principal de isotónica de regresión es volver a calibrar sus probabilidades, si han demostrado ser mal calibrado, pero también puede ser utilizado para la visualización. Básicamente, si la línea de regresión isotónica aproximadamente de la siguiente manera Y=X línea, a continuación, sus probabilidades son calibrados correctamente.

Isotonic Regression on probabilities

Este es Isotónica de Regresión aplicado al problema que se muestra por 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

0voto

Alp Puntos 446

También puede ser que desee mirar en el paquete de la "verificación":

http://cran.r-project.org/web/packages/verification/index.html

Hay parcelas en la viñeta que pueden ser útiles:

http://cran.r-project.org/web/packages/verification/vignettes/verification.pdf

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X