Métricas de Clasificación en Minería de Datos

Evaluación estratégica de modelos en el proceso KDD

Diego Villalba

2026-08-16

Métricas de Clasificación

Evaluación estratégica de modelos en el proceso KDD

“No se puede mejorar lo que no se puede medir — pero medir mal puede ser peor que no medir.”

Objetivos de Aprendizaje

  1. Situar la evaluación dentro del proceso KDD
  2. Interpretar la matriz de confusión y el costo diferencial de los errores
  3. Calcular e interpretar Accuracy, Precision, Recall, F1, ROC-AUC
  4. Seleccionar la métrica adecuada según el contexto y el desbalance
  5. Analizar el efecto del umbral de decisión sobre el clasificador
  6. Tomar decisiones informadas en contextos de medicina y finanzas

Bloque 1: Evaluación en el KDD

El Proceso KDD

La Evaluación no es el paso final — es el guardián del conocimiento descubierto.

¿Por qué importa la métrica correcta?

Escenario: Un modelo predice si un paciente tiene cáncer.

  • Dataset: 950 sanos, 50 enfermos (1000 total)
  • Modelo “inteligente”: predice siempre “sano”

Resultado: \text{Accuracy} = \frac{950}{1000} = 95\%

Paradoja de la Exactitud

Un modelo con 95% de accuracy detecta 0 de los 50 enfermos.
Elegir la métrica incorrecta puede matar conocimiento valioso — y en medicina, pacientes.

Bloque 2: Matriz de Confusión

Estadistica de un clasificador

Diagrama de resultados de un clasificador

Distribucion de clasificacion

Diagrama de distribucion de clasificacion

Anatomía de la Matriz de Confusión

\begin{array}{c|cc} & \textbf{Predicho +} & \textbf{Predicho -} \\ \hline \textbf{Real +} & TP & FN \\ \textbf{Real -} & FP & TN \end{array}

Símbolo Nombre Significado
TP Verdadero Positivo Enfermo → predicho Enfermo ✓
TN Verdadero Negativo Sano → predicho Sano ✓
FP Falso Positivo Sano → predicho Enfermo ✗
FN Falso Negativo Enfermo → predicho Sano ✗

El Costo Diferencial del Error

Medicina

FN es el peor error

  • Paciente enfermo → diagnosticado sano
  • Consecuencia: sin tratamiento, progresión de la enfermedad
  • Costo: mortalidad, daño irreversible

Preferimos más FP (alarmas falsas) antes que perder un caso real.

Finanzas

FP es el peor error

  • Transacción legítima → marcada como fraude
  • Consecuencia: bloqueo de cuenta, fricción con el cliente
  • Costo: pérdida del cliente, reputación

Preferimos más FN (fraudes no detectados) antes que bloquear clientes reales.

Visualizando la Matriz de Confusión

Para esta clase emplearemos un dataset sintético de diagnóstico médico desbalanceado (92% sanos, 8% enfermos) para ilustrar la importancia de las métricas más allá del accuracy.

Matriz de confusión:
[[272   3]
 [ 20   5]]

TP=5, TN=272, FP=3, FN=20

Importante

No existe una métrica universalmente “correcta”. La elección depende del costo asimétrico del error.

Visualización de la Matriz

Bloque 3: Accuracy y Sus Trampas

Definición Formal de Accuracy

\text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN}

Interpretación: Proporción de predicciones correctas sobre el total.

from sklearn.metrics import accuracy_score

acc = accuracy_score(y_test, y_pred)
print(f"Accuracy del modelo: {acc:.4f} ({acc*100:.2f}%)")

# El modelo "trivial" que siempre dice "sano"
y_trivial = np.zeros_like(y_test)  # Siempre predice clase 0 (sano)
acc_trivial = accuracy_score(y_test, y_trivial)
print(f"Accuracy modelo trivial: {acc_trivial:.4f} ({acc_trivial*100:.2f}%)")
Accuracy del modelo: 0.9233 (92.33%)
Accuracy modelo trivial: 0.9167 (91.67%)

Trampa del Accuracy

