Información y Sorpresa

La teoría de la información comienza con una pregunta engañosamente simple: ¿cuánto te sorprendes cuando ocurre un evento? Si llueve en Londres, apenas te sorprendes — llueve mucho. Si llueve en el Sahara, te sorprendes mucho — casi nunca llueve allí. Cuanto más improbable es un evento, más "información" conlleva cuando ocurre. Esto no es una metáfora vaga — Claude Shannon lo formalizó en una cantidad matemática precisa en 1948, y se convirtió en el fundamento de todo, desde los algoritmos de compresión hasta las funciones de pérdida que usamos para entrenar redes neuronales.

Shannon definió el contenido de información (también llamado autoinformación o sorpresa) de un evento $x$ como:

$$I(x) = -\log_2 P(x)$$

Desglosemos esto pieza por pieza.

$P(x)$ es la probabilidad de que ocurra el evento $x$. Debe estar en el intervalo $(0, 1]$ — el evento debe ser posible (probabilidad mayor que cero) y puede ser como máximo seguro (probabilidad igual a uno). Esta es la única entrada a la función de información: la probabilidad de lo que ocurrió.

$-\log_2$ es el logaritmo negativo en base 2, y el resultado se mide en "bits." ¿Por qué negativo? Porque el logaritmo de cualquier número en $(0, 1]$ es no positivo ($\log_2(0.5) = -1$, $\log_2(1) = 0$), así que la negación asegura que la información siempre sea no negativa. ¿Por qué base 2? Porque conecta con la codificación binaria — un bit es la información obtenida de un lanzamiento de moneda justa. Podrías usar el logaritmo natural (midiendo en "nats") o $\log_{10}$ (midiendo en "hartleys"), pero los bits son la unidad más común en teoría de la información.

Ahora tracemos el comportamiento en los límites y extremos:

  • Cuando $P(x) = 1$ (evento seguro): $I(x) = -\log_2(1) = 0$ bits. Sin sorpresa alguna — ya sabías que iba a ocurrir. Ninguna información ganada.
  • Cuando $P(x) = 0.5$ (lanzamiento de moneda): $I(x) = -\log_2(0.5) = 1$ bit. Exactamente un bit de información — la unidad fundamental. Conocer el resultado de un lanzamiento de moneda justa te da precisamente un bit.
  • Cuando $P(x) = 0.01$ (evento raro): $I(x) = -\log_2(0.01) \approx 6.64$ bits. Muy informativo — un evento raro conlleva mucha sorpresa cuando realmente ocurre.
  • Cuando $P(x) \to 0$ (cada vez más imposible): $I(x) \to \infty$. El contenido de información crece sin límite. Un evento con probabilidad de uno en un billón lleva aproximadamente 40 bits de información.

La escala logarítmica es esencial. Si aprendes dos hechos independientes (como lanzar dos monedas independientes), la información total es la suma: $I(x_1) + I(x_2) = -\log P(x_1) - \log P(x_2) = -\log(P(x_1) P(x_2))$. El logaritmo convierte la multiplicación de probabilidades en suma de información — una propiedad profundamente útil.

import numpy as np
import json
import js

probs = [1.0, 0.5, 0.25, 0.1, 0.01, 0.001]

rows = []
for p in probs:
    info = -np.log2(p) + 0.0
    rows.append([str(p), f"{info:.2f} bits"])

js.window.py_table_data = json.dumps({
    "headers": ["P(x)", "Information I(x)"],
    "rows": rows
})

print("A fair coin flip carries exactly 1 bit of information.")
print(f"A fair 6-sided die roll carries log\u2082(6) \u2248 {np.log2(6):.2f} bits.")
print("A fair 6-sided die roll carries log₂(6) ≈ 2.58 bits.")
print(f"  log₂(6) = {np.log2(6):.2f}")

Entropía: La Sorpresa Promedio

La información nos dice la sorpresa de un solo evento. Pero una distribución de probabilidad describe muchos eventos posibles, cada uno con su propia probabilidad. ¿Cuánta sorpresa deberíamos esperar en promedio? Eso es la entropía — la información esperada a través de todos los eventos posibles:

$$H(P) = -\sum_{x} P(x) \log_2 P(x)$$

Cada pieza de esta fórmula tiene un rol específico:

