Tl;dr
¿Cómo puedo calcular correctamente la puntuación Brier para más de dos clases? Obtuve resultados confusos con diferentes enfoques. Detalles a continuación.
Como me sugirieron en un comentario a esta pregunta Me gustaría evaluar la calidad de un conjunto de clasificadores que entrené con la puntuación Brier. Estos clasificadores son multiclase y las clases están desequilibradas. La puntuación de Brier debería ser capaz de manejar estas condiciones. Sin embargo, no estoy muy seguro de cómo aplicar la prueba de la puntuación de Brier. Digamos que tengo 10 puntos de datos y 5 clases:
Los vectores calientes representan qué clase está presente en un elemento de datos determinado:
targets = array([[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 1, 0, 0],
[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0]])
Los vectores de probabilidades representan las salidas de mis clasificadores, asignando una probabilidad a cada clase
probs = array([[0.14, 0.38, 0.4 , 0.04, 0.05],
[0.55, 0.05, 0.34, 0.04, 0.01],
[0.3 , 0.35, 0.18, 0.09, 0.08],
[0.23, 0.22, 0.04, 0.05, 0.46],
[0. , 0.15, 0.47, 0.28, 0.09],
[0.23, 0.13, 0.34, 0.27, 0.03],
[0.32, 0.06, 0.59, 0.02, 0.01],
[0.01, 0.19, 0.01, 0.03, 0.75],
[0.27, 0.38, 0.03, 0.12, 0.2 ],
[0.17, 0.45, 0.11, 0.25, 0.01]])
Estas matrices están coindexadas, por lo que probs[i, j]
es la probabilidad de la clase targets[i, j]
.
Ahora, según Wikipedia la definición de la puntuación de Brier para las clases múltiples es
$$\frac{1}{N} \sum_{t=1}^{N} \sum_{i=1}^{R} (f_{ti} - o_{ti})^2$$
Cuando programo esto en Python y lo ejecuto en el targets
y probs
matrices, obtengo un resultado de $1.0069$
>>> def brier_multi(targets, probs):
... return np.mean(np.sum((probs - targets)**2, axis=1))
...
>>> brier_multi(targets, probs)
1.0068899999999998
Pero no estoy seguro de haber interpretado correctamente la definición.
Para Python, la biblioteca sklearn proporciona sklearn.metrics.brier_score_loss
. Aunque la documentación indica
La puntuación de Brier es adecuada para resultados binarios y categóricos que pueden estructurarse como verdaderos o falsos
Lo que la función hace en realidad es escoger uno (u obtener uno pasado como argumento) de $n > 2$ y tratar esa clase como clase $1$ y todas las demás clases como clase $0$ .
Por ejemplo, si elegimos la clase 3 (índice 2) como $1$ y, por tanto, todas las demás clases como clase $0$ obtenemos:
>>> # get true classes by argmax over binary arrays
... true_classes = np.argmax(targets, axis=1)
>>>
>>> brier_score_loss(true_classes, probs[:,2], pos_label=2)
0.13272999999999996
alternativamente:
>>> brier_score_loss(targets[:,2], probs[:,2])
0.13272999999999996
Esta es, en efecto, la versión binaria de la puntuación de Brier como se puede demostrar al definirlo y ejecutarlo manualmente:
>>> def brier_bin_(targets, probs):
... return np.mean((targets - probs) ** 2)
>>> brier_bin(targets[:,2], probs[:,2])
0.13272999999999996
Como se puede ver, este es el mismo resultado que el de sklearn brier_score_loss
.
Wikipedia dice sobre la versión binaria:
Esta formulación se utiliza sobre todo para eventos binarios (por ejemplo, "lluvia" o "sin lluvia"). La ecuación anterior es una regla de puntuación adecuada sólo para eventos binarios;
Así que... Ahora estoy confundido y tengo las siguientes preguntas:
1) Si sklearn calcula la puntuación Brier de varias clases como una puntuación binaria de uno contra todos, ¿es esa la única forma correcta de calcular la puntuación Brier de varias clases?
Lo que me lleva a
2) Si es así, mi brier_multi
el código debe estar basado en una idea errónea. ¿Cuál es mi idea errónea sobre la definición de la puntuación Brier multiclase?
3) Tal vez me equivoque de camino. En ese caso, por favor, explíqueme cómo calculo correctamente la puntuación de la Brier.
0 votos
¿cómo estáis? ¿Habéis conseguido utilizar el brier_multi? ¿Qué paquete habéis utilizado? Un saludo.
1 votos
He utilizado mi propio código tal y como lo he publicado en mi pregunta.