El modelo trivial puede tener accuracy igual o mayor que el modelo real, en datasets desbalanceados. ¿Cuál usarías en producción?

La Paradoja Visualizada

El modelo trivial tiene Recall = 0% en la clase positiva. No detecta ningún enfermo.

Bloque 4: Métricas de Relevancia

Precision — ¿Qué tan confiables son mis alarmas?

\text{Precision} = \frac{TP}{TP + FP}

Intuición: De todos los casos que el modelo dijo “positivo”, ¿cuántos realmente lo eran?

Alta Precision: - Pocas alarmas falsas - Cuando el modelo alerta, hay que hacerle caso - Importante cuando los FP son costosos

Ej: Spam → mejor no bloquear email legítimo

Baja Precision: - Muchas alarmas falsas - Modelo “gritador de lobo” - Pérdida de confianza del usuario

Ej: Fraude → muchos clientes bloqueados por error

Recall (Sensibilidad) — ¿Cuántos enfermos detecté?

\text{Recall} = \text{Sensibilidad} = \frac{TP}{TP + FN}

Intuición: De todos los casos que realmente eran positivos, ¿cuántos encontré?

Recall es crítico cuando los FN son costosos

  • Medicina: No detectar cáncer (FN) → tratamiento tardío
  • Seguridad: No detectar intrusión (FN) → brecha de seguridad
  • Terremotos: No detectar sismo (FN) → víctimas

Limitación: Un modelo que predice siempre positivo tiene Recall = 100%

\text{Si } \hat{y} = 1 \text{ siempre}: \quad \text{Recall} = \frac{TP}{TP + 0} = 1.0

Specificity (Especificidad) — Protegiendo a los sanos

\text{Specificity} = \frac{TN}{TN + FP}

Intuición: De todos los verdaderamente negativos, ¿cuántos identifiqué correctamente?

Métrica Denominator ¿Qué protege?
Recall TP + FN (todos los positivos reales) Detectar los positivos
Specificity TN + FP (todos los negativos reales) Proteger a los negativos

Complemento: \text{Tasa de Falsos Positivos} = 1 - \text{Specificity} = \frac{FP}{TN + FP}

En medicina: Sensibilidad = no perder enfermos, Especificidad = no alarmar sanos.

Calculando las Tres Métricas

from sklearn.metrics import classification_report, precision_score, recall_score

cm_vals = confusion_matrix(y_test, y_pred)
TP = cm_vals[1, 1]
TN = cm_vals[0, 0]
FP = cm_vals[0, 1]
FN = cm_vals[1, 0]

precision = TP / (TP + FP)
recall    = TP / (TP + FN)
specificity = TN / (TN + FP)

print(f"TP={TP}, TN={TN}, FP={FP}, FN={FN}")
print(f"\nPrecision:    {precision:.4f} ({precision*100:.1f}%)")
print(f"Recall:       {recall:.4f} ({recall*100:.1f}%)")
print(f"Specificity:  {specificity:.4f} ({specificity*100:.1f}%)")
TP=5, TN=272, FP=3, FN=20

Precision:    0.6250 (62.5%)
Recall:       0.2000 (20.0%)
Specificity:  0.9891 (98.9%)

El Dilema Precision-Recall

A medida que sube el umbral: ↑ Precision, ↓ Recall. No hay umbral “correcto” — depende del costo del error.

Bloque 5: F1-Score y Variantes

F1-Score — La Media Armónica

F1 = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}}

¿Por qué media armónica y no aritmética?

La media armónica penaliza más los valores extremos:

\text{Si P=1.0, R=0.01}: \quad \bar{x} = 0.505 \quad \text{vs} \quad F1 = 0.0198

Cuándo usar F1

  • Dataset desbalanceado
  • Los dos tipos de error (FP y FN) tienen peso similar
  • Necesitas una sola métrica para comparar modelos

Variantes para Clasificación Multiclase

F1_{\text{macro}} = \frac{1}{C}\sum_{c=1}^{C} F1_c \qquad \text{(cada clase pesa igual)}