$P(x)$ es la probabilidad del evento $x$ bajo la distribución $P$. Esto nos dice con qué frecuencia ocurre cada evento.

$-\log_2 P(x)$ es la información (sorpresa) del evento $x$ — la cantidad que definimos en la sección anterior. Los eventos raros tienen alta sorpresa, los eventos comunes tienen baja sorpresa.

$P(x) \times [-\log_2 P(x)]$ es la sorpresa del evento $x$, ponderada por la frecuencia con la que ocurre. Un evento muy sorprendente que casi nunca sucede contribuye poco al promedio. Un evento moderadamente sorprendente que sucede frecuentemente contribuye mucho. Esta ponderación es lo que hace de la entropía un promedio significativo — tiene en cuenta tanto cuán sorprendente es cada evento como con qué frecuencia realmente lo encuentras.

$\sum_x$ suma sobre todos los eventos posibles en la distribución. El resultado es el número promedio de bits necesarios para codificar un evento extraído aleatoriamente de $P$.

La entropía mide la incertidumbre promedio en una distribución. Alta entropía significa alta incertidumbre — la distribución está dispersa entre muchos resultados y no puedes predecir qué pasará. Baja entropía significa baja incertidumbre — la distribución está concentrada en unos pocos resultados y puedes predecir con confianza.

Comportamiento en los límites:

  • Entropía máxima: la distribución uniforme. Cuando todos los $K$ eventos son igualmente probables, $P(x) = 1/K$ para todo $x$, y $H = \log_2 K$ bits. Una moneda justa ($K = 2$) tiene $H = 1$ bit. Un dado justo de 6 caras ($K = 6$) tiene $H = \log_2(6) \approx 2.58$ bits. La distribución uniforme maximiza la entropía porque cada resultado es igualmente incierto — no tienes información que te ayude a predecir qué evento ocurrirá.
  • Entropía mínima: $H = 0$ bits. Esto ocurre cuando toda la probabilidad está concentrada en un solo evento ($P(x) = 1$ para un evento, $P(x) = 0$ para todos los demás). No hay incertidumbre en absoluto — siempre sabes exactamente qué pasará. Entropía cero significa cero sorpresa en promedio.

Una convención importante: definimos $0 \log_2 0 = 0$, porque $\lim_{p \to 0^+} p \log_2 p = 0$. Los eventos que nunca ocurren no contribuyen nada a la entropía. Esto hace que la fórmula esté bien definida incluso cuando algunas probabilidades son cero.

El siguiente gráfico muestra la entropía de una distribución binaria (como una moneda sesgada) conforme la probabilidad $p$ de cara varía de 0 a 1:

import numpy as np
import json
import js

p = np.linspace(0.001, 0.999, 200)
entropy = -(p * np.log2(p) + (1 - p) * np.log2(1 - p))

plot_data = [{
    "title": "Binary Entropy H(p)",
    "x_label": "p (probability of heads)",
    "y_label": "Entropy (bits)",
    "x_data": p.tolist(),
    "lines": [
        {"label": "H(p) = -p log₂(p) - (1-p) log₂(1-p)", "data": entropy.tolist(), "color": "#8b5cf6"}
    ]
}]
js.window.py_plot_data = json.dumps(plot_data)

La curva es simétrica y alcanza su máximo en $p = 0.5$ (máxima incertidumbre — una moneda justa). Cae a 0 en ambos extremos ($p = 0$ y $p = 1$, donde el resultado es seguro). Esta forma — más alta cuando menos sabes, más baja cuando más sabes — es la firma de la entropía.

Entropía Cruzada: Midiendo el Desajuste entre Distribuciones

La entropía mide la sorpresa promedio cuando extraes de una distribución y conoces la distribución verdadera. Pero ¿qué pasa si no conoces la distribución verdadera? ¿Qué pasa si la realidad sigue una distribución $P$, pero tú haces predicciones basándote en una distribución diferente $Q$? La sorpresa promedio que experimentarás es la entropía cruzada:

$$H(P, Q) = -\sum_{x} P(x) \log Q(x)$$

Analicemos cada componente:

$P(x)$ es la distribución verdadera — lo que realmente ocurre. Los eventos se extraen de $P$. En aprendizaje automático, esta es la verdad fundamental: la distribución real de los datos o las etiquetas codificadas en one-hot.

