13. Matriz de confusión, precisión, recall y F1

13.1 Por qué este tema es clave

En el tema anterior vimos que la exactitud no siempre alcanza para evaluar un clasificador. Ahora vamos a profundizar en las herramientas que permiten entender qué tipo de aciertos y qué tipo de errores está cometiendo el modelo.

Eso es importante porque no todos los errores cuestan lo mismo. En algunos problemas, dejar pasar un caso positivo es grave. En otros, marcar demasiados positivos también puede ser un problema.

13.2 La matriz de confusión: una tabla para mirar con claridad

La matriz de confusión resume cómo se comparan las predicciones del modelo con los valores reales.

En un problema binario aparecen cuatro situaciones:

  • Verdadero positivo: el caso era positivo y el modelo dijo positivo.
  • Verdadero negativo: el caso era negativo y el modelo dijo negativo.
  • Falso positivo: el caso era negativo, pero el modelo dijo positivo.
  • Falso negativo: el caso era positivo, pero el modelo dijo negativo.

La utilidad de esta tabla es que deja de ocultar los errores dentro de un único número global.

13.3 Un ejemplo intuitivo

Supongamos un sistema que intenta detectar si un paciente tiene una enfermedad:

  • si el modelo dice “enfermo” y realmente lo está, tenemos un verdadero positivo;
  • si dice “sano” y realmente está sano, tenemos un verdadero negativo;
  • si dice “enfermo” cuando no lo está, tenemos un falso positivo;
  • si dice “sano” cuando sí estaba enfermo, tenemos un falso negativo.

En un problema médico, un falso negativo suele ser muy delicado, porque significa no detectar a tiempo un caso real.

13.4 Qué significa precisión

La precisión responde a esta pregunta:

De todos los casos que el modelo marcó como positivos, ¿cuántos eran realmente positivos?

Si la precisión es baja, significa que el modelo está generando muchos falsos positivos.

En términos prácticos, la precisión importa cuando queremos que una predicción positiva sea confiable.

13.5 Qué significa recall

El recall responde a otra pregunta:

De todos los casos positivos reales, ¿cuántos logró detectar el modelo?

Si el recall es bajo, significa que el modelo está dejando escapar muchos positivos reales, es decir, tiene muchos falsos negativos.

Esta métrica es muy valiosa cuando detectar los casos positivos es especialmente importante.

13.6 Qué representa F1

La métrica F1 combina precisión y recall en un solo valor. No es un simple promedio común: está diseñada para penalizar situaciones donde una de las dos métricas es buena y la otra es mala.

Por eso, F1 resulta útil cuando necesitamos equilibrio entre ambas.

13.7 Ejemplo muy claro: detección de enfermedad

Vamos a usar un ejemplo pequeño y explícito. El objetivo es predecir si un paciente tiene una enfermedad a partir de dos variables:

  • edad;
  • nivel de un marcador biológico.

Después de entrenar el modelo, construiremos la matriz de confusión y calcularemos precisión, recall y F1.

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, accuracy_score

pacientes = pd.DataFrame({
    "edad": [25, 30, 34, 38, 40, 43, 46, 50, 54, 58, 61, 65],
    "marcador": [0.8, 1.0, 1.1, 1.4, 1.5, 1.7, 2.0, 2.1, 2.4, 2.6, 2.8, 3.0],
    "enfermedad": [0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1]
})

X = pacientes[["edad", "marcador"]]
y = pacientes["enfermedad"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.33, random_state=42, stratify=y
)

modelo = LogisticRegression()
modelo.fit(X_train, y_train)

y_pred = modelo.predict(X_test)
matriz = confusion_matrix(y_test, y_pred)

print("Valores reales:", y_test.values)
print("Predicciones:", y_pred)
print("Matriz de confusión:")
print(matriz)
print("Exactitud:", accuracy_score(y_test, y_pred))
print("Precisión:", precision_score(y_test, y_pred))
print("Recall:", recall_score(y_test, y_pred))
print("F1:", f1_score(y_test, y_pred))

nuevo_paciente = pd.DataFrame({
    "edad": [52],
    "marcador": [2.3]
})

prediccion = modelo.predict(nuevo_paciente)[0]
probabilidad = modelo.predict_proba(nuevo_paciente)[0, 1]

print("Predicción para el nuevo paciente:", prediccion)
print(f"Probabilidad de enfermedad: {probabilidad:.3f}")

Salida resumida esperada:

Valores reales: [...]
Predicciones: [...]
Matriz de confusión:
[[... ...]
 [... ...]]
Exactitud: ...
Precisión: ...
Recall: ...
F1: ...
Predicción para el nuevo paciente: ...
Probabilidad de enfermedad: ...

13.8 Cómo leer la matriz del ejemplo

En Scikit-learn, la matriz de confusión de un problema binario suele organizarse así:

  • fila 1, columna 1: verdaderos negativos;
  • fila 1, columna 2: falsos positivos;
  • fila 2, columna 1: falsos negativos;
  • fila 2, columna 2: verdaderos positivos.

Eso permite ver enseguida si el modelo se equivoca más por exceso de alarmas o por no detectar casos reales.

13.9 Relación entre las métricas y los errores

La conexión práctica es esta:

  • si hay muchos falsos positivos, la precisión tenderá a bajar;
  • si hay muchos falsos negativos, el recall tenderá a bajar;
  • si una de las dos cae mucho, F1 también se resentirá.

Por eso la matriz de confusión y estas métricas deben leerse juntas. Una tabla te muestra el detalle; las métricas te dan un resumen numérico.

13.10 Cuándo conviene priorizar precisión o recall

Depende del problema:

  • en detección de fraude, quizás prefieras más recall para no dejar escapar operaciones sospechosas;
  • en un sistema automático de sanciones, tal vez prefieras más precisión para no acusar incorrectamente a usuarios inocentes;
  • en medicina, muchas veces detectar más casos reales tiene prioridad, aunque luego haga falta revisar falsos positivos.

No existe una métrica “mejor” en abstracto. Existe una métrica más coherente con el costo de error del problema real.

13.11 Explicación detallada del código

  • confusion_matrix(y_test, y_pred): construye la tabla de aciertos y errores.
  • precision_score(...): mide la calidad de las predicciones positivas.
  • recall_score(...): mide cuántos positivos reales fueron detectados.
  • f1_score(...): resume el equilibrio entre precisión y recall.
  • predict_proba(...): devuelve la probabilidad estimada de la clase positiva.

El código es corto, pero conceptualmente muy importante. Con pocas líneas ya podemos entender bastante mejor el comportamiento del modelo.

13.12 Errores frecuentes

  • Confundir precisión con recall: una habla de los positivos predichos; la otra, de los positivos reales.
  • Mirar solo F1 sin revisar la matriz: el número resume, pero no explica qué error domina.
  • Usar solo exactitud en datasets desbalanceados: puede ocultar problemas graves.
  • No pensar el problema real: la elección de métrica debe responder al contexto, no a costumbre.

13.13 Qué deberías retener

  • La matriz de confusión muestra el detalle de aciertos y errores.
  • La precisión indica qué tan confiables son los positivos predichos.
  • El recall indica cuántos positivos reales logra encontrar el modelo.
  • F1 ayuda a resumir el equilibrio entre precisión y recall.
  • La mejor métrica depende del costo real de cada tipo de error.