F1_{\text{micro}} = \frac{2 \cdot \sum TP_c}{2 \cdot \sum TP_c + \sum FP_c + \sum FN_c} \qquad \text{(cada instancia pesa igual)}

F1_{\text{weighted}} = \sum_{c=1}^{C} w_c \cdot F1_c, \quad w_c = \frac{|c|}{N} \qquad \text{(pondera por frecuencia)}

Variante Favorece Usar cuando
Macro Clases minoritarias Todas las clases importan igual
Micro Clases mayoritarias Las instancias importan más que las clases
Weighted Clases más frecuentes Importancia proporcional a la frecuencia
from sklearn.metrics import f1_score

f1_bin = f1_score(y_test, y_pred)
print(f"F1-Score (binario):  {f1_bin:.4f}")

# Reporte completo
print("\n" + classification_report(y_test, y_pred,
      target_names=['Sano', 'Enfermo']))
F1-Score (binario):  0.3030

              precision    recall  f1-score   support

        Sano       0.93      0.99      0.96       275
     Enfermo       0.62      0.20      0.30        25

    accuracy                           0.92       300
   macro avg       0.78      0.59      0.63       300
weighted avg       0.91      0.92      0.90       300

Bloque 6: ROC-AUC y Precision-Recall

Curva ROC — Capacidad Discriminativa Global

\text{Eje X: FPR} = \frac{FP}{FP + TN} = 1 - \text{Specificity} \text{Eje Y: TPR} = \frac{TP}{TP + FN} = \text{Recall}

from sklearn.metrics import roc_curve, auc

fpr, tpr, thresholds_roc = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)
print(f"AUC-ROC: {roc_auc:.4f}")
AUC-ROC: 0.7593

Interpretación probabilística del AUC:

P(\hat{p}(x^+) > \hat{p}(x^-))= \text{AUC}

Si AUC = 0.85, hay un 85% de probabilidad de que el modelo asigne mayor score a una instancia positiva que a una negativa escogida al azar.

Visualización Interactiva: Curva ROC

Curva Precision-Recall

¿Por qué Precision-Recall para clases desbalanceadas?

La curva ROC incluye TN en su denominador (especificidad). Con millones de TN, el FPR parece pequeño aunque haya muchos FP. La curva PR ignora los TN y se enfoca solo en la clase positiva (minoritaria).

ROC vs. Precision-Recall: ¿Cuándo usar cada una?

Criterio ROC-AUC Precision-Recall
Dataset balanceado ✅ Ideal ✅ Válida
Clase minoritaria importa ⚠️ Puede ser optimista ✅ Más informativa
Comparación general ✅ Estándar ✅ Más rigurosa
Interpretación intuitiva ✅ Fácil (prob.) ⚠️ Área promedio
Cuando TN son irrelevantes ❌ Los incluye ✅ Los ignora

Bloque 7: Optimización de Umbrales

El Umbral de Decisión

La mayoría de los clasificadores producen una probabilidad, no una clase directa:

\hat{y} = \begin{cases} 1 & \text{si } \hat{p}(x) \geq \theta \\ 0 & \text{si } \hat{p}(x) < \theta \end{cases}

El umbral \theta = 0.5 es una convención, no una verdad absoluta.

Bajar el umbral (\theta < 0.5): - ↑ Recall (más positivos detectados) - ↓ Precision (más falsos positivos) - Modelo más “alarmista”

Subir el umbral (\theta > 0.5): - ↓ Recall (menos positivos detectados) - ↑ Precision (más confiable cuando alerta) - Modelo más “conservador”

Exploración Interactiva del Umbral

Selección de Umbral según el Contexto

# Encontrar el umbral que maximiza el F1-Score
f1_scores = []
for u in np.arange(0.05, 0.95, 0.01):
    y_u = (y_prob >= u).astype(int)
    f1_scores.append(f1_score(y_test, y_u, zero_division=0))

umbral_optimo_f1 = np.arange(0.05, 0.95, 0.01)[np.argmax(f1_scores)]
print(f"Umbral óptimo (max F1): θ = {umbral_optimo_f1:.2f}")