$Q(x)$ es la distribución predicha — lo que el modelo cree que ocurrirá. Esta es la salida del modelo, típicamente las probabilidades softmax sobre las clases.

$-\log Q(x)$ es cuánto se sorprende el modelo $Q$ cuando ocurre el evento $x$. Si $Q$ asigna alta probabilidad a $x$, la sorpresa es baja. Si $Q$ asigna baja probabilidad a $x$, la sorpresa es alta. Este es el contenido de información bajo las creencias del modelo.

La suma pondera cada sorpresa por la frecuencia con que $x$ realmente ocurre (bajo $P$). La entropía cruzada responde: "si la realidad sigue $P$ pero yo uso $Q$ para hacer predicciones, ¿cuánto me sorprenderé en promedio?"

Propiedad clave: $H(P, Q) \geq H(P)$, siempre. La entropía cruzada es al menos tan grande como la entropía verdadera. Esto tiene sentido intuitivo: usar la distribución equivocada solo puede aumentar tu sorpresa promedio, nunca disminuirla. La igualdad se cumple solo cuando $Q = P$ — la mejor predicción es la distribución verdadera misma.

La diferencia $H(P, Q) - H(P)$ es la divergencia KL (siguiente sección) — la "sorpresa extra" por usar $Q$ en lugar de $P$. Esta descomposición es fundamental: entropía cruzada = entropía + divergencia KL.

¡Esta es exactamente la pérdida de entropía cruzada del artículo 3! En clasificación, $P$ es la etiqueta verdadera en one-hot y $Q$ es la salida softmax. Como $P$ es one-hot (solo un $P(x) = 1$, el resto son 0), la suma $-\sum_x P(x) \log Q(x)$ se colapsa a $-\log Q(c)$ donde $c$ es la clase verdadera. Todos los términos cero desaparecen. La pérdida de entropía cruzada que hemos estado usando todo el tiempo es un caso especial de esta fórmula general.

💡 La conexión es profunda: minimizar la pérdida de entropía cruzada en clasificación es equivalente a la estimación de máxima verosimilitud, que es equivalente a minimizar la divergencia KL respecto a la distribución verdadera. Estos son tres nombres diferentes para el mismo objetivo de optimización, vistos desde diferentes ángulos matemáticos.

Divergencia KL: El Costo Extra de Estar Equivocado

La divergencia KL (divergencia de Kullback-Leibler) mide los bits extra de sorpresa en que se incurre al usar la distribución $Q$ cuando la distribución verdadera es $P$. Tiene dos formas equivalentes:

$$D_{\text{KL}}(P \| Q) = \sum_{x} P(x) \log \frac{P(x)}{Q(x)} = H(P, Q) - H(P)$$

Desglosemos cada componente de esta fórmula:

$P(x) \log \frac{P(x)}{Q(x)}$ : para cada evento $x$, ¿cuánto más sorprendente es la predicción de $Q$ que la realidad? La razón $P(x)/Q(x)$ mide la discrepancia entre las dos distribuciones en el evento $x$. Si $Q(x) = P(x)$, la razón es 1 y $\log 1 = 0$ — sin sorpresa extra. Si $Q(x) < P(x)$ (el modelo subestima la probabilidad), la razón excede 1 y el logaritmo es positivo — sorpresa extra. Si $Q(x) > P(x)$ (el modelo sobreestima), la razón es menor que 1 y el logaritmo es negativo — pero esto está ponderado por $P(x)$, así que los eventos raros sobreestimados contribuyen poco.

$H(P, Q) - H(P)$ : la forma equivalente. Entropía cruzada menos entropía es igual a los bits extra de sorpresa causados por usar $Q$ en lugar de $P$. Esta descomposición es elegante: $H(P)$ es la sorpresa mínima irreducible (la entropía de la realidad), y $D_{\text{KL}}(P \| Q)$ es la penalización adicional por tener el modelo equivocado.

$D_{\text{KL}} \geq 0$ siempre (esto se conoce como la desigualdad de Gibbs). La divergencia KL es cero si y solo si $P = Q$ en todas partes. No puedes hacerlo mejor que la distribución verdadera — cualquier desviación añade sorpresa extra.

