Saltar al contenido

# procesos-estocasticos-discretos-simulacion-estados-y-tiempos-de-absorcion-con-pydtmc

Procesos Estocásticos Discretos: Simulación, Estados y Tiempos de Absorción con PyDTMC

Volver a la portada del curso
Notebook

Ejercicio de Simulación con PyDTMC

Sección 2 · Simulación de Cadenas de Markov

Ejercicio de simulación con PyDTMC

En este notebook construyes tu primera cadena de Markov con PyDTMC, la simulas, la pronosticas y compruebas que la simulación y el cálculo exacto coinciden. El ejemplo es un modelo de clima con tres estados: Soleado, Nublado y Lluvioso. Descarga el notebook adjunto a esta lección y ejecútalo celda por celda.

Antes de empezar

Instala la biblioteca con pip install pydtmc. Este material se probó con PyDTMC 9.0, NumPy 2.4 y Matplotlib 3.10. No necesitas descargar datos: todo se genera con semillas fijas, así que tus números deben coincidir con los del notebook.

Paso 1: crear la cadena

Una MarkovChain recibe la matriz de transición y, opcionalmente, los nombres de los estados. Al imprimirla obtienes un resumen de sus propiedades:

from pydtmc import MarkovChain

P = [[0.9, 0.1, 0.0],
     [0.3, 0.5, 0.2],
     [0.0, 0.4, 0.6]]
clima = MarkovChain(P, ["Soleado", "Nublado", "Lluvioso"])
print(clima)
print(clima.is_ergodic, clima.period)

Esta cadena es ergódica: desde cualquier estado se llega a cualquier otro y no hay ciclos forzados (periodo 1). Si una fila no suma 1, el constructor lanza un ValidationError; es tu primera red de seguridad.

Paso 2: simular trayectorias

simulate(steps, initial_state, seed) genera una trayectoria. Ojo: devuelve steps + 1 estados, porque incluye el estado inicial. Con next obtienes un solo paso.

ruta = clima.simulate(10, initial_state="Soleado", seed=42)
print(len(ruta))
print(ruta)
print(clima.next("Lluvioso", seed=3))

La semilla hace que el experimento sea reproducible. Sin ella, cada ejecución da una trayectoria distinta, que es lo correcto en producción pero confuso al aprender.

Paso 3: pronosticar con redistribute

La simulación responde "qué podría pasar"; la redistribución responde "con qué probabilidad". redistribute(n, initial_status) calcula $\pi_0 P^n$ sin que tengas que escribir la potencia de la matriz:

for n in (1, 3, 10, 30):
    print(n, clima.redistribute(n, initial_status="Lluvioso").round(3))
print("estacionaria:", clima.pi[0].round(3))

Aunque empieces en Lluvioso, después de unos 30 pasos la distribución ya no recuerda el punto de partida y se acerca a la distribución estacionaria $\pi$, que cumple $\pi = \pi P$. Para este clima, $\pi \approx (0.667, 0.222, 0.111)$. Observa que pi es una lista de vectores: una cadena con varias clases recurrentes tiene varias distribuciones estacionarias.

Paso 4: frecuencias simuladas contra $\pi$

La ley de los grandes números para cadenas ergódicas dice que la fracción de tiempo que una trayectoria larga pasa en cada estado converge a $\pi$. Lo verificas así:

import numpy as np

larga = clima.simulate(20000, initial_state="Soleado", seed=7)
valores, conteos = np.unique(larga, return_counts=True)
print(dict(zip(valores, (conteos / conteos.sum()).round(3))))
print(clima.mean_recurrence_times())

Los tiempos medios de recurrencia son $1/\pi_i$: si llueve el 11% de los días, en promedio pasan 9 días entre un día lluvioso y el siguiente.

Paso 5: recuperar la matriz desde datos

En la práctica no conoces $P$; tienes una secuencia observada. MarkovChain.fit_sequence("mle", estados, secuencia) estima cada $p_{ij}$ como el conteo de transiciones $i \to j$ dividido entre las salidas de $i$. Con 20,000 pasos la estimación queda a menos de 0.01 de la matriz real. El notebook también grafica la trayectoria con plot_sequence y la evolución de la distribución con plot_redistributions.

Trampas comunes

  • simulate(10) devuelve 11 estados, no 10.
  • pi devuelve una lista; usa clima.pi[0] cuando la cadena es ergódica.
  • plot_graph solo acepta ciertos valores de dpi (75, 100, 150, 200, 250, 300 o 600).
  • Una trayectoria corta da estimaciones ruidosas: con 50 pasos, un estado poco frecuente puede no aparecer nunca.

Cierre

Termina el notebook cambiando una sola probabilidad (por ejemplo, que Lluvioso siga a Lluvioso con 0.8) y observa cómo se mueven $\pi$ y los tiempos de recurrencia. Ese ejercicio de sensibilidad es la base del análisis de escenarios que harás en el proyecto.

Recursos