- La divergencia KL mide cuánto difiere una distribución real (P) de una referencia (Q) en términos de entropía relativa.
- Calcula KL en ejemplos discretos, incluyendo el suavizado necesario ante probabilidades nulas.
- Aplícala a evaluación de modelos y detección de drift, teniendo en cuenta su asimetría e inestabilidad.
1. Definición #
Para distribuciones discretas (P) y (Q):
$$ \mathrm{KL}(P \parallel Q) = \sum_i p_i \log \frac{p_i}{q_i} $$
- ( \mathrm{KL}(P \parallel Q) = 0 ) si (P = Q).
- Es asimétrica: ( \mathrm{KL}(P \parallel Q) \neq \mathrm{KL}(Q \parallel P) ).
- Sensible a diferencias de soporte: si ( q_i = 0 ) y ( p_i > 0 ), diverge a infinito.
2. Cálculo en Python #
import numpy as np
from scipy.special import rel_entr # p * log(p / q) elemento a elemento
def kl_divergence(p: np.ndarray, q: np.ndarray) -> float:
"""Divergencia KL D(P || Q)."""
p = np.asarray(p, dtype=float)
q = np.asarray(q, dtype=float)
p = p / p.sum()
q = q / q.sum()
epsilon = 1e-12
return float(np.sum(rel_entr(p + epsilon, q + epsilon)))
Agregar un epsilon pequeño evita divisiones por cero cuando hay probabilidades nulas. Ajusta el suavizado según el dominio.
3. Ejemplo con histogramas #
import matplotlib.pyplot as plt
import japanize_matplotlib # opcional para etiquetas en japonés
a = np.array([0.1, 0.2, 0.3, 0.2, 0.1, 0.1])
b = np.array([0.05, 0.1, 0.2, 0.3, 0.3, 0.05])
plt.figure(figsize=(12, 4))
plt.bar(np.arange(a.size) - 0.1, a, width=0.2, label="P")
plt.bar(np.arange(b.size) + 0.1, b, width=0.2, label="Q")
plt.legend()
plt.show()
print(f"KL(P || P) = {kl_divergence(a, a):.4f}")
print(f"KL(P || Q) = {kl_divergence(a, b):.4f}")
print(f"KL(Q || P) = {kl_divergence(b, a):.4f}")
Intercambiar el orden cambia el resultado; interpreta KL con el punto de vista “referencia vs. objetivo” correcto.
4. Conexión con la divergencia Jensen–Shannon #
Para obtener una medida simétrica y acotada, promedia ambas direcciones de KL:
plt.hist(np.random.normal(1, 1, 1000), alpha=0.85, color="blue")
plt.hist(np.random.normal(4, 1, 1000), alpha=0.85, color="red")
plt.hist(np.random.normal(2.5, 1, 1000), alpha=0.85, color="green")
plt.show()
La divergencia Jensen–Shannon mitiga los valores infinitos cuando los soportes difieren y es más práctica en contextos reales.
5. Usos y precauciones #
- Evaluación de modelos generativos: monitoriza cuánto se desvía la distribución generada de la real.
- Monitorización/drift: sigue cómo los datos en producción se alejan de los de entrenamiento.
- Modelos de lenguaje: compara distribuciones de n-gramas o probabilidades token.
Utiliza suavizado (p. ej., priors de Dirichlet) cuando los datos son escasos. Un KL alto no implica necesariamente fracaso; combínalo con otras métricas.
Resumen #
La divergencia KL captura la diferencia relativa entre distribuciones. Su asimetría y sensibilidad a probabilidades nulas exigen un uso cuidadoso, pero con suavizado y métricas complementarias proporciona señales valiosas sobre desviaciones o drift.