NO es simétrica: $D_{\text{KL}}(P \| Q) \neq D_{\text{KL}}(Q \| P)$ en general. La divergencia KL no es una métrica de distancia verdadera. Esta asimetría no es una inconveniencia matemática — codifica algo significativo.

Por qué importa la asimetría: $D_{\text{KL}}(P \| Q)$ penaliza casos donde $P(x) > 0$ pero $Q(x) \approx 0$ — el modelo asigna probabilidad cercana a cero a algo que realmente ocurre. Esto es catastrófico: el modelo está diciendo "esto es esencialmente imposible" sobre algo que ocurre en la realidad, produciendo una sorpresa $-\log Q(x) \to \infty$. Pero no penaliza $Q(x) > 0$ cuando $P(x) = 0$ — el modelo desperdicia probabilidad en eventos imposibles, lo cual es un desperdicio pero no catastrófico (esos términos desaparecen porque se multiplican por $P(x) = 0$). Esta asimetría es por lo que la dirección importa: en el entrenamiento, típicamente minimizamos $D_{\text{KL}}(P_{\text{verdadera}} \| Q_{\text{modelo}})$, lo que obliga al modelo a cubrir todos los eventos que realmente ocurren.

import numpy as np

def kl_divergence(p, q):
    """D_KL(P || Q)"""
    # Filter out zero entries in P (0 * log(0/q) = 0)
    mask = p > 0
    return np.sum(p[mask] * np.log2(p[mask] / q[mask]))

def cross_entropy(p, q):
    mask = p > 0
    return -np.sum(p[mask] * np.log2(q[mask]))

def entropy(p):
    mask = p > 0
    return -np.sum(p[mask] * np.log2(p[mask]))

# True distribution: 70% cat, 20% dog, 10% bird
P = np.array([0.7, 0.2, 0.1])
labels = ["cat", "dog", "bird"]

# Good model prediction
Q_good = np.array([0.6, 0.3, 0.1])

# Bad model prediction (thinks bird is most likely)
Q_bad = np.array([0.1, 0.1, 0.8])

print(f"True distribution P:  {dict(zip(labels, P))}")
print()

for name, Q in [("Good model", Q_good), ("Bad model", Q_bad)]:
    H_P = entropy(P)
    H_PQ = cross_entropy(P, Q)
    KL = kl_divergence(P, Q)
    print(f"{name} Q: {dict(zip(labels, Q))}")
    print(f"  Entropy H(P):        {H_P:.4f} bits  (irreducible uncertainty)")
    print(f"  Cross-entropy H(P,Q): {H_PQ:.4f} bits  (total surprise)")
    print(f"  KL divergence:        {KL:.4f} bits  (extra surprise from using Q)")
    print(f"  Check: H(P,Q) - H(P) = {H_PQ - H_P:.4f} = KL ✓")
    print()

# Show asymmetry
print("Asymmetry of KL divergence:")
print(f"  D_KL(P || Q_good) = {kl_divergence(P, Q_good):.4f}")
print(f"  D_KL(Q_good || P) = {kl_divergence(Q_good, P):.4f}")
print(f"  They're different! KL is NOT symmetric.")

La Divergencia KL en el Aprendizaje Profundo

