<jupyter_start><jupyter_text>Random Walk (Caminata aleatoria) > Una caminata aleatoria es una secuencia de pasos o movimientos que se escogen aleatoriamente dentro de un cierto espacio Ejemplo: Caminata 1DConsidere por ejemplo el espacio de los enteros en una dimensión- Digamos que inicialmente estamos en la posición $0$- En cada paso lanzamos una moneda- Si sale cara nos movemos a la derecha $+1$, si sale sello nos movemos a la izquierda $-1$- ¿Dónde estoy luego de lanzar $r$ veces la moneda?Podemos definir la posición luego de lanzar $i+1$ veces la moneda como$$p_{i+1} = p_{i} + 2 \cdot m -1$$donde $m \in \{0, 1\}$ es una variable aleatoria que se distribuye Bernoulli$$m \sim \text{Bernoulli}(0.5)$$y estamos asumiendo una moneda "justa", es decir con probabilidad $0.5$> Esta distribución define las "transiciones" o pasos de mi caminataMás adelante veremos como responder una pregunta como la planteada usando una simulación de Monte Carlo  Aplicaciones de las caminatas aleatoriasLa caminata aleatoria es un modelo ampliamente usado con aplicaciones en ecología, física, economía, entre otrosAlgunos ejemplos- [Comportamiento de un animal](https://core.ac.uk/download/pdf/36054338.pdf)- [Movimientos realizados por las particulas de un gas](https://en.wikipedia.org/wiki/Brownian_motion)- [La deriva genética](https://es.wikipedia.org/wiki/Deriva_gen%C3%A9tica)- El precio de las acciones de una firmaEn la actividad veremos como podemos usarlo en el contexto económicoLa clave está en el modelamiento de la **probabilidad de transición o paso**  Proceso estocástico y propiedad de MarkovUna caminata aleatoria es un tipo particular de **proceso estocástico**. Llamamos proceso estocástico a una colección de variables aleatorias ordenadas como una secuenciaPor ejemplo$$\{X(t): t \in \mathbb{R}^+\}$$es una secuencia de variables aleatorias indexadas en el tiempo o$$\{X_n: n \in \mathbb{Z}\}$$es una secuencia de variables aleatorias con un índice discretoUna caminata aleatoria es además un caso particular de **proceso Markoviano**La propiedad de Markov dice que el lugar donde estaré en el futuro sólo depende de donde estoy en el presente. No hay dependencia del pasado. Esto se resume matematicamente como:$$P(X_{t+1}|X_{t}, X_{t-1}, \ldots, X_{1}) = P(X_{t+1}|X_{t})$$  Ejemplo: Caminata 2DSea un espacio discreto en dos dimensiones y un personaje que parte en la posición $(0, 0)$El personaje puede moverse hacia el Norte, Sur, Este o OesteLa probabilidad de escoger cada una de estas direcciones es $1/4$En promedio ¿A qué distancia del centro estará el personaje luego de $10$, $100$ y $1000$ pasos?Respondamos esta pregunta usando una simulación de Monte Carlo<jupyter_code>fig, ax = plt.subplots(figsize=(4, 4), tight_layout=True)

def caminata(r, plot_steps=False):
    probs = np.array([1/4, 1/4, 1/4, 1/4])
    movimientos = np.array([[0, 1], [1, 0], [-1, 0], [0, -1]])
    posicion = np.zeros(shape=(r+1, 2))   
    for i in range(1, r+1):
        decision = np.random.choice(len(probs), p=probs)
        posicion[i] = posicion[i-1] + movimientos[decision, :]
        if plot_steps:
            ax.cla()
            ax.plot(posicion[:i+1, 0], posicion[:i+1, 1])
            ax.scatter(posicion[i, 0], posicion[i, 1])
            ax.set_title(str(i))
            fig.canvas.draw() 
            plt.pause(0.01) 

    return posicion

pos = caminata(100, plot_steps=True)
fig, ax = plt.subplots(figsize=(4, 4), tight_layout=True)

def distancia(posicion):
    return np.sum(np.absolute(posicion[-1, :]))

for i in range(10):
    borrachin = caminata(1000)
    print(i, distancia(borrachin))
    ax.plot(borrachin[:, 0], borrachin[:, 1], alpha=0.5)
Ns = np.logspace(0, 4, 10)
stats = np.zeros(shape=(len(Ns), 4))

n_pasos = 1000
for k, N in enumerate(Ns):
    N = int(N)
    distancias = np.zeros(shape=(N,))
    for i in range(N):
        borrachin = caminata(n_pasos)
        distancias[i] = distancia(borrachin)
    #print(f"{N} {np.mean(distancias):0.4f} {np.std(distancias):0.4f}")     
    stats[k, 0] = np.mean(distancias)
    stats[k, 1] = np.std(distancias)
    stats[k, 2] = np.amax(distancias)
    stats[k, 3] = np.amin(distancias)
    
fig, ax = plt.subplots(figsize=(6, 4), tight_layout=True)    
ax.plot(Ns, stats[:, 0])
ax.fill_between(Ns, stats[:, 0]-stats[:, 1], stats[:, 0]+stats[:, 1], alpha=0.5)
ax.plot(Ns, stats[:, 2], 'k--')
ax.plot(Ns, stats[:, 3], 'k--')
ax.axhline(np.sqrt(n_pasos), c='r', ls='--', alpha=0.5)
ax.set_title(str(n_pasos))
ax.set_xscale('log')<jupyter_output><empty_output><jupyter_text>Jugando a la ruleta (la casa siempre gana) Sea un casino con una ruleta con 36 casilleros numéricados del 1 al 36Una persona llega con $10.000$ pesos al casino y comienza a jugar ruleta. Su estrategia de juego es siempre apostarle $1.000$ pesos al número $13$. En promedio ¿Cuánto podría ganar esta persona con su particular estrategia?Usemos una simulación de Monte Carlo para resolverlo<jupyter_code>import random

class Ruleta():
    def __init__(self):
        self.casilleros = []
        for i in range(1, 37):
            self.casilleros.append(i)
        self.pelota = None
        self.retornos = len(self.casilleros) - 1
        #self.casilleros.append('0')
        #self.casilleros.append('00')
        
    def girar(self):
        self.pelota = random.choice(self.casilleros)
        
    def apostar(self, casillero, cantidad):
        if str(casillero) == str(self.pelota):
            return cantidad*self.retornos
        else:
            return -cantidad
casino_dreams = Ruleta()  
sims = []
giros = 100
for k in range(10): # Simulaciones
    dinero = np.zeros(shape=(giros+1,))
    dinero[0] = 10_000    
    for i in range(1, giros+1):
        casino_dreams.girar()
        dinero[i] = dinero[i-1] + casino_dreams.apostar(13, 1_000)
    sims.append(dinero)
    
sims = np.vstack(sims)
fig, ax = plt.subplots(figsize=(6, 3), tight_layout=True)
for dinero in sims:
    ax.plot(dinero - 10_000)
ax.plot(np.mean(sims - 10_000  , axis=0), 'k--', lw=2, alpha=0.5)    
ax.axhline(0, c='r', ls='--', alpha=0.5, lw=2)
ax.set_ylabel('Ganancia')<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup