¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Evaluar un modelo: precisión y exhaustividad

Después de esta lección: Puedo juzgar un modelo con la matriz de confusión, la precisión, la exhaustividad y un conjunto de prueba.

Lección de 65 min3 comandosLaboratorio JupyterLab de ciencia de datos: pandas, Matplotlib y scikit-learn en el navegador

¿Basta con el porcentaje de aciertos?

Evaluar un modelo es medir cuánto acierta y qué fallos comete. Para eso se usan la matriz de confusión, la precisión y la exhaustividad (recall en inglés). Un solo porcentaje de aciertos puede esconder un modelo inútil.

Una empresa de alquiler de bicicletas quiere avisar los días movidos. Una regla acierta mucho, pero ¿a qué coste?

Al final de esta lección

Nota

Puedo juzgar un modelo con la matriz de confusión, la precisión, la exhaustividad y un conjunto de prueba.

Palabras clave

PalabraQué significaEjemplo
Matriz de confusiónuna tabla de aciertos y fallos
Falso positivoel modelo dice sí y era nouna falsa alarma
Falso negativoel modelo dice no y era síun caso perdido
Precisiónde los sí del modelo, la parte que era sí
Exhaustividadde los sí reales, la parte que el modelo encontró
Conjunto de pruebadatos que el modelo no usó para aprender

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

La matriz de confusión cuenta cuatro casos

Un modelo dice sí o no, y la realidad también. Eso da cuatro casos. Dos son aciertos y dos son fallos.

Un verdadero positivo es un sí que era sí. Un falso positivo es un sí que era no. Un falso negativo es un no que era sí. Un verdadero negativo es un no que era no.

Ejemplo resuelto: la regla de 12 grados

Dijo movidoDijo tranquiloTotal
Era movido109, acierto22, fallo131
Era tranquilo48, fallo186, acierto234
Total157208365 días

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Cuenta los cuatro casos con dos umbrales

Comando
docker exec jupyter python3 -c "import csv; d=list(csv.DictReader(open('hires.csv'))); y=[int(r['hires'])>=300 for r in d]; t=[float(r['temp_c']) for r in d]; print([(k, sum(a and b>=k for a, b in zip(y, t)), sum((not a) and b>=k for a, b in zip(y, t)), sum(a and b<k for a, b in zip(y, t)), sum((not a) and b<k for a, b in zip(y, t))) for k in (12, 15)])"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

La precisión y la exhaustividad miran fallos distintos

La precisión pregunta: cuando el modelo dice sí, ¿cuántas veces tiene razón? Es verdaderos positivos entre todos los sí del modelo.

La exhaustividad pregunta: de los sí reales, ¿cuántos encontró? Es verdaderos positivos entre todos los sí reales. Subir una suele bajar la otra.

Ejemplo resuelto: dos umbrales de temperatura

ReglaPrecisiónExhaustividadQué pasa
12 grados o más109 / 157 = 0,69109 / 131 = 0,83Encuentra casi todos, con falsas alarmas
15 grados o más76 / 99 = 0,7776 / 131 = 0,58Acierta más, pero pierde muchos

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Calcula la precisión y la exhaustividad

Comando
docker exec jupyter python3 -c "import csv; d=list(csv.DictReader(open('hires.csv'))); y=[int(r['hires'])>=300 for r in d]; t=[float(r['temp_c']) for r in d]; print([(k, round(sum(a and b>=k for a, b in zip(y, t)) / sum(b>=k for b in t), 2), round(sum(a and b>=k for a, b in zip(y, t)) / sum(y), 2)) for k in (12, 15)])"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error muy común

Advertencia

Mucha gente cree que un 99 % de aciertos es siempre un buen modelo. Si solo 1 de cada 100 operaciones es un fraude, decir siempre «no es fraude» acierta el 99 %. Su exhaustividad es 0: no encuentra ningún fraude. Mira siempre la precisión y la exhaustividad.

Cuenta los casos de seis días

Código: python
# Una regla: «movido si hace k grados o más». Cuenta los cuatro casos.
days = [[18, True], [9, False], [14, True], [11, True], [16, False], [7, False]]
k = 12
tp = 0
fp = 0
fn = 0
tn = 0
for day in days:
    predicted = day[0] >= k
    real = day[1]
    if predicted and real:
        tp = tp + 1
    elif predicted and not real:
        fp = fp + 1
    elif real:
        fn = fn + 1
    else:
        tn = tn + 1
print("tp", tp, "fp", fp, "fn", fn, "tn", tn)
print("precisión", round(tp / (tp + fp), 2))
print("exhaustividad", round(tp / (tp + fn), 2))
# Cambia k a 10 y vuelve a ejecutar. ¿Qué cifra sube y cuál baja?

Se juzga con datos que no vio

Si eliges la regla y la mides con los mismos días, el resultado es demasiado optimista. Por eso se separan los datos.

Con los primeros 292 días se elige la temperatura. Con los últimos 73, el conjunto de prueba, se juzga. Esos días no pudieron influir en la elección.

Elige la temperatura y mídela con días nuevos

Comando
docker exec jupyter python3 -c "import csv; d=list(csv.DictReader(open('hires.csv'))); y=[int(r['hires'])>=300 for r in d]; t=[float(r['temp_c']) for r in d]; a=lambda lo, hi, k: sum((t[i]>=k)==y[i] for i in range(lo, hi))/(hi-lo); k=max(range(26), key=lambda k: (a(0, 292, k), -k)); print(k, round(a(0, 292, k), 3), round(a(292, 365, k), 3), round(1-sum(y[292:])/73, 3))"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Para ir más lejos: el mejor corte

Un modelo da un número y tú pones el corte. Prueba 10, 12, 14, 16 y 18 grados con el programa de la lección. Apunta la precisión y la exhaustividad de cada uno. ¿Qué corte elegirías si una falsa alarma cuesta poco y perder un día movido cuesta mucho?

Sobre este laboratorio y su código: Laboratorio JupyterLab de ciencia de datos: pandas, Matplotlib y scikit-learn en el navegador

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.