La divergencia KL no es solo una curiosidad teórica — aparece como un término explícito en las funciones de pérdida y los procedimientos de entrenamiento de varios paradigmas importantes del aprendizaje profundo. Entender dónde y por qué aparece te ayudará a leer artículos modernos de ML con confianza.

  • Destilación de conocimiento: la red estudiante minimiza $D_{\text{KL}}(P_{\text{profesor}} \| P_{\text{estudiante}})$ — igualando las predicciones suaves del profesor. El softmax con temperatura del artículo 2 crea distribuciones del profesor más suaves que son más fáciles de igualar, porque las probabilidades suavizadas revelan similitudes entre clases ("este 7 se parece un poco a un 1") que las etiquetas duras descartan.
  • Autoencoders variacionales (VAEs): la pérdida incluye $D_{\text{KL}}(q(z|x) \| p(z))$, que empuja la distribución latente aprendida por el codificador $q(z|x)$ hacia un prior normal estándar $p(z) = \mathcal{N}(0, I)$. Este término KL es lo que hace el espacio latente suave e interpolable — sin él, el codificador podría mapear las entradas a puntos dispersos sin estructura, haciendo la generación imposible.
  • RLHF / DPO: una penalización KL $D_{\text{KL}}(\pi_\theta \| \pi_{\text{ref}})$ evita que la política ajustada $\pi_\theta$ se desvíe demasiado del modelo de referencia $\pi_{\text{ref}}$. Sin esta restricción, el modelo puede sobreajustarse a la señal de recompensa y producir salidas degeneradas — explotando la función de recompensa de maneras que producen alta recompensa pero texto de baja calidad. El término KL actúa como una correa, manteniendo al modelo cerca de su punto de partida bien comportado. (Cubierto en detalle en el track de RLHF.)
  • Cuello de botella de información: el principio de comprimir representaciones mientras se preserva la información relevante para la tarea se formaliza como minimizar la información mutua (que involucra términos KL). La idea es encontrar la representación más compacta $Z$ de la entrada $X$ que aún prediga bien la etiqueta $Y$. El compromiso entre compresión y predicción está gobernado por divergencias KL entre las distribuciones conjuntas y marginales.

En todos los casos, la divergencia KL cumple el mismo rol conceptual: mide cuán lejos está una distribución de otra y proporciona una penalización diferenciable que el optimizador puede empujar hacia cero. Las distribuciones específicas difieren (salidas softmax, codificaciones latentes, distribuciones de política), pero la maquinaria matemática es idéntica.

Conectando Todo

Las cuatro cantidades que hemos cubierto forman una jerarquía limpia, cada una construyendo sobre la anterior:

$$\text{Información} \xrightarrow{\text{promedio}} \text{Entropía} \xrightarrow{\text{desajuste}} \text{Entropía Cruzada} \xrightarrow{\text{menos entropía}} \text{Divergencia KL}$$
  • Información: sorpresa de un solo evento. $I(x) = -\log_2 P(x)$.
  • Entropía: sorpresa promedio a través de todos los eventos. $H(P) = -\sum_x P(x) \log_2 P(x)$.
  • Entropía cruzada: sorpresa promedio cuando usas la distribución equivocada. $H(P, Q) = -\sum_x P(x) \log Q(x)$.
  • Divergencia KL: la sorpresa extra causada por la distribución equivocada. $D_{\text{KL}}(P \| Q) = H(P, Q) - H(P)$.

Y ahora la conexión crucial con las funciones de pérdida: minimizar la entropía cruzada $H(P, Q)$ respecto a $Q$ es equivalente a minimizar la divergencia KL $D_{\text{KL}}(P \| Q)$. ¿Por qué? Porque $H(P, Q) = D_{\text{KL}}(P \| Q) + H(P)$, y $H(P)$ es una constante — la distribución de datos no cambia durante el entrenamiento. Tomar el gradiente de $H(P, Q)$ respecto a los parámetros del modelo da el mismo gradiente que tomar el gradiente de $D_{\text{KL}}(P \| Q)$. La constante $H(P)$ desaparece.

Por eso "pérdida de entropía cruzada" y "minimizar la divergencia KL" se usan indistintamente en la práctica. Producen gradientes idénticos y modelos entrenados idénticos. La única diferencia es un desplazamiento constante en el valor de la pérdida — y como nos importa la dirección de la optimización (los gradientes), no el número absoluto de la pérdida, la distinción es irrelevante para el entrenamiento.

Cada vez que ves una pérdida de entropía cruzada en un bucle de entrenamiento, estás implícitamente minimizando la divergencia KL entre la distribución verdadera de los datos y la distribución aprendida del modelo. Cada vez que ves una penalización KL en un VAE o un objetivo de RLHF, estás usando la misma maquinaria matemática. La teoría de la información proporciona el lenguaje unificador.

Quiz

Pon a prueba tu comprensión de la teoría de la información, la entropía y la divergencia KL.

¿Por qué un evento raro conlleva más información que uno común?

¿Qué significa la entropía máxima para una distribución de probabilidad?

¿Por qué la divergencia KL no es una métrica de distancia verdadera?

¿Por qué minimizar la entropía cruzada H(P,Q) es equivalente a minimizar la divergencia KL D_KL(P||Q) durante el entrenamiento?