# Para medicina: priorizar Recall >= 0.90
for u in np.arange(0.05, 0.95, 0.01):
    y_u = (y_prob >= u).astype(int)
    r = recall_score(y_test, y_u, zero_division=0)
    p = precision_score(y_test, y_u, zero_division=0)
    if r >= 0.90:
        print(f"Umbral médico (Recall≥90%): θ={u:.2f} → P={p:.3f}, R={r:.3f}")
        break
Umbral óptimo (max F1): θ = 0.23

Síntesis Comparativa

¿Qué métrica usar y cuándo?

Situación Métrica recomendada Referencia clave
Dataset balanceado Accuracy, F1 macro Han et al. (2011)
Clase positiva rara (< 10 %) F1 clase positiva, PR-AUC Saito & Rehmsmeier (2015)
FN muy costoso (medicina, seguridad) Recall / Sensibilidad James et al. (2021)
FP muy costoso (spam, fraude leve) Precision Fawcett (2006)
FP y FN con costo similar F1-Score Han et al. (2011)
Comparar modelos sin fijar umbral ROC-AUC Fawcett (2006); Bamber (1975)
Clase escasa + interés en ranking Precision-Recall AUC Saito & Rehmsmeier (2015)
Multiclase, todas las clases importan igual F1 macro Pedregosa et al. (2011)

Comparación Final de los Dos Modelos

El modelo médico tiene menor accuracy pero mayor recall. ¿Cuál es mejor para el médico?

Preguntas de Reflexión

  1. Un banco detecta fraudes con 99.9% de accuracy. El dataset tiene 0.1% de fraudes reales. ¿Confiarías en ese modelo?

  2. Un modelo A tiene ROC-AUC = 0.95 y otro modelo B tiene ROC-AUC = 0.80. Para detectar una enfermedad rara (1 en 10,000), ¿cuál es “mejor”?

  3. Si el costo de un FN es 100 veces mayor que el costo de un FP, ¿cómo ajustarías el umbral de decisión?

  4. ¿Por qué un F1-Score macro puede ser peor métrica que el F1-Score de la clase positiva en un problema de detección de anomalías?

  5. ¿Puede un modelo tener AUC-ROC = 0.95 pero ser inútil en producción? Explica el escenario.

Conclusiones Clave

  • Accuracy miente en datasets desbalanceados — siempre reportar métricas adicionales
  • No hay métrica universal — la elección depende del costo asimétrico del error
  • Recall protege de FN; Precision protege de FP — el contexto dicta cuál priorizar
  • F1-Score equilibra ambos errores con una sola cifra — ideal para comparar modelos
  • ROC-AUC mide capacidad discriminativa independiente del umbral
  • PR-AUC es más informativa cuando la clase positiva es minoritaria
  • El umbral de decisión es una palanca estratégica — no un parámetro fijo
  • Las métricas son conocimiento sobre el modelo — en KDD, la evaluación retroalimenta todo el proceso

Bibliografía

  • Han, J., Kamber, M., & Pei, J. (2011). Data Mining: Concepts and Techniques (3rd ed.). Morgan Kaufmann.

  • Fawcett, T. (2006). An introduction to ROC analysis. Pattern Recognition Letters, 27(8), 861–874.

  • Saito, T., & Rehmsmeier, M. (2015). The precision-recall plot is more informative than the ROC plot when evaluating binary classifiers on imbalanced datasets. PLOS ONE, 10(3), e0118432.

  • Provost, F., & Fawcett, T. (2013). Data Science for Business. O’Reilly Media.

  • James, G., Witten, D., Hastie, T., & Tibshirani, R. (2021). An Introduction to Statistical Learning (2nd ed.). Springer.

  • Pedregosa, F., et al. (2011). Scikit-learn: Machine Learning in Python. Journal of Machine Learning Research, 12, 2825–2830.

¡Gracias!

Resumen en una Frase

“Elige la métrica que penalice el error que más te cuesta — y desconfía de cualquier número que parezca demasiado bueno.”

Material disponible: slides + código Python ejecutable

¿Preguntas?