• Saltar al contenido principal
  • Skip to secondary menu
  • Saltar a la barra lateral principal
  • Saltar al pie de página
  • Inicio
  • Secciones
    • Ciencia de datos
    • Criptografía
    • Herramientas
    • Machine Learning
    • Noticias
    • Opinión
    • Productividad
    • Programación
      • JavaScript
      • Julia
      • Matlab
      • Python
      • R
  • Programación
    • JavaScript
    • Julia
    • Matlab
    • Python
    • R
  • Laboratorio
    • Estadística
      • Calculadora del Tamaño Muestral en Encuestas
      • Calculadora de estadísticos descriptivos
      • Test de normalidad
      • Calculadora de contrastes de hipotesis
      • Calculadora de tamano del efecto
      • Simulador de Regresión Lineal con Ruido
      • Visualizador de PCA
      • Visualizador de Series Temporales
      • Simulador de Regresión Logística
      • Simulador de K-Means
      • Simulador de DBSCAN
      • Detector de la Ley de Benford
    • Probabilidad
      • Calculadora de Probabilidad de Distribuciones
      • Calculadora de Probabilidades de Lotería
      • Simulador del Problema de Monty Hall
      • Simulador de la Estrategia Martingala
    • Finanzas
      • Calculadora de Préstamos e Hipotecas
      • Conversor TIN ↔ TAE
      • Calculadora DCA con ajuste por inflación
      • Calculadora XIRR con Flujos Irregulares
      • Simulador FIRE (Financial Independence, Retire Early)
    • Riesgo
      • Constructor de Scorecards de Crédito
      • Aplicar Scorecard de Crédito
    • Herramientas
      • Formateador / Minificador de JSON
      • Conversor CSV ↔ JSON
      • Comparador y Formateador de Texto y JSON
      • Formateador y Tester de Expresiones Regulares
      • Inspector de JWT
      • Generador y verificador de hashes
      • Codificador / Decodificador Base64 y URL
      • Conversor de bases numericas
      • Conversor de Timestamp Unix
      • Conversor de colores
      • Generador de UUIDs
    • Juegos
      • Tres en Raya
      • Nim con Q-Learning
    • Más
      • Método D’Hondt
      • Generador de Contraseñas Seguras
  • Noticias
  • Boletín
  • Contacto
  • Tienda
    • Libros
    • Equipamiento de oficina
    • Equipamiento en movilidad

Analytics Lane

Ciencia e ingeniería de datos aplicada

  • Ciencia de datos
  • Machine Learning
  • IA Generativa
  • Python
  • Pandas
  • NumPy
  • R
  • Excel

Valores iniciales optimistas para un problema Bandido Multibrazo (Multi-Armed Bandit)

marzo 12, 2021 Por Daniel Rodríguez Deja un comentario
Tiempo de lectura: 8 minutos

En entradas anteriores hemos aprendido a abordar el problema del Bandido Multibrazo utilizando para ello la estrategia llamada Epsilon-Greedy. Estrategia con la que se obtienen mejores resultados que los de un test A/B. Aunque Epsilon-Greedy tiene un problema cuando el número de episodios a jugar es elevado, continúa explorando los peores bandidos con una probabilidad fija épsilon. Para solucionar esto, la semana pasada, introdujimos la opción de que este parámetro se reduzca con el tiempo. Comprobando que así se obtienen mejores resultados a largo plazo. Ya que una vez se ha identificado al bandido que ofrece la mayor recompensa promedio el agente estará más tiempo explotando este, en lugar de explorar el resto de los bandidos. Pero aún así es posible reducir la fase de exploración si se cuenta con una estimación optimista de la recompensa de cada bandido. Una estrategia a la que se conoce como valores iniciales optimistas y vamos a ver a continuación cómo implementarla en Python.

Tabla de contenidos

  • 1 Valores iniciales optimistas para un problema Bandido Multibrazo
  • 2 ¿Por qué tienen que ser optimistas los valores iniciales?
  • 3 Problemas con valores iniciales optimistas
  • 4 Implementación en Python
  • 5 Evaluación de los resultados y comparación con Epsilon-Greedy
  • 6 Resultados cuando los valores iniciales no son óptimos
  • 7 Conclusiones

Valores iniciales optimistas para un problema Bandido Multibrazo

Supongamos que al comenzar disponemos de una estimación de cuál es la recompensa promedio que nos puede ofrecer cada uno de los bandidos. Entonces se puede usar este punto de partida para seleccionar el bandido mediante una estrategia puramente avariciosa, esto es, con épsilon igual a cero. Así, si la estimación es correcta siempre se explotará el mejor bandido, obteniendo de este modo la mayor recompensa posible. Solamente se ha jugado con el mejor bandido. Por otro lado, si no es así, al actualizar el valor esperado de la recompensa con los datos reales se podrá comparar esta estimación con las iniciales. En caso de que la estimación para otro bandido sea mejor, se pasará a jugar con este. Así hasta que se pase a jugar siempre con el bandido que ofrece las mayores recompensas.

Nuevo conversor de timestamp Unix en el laboratorio de Analytics Lane
En Analytics Lane
Nuevo conversor de timestamp Unix en el laboratorio de Analytics Lane

¿Por qué tienen que ser optimistas los valores iniciales?

La estrategia se llama valores iniciales óptimas y esto es así porque los valores tienen que ser realmente optimistas para que esta pueda funcionar de forma correcta. Para esto nos podemos fijar en un ejemplo. Supongamos que tenemos dos bandidos con una recompensa promedio de 1 y 2 respectivamente. Así, si fijamos unos valores iniciales de 3 y 2 el agente jugará inicialmente con el primero de los bandidos, al que se le ha asignado una recompensa promedio de 3. Siendo esto así hasta que se compruebe que la recompensa real del primero es inferior a 2, el valor que se le ha asignado al segundo bandido. Por lo que el agente para a explotar únicamente el segundo de los bandidos, ya que su recompensa esperada es 2.

Por otro lado, si los valores iniciales no son optimistas el agente puede explotar un bandido que no sea óptimo. Algo que se puede comprobar si se asigna valores iniciales de 0,5 y 0,2. En este caso el agente jugará solamente con el primero ya que la recompensa esperada es 1 y esta es mayor que 0,2, la asignada al segundo. Por lo que la solución obtenida no será la óptima.

Publicidad


Problemas con valores iniciales optimistas

A la hora de aplicar esta estrategia hay que tener en cuenta que es posible que es posible que esta estrategia no obtenga un resultado óptimo. Algo que se produce porque el agente no explora en ningún momento otras opciones.

Como se ha visto una posible causa sería no seleccionar correctamente los valores iniciales. Lo que llevaría al agente a seleccionar una solución que no es óptima. Por otro lado, también se puede dar este problema si la recompensa promedio de dos bandidos es muy parecida. En este caso, si en algún momento, debido al carácter aleatorio de las recompensas, la recompensa estimada para un bandido es inferior a la real y existe otro bandido con una mejor, es posible que se seleccione el segundo y no se vuelva al primero en ningún momento. Por lo que la solución final no será la óptima.

Un problema similar también se puede dar con Epsilon-Greedy, aunque en este caso, al explorar siempre las recompensas de todos los bandidos, el problema suele ser puntual. Esto es, solo hasta que se comprueba que la solución no es la óptima.

Implementación en Python

Para implementar esta estrategia se puede usar la clase Epsilon que se implementó la estrategia de Epsilon-Greedy con decaimiento. Para lo que solamente se tiene que hacer unos ligeros cambios.

En primer lugar, se debe aceptar un nuevo parámetro, al que llamaremos initial, al que se le debe indicar el valor inicial para para cada uno de los bandidos. Valor que se asigna a la propiedad _mean en los casos que esta se indique.

Cuando se asigna un valor inicial es importante asignar a la propiedad _plays, el número de jugadas para cada agente, el valor 1 en lugar de 0. Esto es así porque en caso contrario al actualizar el valor esperado se ignorará el valor. Algo que no es bueno. Debido a que, en el caso de que se ignore el valor inicial al calcular las primeras medidas, el peso de la primera tirada será clave, ya que esta pasará a ser la media empleada para seleccionar el bandido con solo una observación. Lo que hará que el resultado dependa en gran medida del azar.

Por otro lado, para que no se seleccione nunca al azar el bandido es necesario que el valor de la propiedad _epsilon sea cero. Lo que hará que la estrategia sea puramente avariciosa.

Así la clase Epsilon puede quedar de la siguiente forma:

import numpy as np
import matplotlib.pyplot as plt

class Epsilon:
    """
    Agente que soluciona el problema del el Bandido Multibrazo
    (Multi-Armed Bandit) mediante el uso de una estrategia Epsilon
    Greedy
    
    Parámetros
    ----------
    bandits : array of Bandit
        Vector con los bandidos con los que se debe jugar
    epsilon : float
        Porcentaje de veces en las que el agente jugada de forma
        aleatoria
    decay : float
        Velocidad con la que decae la probabilidad de seleccionar una
        jugada al azar
    initial: array of float
        Valor inicial de la recompensa esperada para cada uno de
        bandidos
    Métodos
    -------
    run :
        Realiza una tirada en el bandido
    average_reward :
        Obtención de la recompensa promedio
    plot :
        Representación gráfica del histórico de jugadas
    reset :
        Reinicia el agente
    """
    
    def __init__(self, bandits, epsilon=0.05, decay=1, initial=None):
        self.bandits = bandits
        self.epsilon = epsilon
        self.decay = decay
        
        self.reset(initial)
        
        
    def run(self, episodes=1):
        for i in range(episodes):
            prob = np.random.random()
            
            # Selección entre la jugada aleatoria o avariciosa
            if prob < self._epsilon:
                bandit = np.random.choice(len(bandits))
            else:
                max_bandits = np.where(self._mean == np.max(self._mean))[0]
                bandit = np.random.choice(max_bandits)

            # Decaimiento del parámetro epsilon
            self._epsilon *= self.decay
            
            # Obtención de una nueva recompensa
            reward = bandits[bandit].pull()
            
            # Agregación de la recompensa al listado
            self._rewards.append(reward)
            
            # Actualización de la media
            self._plays[bandit] += 1
            self._mean[bandit] = (1 - 1.0/self._plays[bandit]) * self._mean[bandit] \
                                 + 1.0/self._plays[bandit] * reward
        
        return self.average_reward()
    
    
    def average_reward(self):
        return np.mean(self._rewards)
    
    
    def plot(self, log=False, reference=False, label=None):
        cumulative_average = np.cumsum(self._rewards) / (np.arange(len(self._rewards)) + 1)
        
        if label is None:
            plt.plot(range(len(self._rewards)), cumulative_average)
        else:
            plt.plot(range(len(self._rewards)), cumulative_average, label=label)
            
        if reference:
            for reward in [b.reward for b in self.bandits]:
                plt.plot([0, len(self._rewards)], [reward, reward],
                         label=f'reward={reward}')
                
        if log:
            plt.xscale('log')
    
    
    def reset(self, initial=None):
        self._rewards = []
        
        if initial is None:
            self._epsilon = self.epsilon
            self._plays = [0] * len(self.bandits)
            self._mean = [0] * len(self.bandits)
        else:
            self._epsilon = 0
            self._plays = [1] * len(self.bandits)
            self._mean = initial

Evaluación de los resultados y comparación con Epsilon-Greedy

Ahora, con la nueva clase, para crear un agente que emplee valores iniciales optimistas solamente hay que asignar estos valores. De este modo se puede comparar el rendimiento de las tres estrategias vistas hasta ahora para 20.000 tiradas con el siguiente código.

class Bandit:
    """
    Implementación de un Bandido Multibrazo (Multi-Armed Bandit) basado
    en una distribución binomial

    Parámetros
    ----------
    number: integer
        Número de recompensas que puede devolver el agente
    probability : float
        Probabilidad de que el objeto devuelva una recompensa
    
    Métodos
    -------
    pull :
        Realiza una tirada en el bandido
        
    """
    def __init__(self, probability, number=1):
        self.number = number
        self.probability = probability
        
        self.reward = self.number * self.probability
        
        
    def pull(self):        
        return np.random.binomial(self.number, self.probability)
    
    
np.random.seed(0)

bandits = [Bandit(0.02), Bandit(0.06), Bandit(0.10)]

epsilon = Epsilon(bandits)
decay = Epsilon(bandits, epsilon=1, decay=0.999)
optimistic = Epsilon(bandits, initial=[0.2, 0.2, 0.2])

epsilon.run(20000)
decay.run(20000)
optimistic.run(20000)

epsilon.plot(True, label='Epsilon')
decay.plot(True, label='Decay')
optimistic.plot(True, True, label='Optimistic')
plt.legend()

Pudiéndose ver los resultados en la siguiente gráfica.

Comparación de la recompensa media obtenida en función del número de tiradas con Epsilon-Greedy con y decaimiento de épsilon y valores iniciales optimistas
Comparación de la recompensa media obtenida en función del número de tiradas con Epsilon-Greedy con y decaimiento de épsilon y valores iniciales optimistas

Aquí se puede observar como valores iniciales optimistas, bien configurado, es el método que se da observa antes cuál es el mejor bandido. Para comparar los algoritmos también nos podemos fijar en el número de veces que ha jugado cada uno con las soluciones que no son óptimas. En el caso de Epsilon-Greedy han sido 381 y 355 con el primero y segundo bandido. Valores que mejorar ligeramente con en el caso de Epsilon-Greedy con decaimiento, 333 y 352 para el primero y segundo. Finalmente, en el caso de valores iniciales optimistas solamente se han explorado los dos primeros bandidos en 90 y 16 casos respectivamente. Lo que supone más de 500 tiradas en las que se ha jugado con el mejor bandido.

Publicidad


Resultados cuando los valores iniciales no son óptimos

Aunque, en caso de que se configure mal no será así. Por ejemplo, en caso de fijar los valores iniciales a 0.09, es posible que el agente nunca seleccioné el tercer mejor bandido, como se puede ver en el siguiente ejemplo.

np.random.seed(0)
optimistic = Epsilon(bandits, initial=[0.09, 0.09, 0.09])
print(optimistic.run(20000))
optimistic.plot(True, True, label='Optimistic')
Recompensa media obtenida en función del número de tiradas con valores iniciales optimistas con valores que no son optimistas
Recompensa media obtenida en función del número de tiradas con valores iniciales optimistas con valores que no son optimistas

En este caso lo que se puede ver observar es que el agente ha jugado principalmente con el segundo bandido, ya que los valores iniciales han provocado que juegue poco con el tercero. Provocando que la estimación de la recompensa esperada no sea la correcta. En concreto solamente ha jugado seis veces con el último bandido, con lo que ha estimado que su recompensa promedio es 0,015, muy por debajo de la real y la del segundo bandido.

Conclusiones

En esta ocasión se ha visto la estrategia valores iniciales optimistas para un problema Bandido Multibrazo. Una estrategia que, si se configura correctamente, puede ofrecer mejores resultados que Epsilon-Greedy al reducir la fase de exploración. Aunque en su contra requiere disponer de un conocimiento previo de los bandidos que existe en muchos casos.

Imagen de Free-Photos en Pixabay

¿Te ha parecido de utilidad el contenido?

¡Puntúalo entre una y cinco estrellas!

Puntuación promedio 0 / 5. Votos emitidos: 0

Ya que has encontrado útil este contenido...

¡Síguenos en redes sociales!

¡Siento que este contenido no te haya sido útil!

¡Déjame mejorar este contenido!

Dime, ¿cómo puedo mejorar este contenido?

Publicaciones relacionadas

  • Nuevo conversor de timestamp Unix en el laboratorio de Analytics Lane
  • Lanzamiento de la versión 1.0 del laboratorio de Analytics Lane con nuevas herramientas de scoring
  • ¡Analytics Lane cumple ocho años!
  • Analytics Lane lanza una Calculadora de Rentabilidad con Flujos Irregulares basada en TIR (XIRR)
  • Analytics Lane lanza un Conversor CSV ↔ JSON para transformar datos en tiempo real
  • Analytics Lane lanza un nuevo Formateador y Tester de Expresiones Regulares para desarrolladores
  • Analytics Lane lanza su Visualizador de Series Temporales: entiende tendencia, estacionalidad y ruido de forma visual e interactiva
  • Analytics Lane lanza su Conversor de Bases Numéricas: entiende cómo trabajan los ordenadores a nivel de bits
  • Analytics Lane lanza su Conversor TIN ↔ TAE: la herramienta definitiva para entender el coste real de depósitos, préstamos e hipotecas

Publicado en: Ciencia de datos Etiquetado como: Aprendizaje por refuerzo, Machine learning, Multi-Armed Bandit

Interacciones con los lectores

Deja una respuesta Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

I accept the Terms and Conditions and the Privacy Policy

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Barra lateral principal

Suscríbete a nuestro boletín

Suscríbete al boletín semanal para estar al día de todas las publicaciones.

Política de Privacidad

Analytics Lane en redes sociales

  • Amazon
  • Bluesky
  • Facebook
  • GitHub
  • Instagram
  • Mastodon
  • Pinterest
  • RSS
  • Telegram
  • Tumblr
  • Twitter
  • YouTube

Publicidad

Entradas recientes

Noticias

Lanzamiento de la versión 1.0 del laboratorio de Analytics Lane con nuevas herramientas de scoring

mayo 2, 2026 Por Daniel Rodríguez

Analytics Lane

¡Analytics Lane cumple ocho años!

mayo 2, 2026 Por Daniel Rodríguez

Analytics Lane lanza una Calculadora de Rentabilidad con Flujos Irregulares basada en TIR (XIRR)

mayo 1, 2026 Por Daniel Rodríguez

Publicidad

Es tendencia

  • JSON en bases de datos: cuándo es buena idea y cuándo no publicado el febrero 24, 2026 | en Ciencia de datos
  • Cómo Interpretar las Métricas de Fondos de Inversión y ETFs: Guía Completa para Tomar Decisiones Informadas publicado el noviembre 25, 2025 | en Ciencia de datos
  • Web del proyecto HeidiSQL HeidiSQL: administrador de base de datos publicado el diciembre 20, 2019 | en Herramientas
  • Cómo ejecutar JavaScript desde Python: Guía práctica con js2py publicado el octubre 30, 2025 | en JavaScript, Python
  • Método del codo (Elbow method) para seleccionar el número óptimo de clústeres en K-means publicado el junio 9, 2023 | en Ciencia de datos

Publicidad

Lo mejor valorado

4.9 (24)

Seleccionar filas y columnas en Pandas con iloc y loc

4.6 (16)

Archivos JSON con Python: lectura y escritura

4.4 (14)

Ordenación de diccionarios en Python mediante clave o valor

4.7 (13)

Operaciones de filtrado de DataFrame con Pandas en base a los valores de las columnas

4.9 (11)

Pandas: Cambiar los tipos de datos en los DataFrames

Comentarios recientes

  • M. Pilar en Cómo eliminar las noticias en Windows 11 y recuperar tu concentración
  • Daniel Rodríguez en Probabilidad básica: cómo entender el azar en nuestra vida diaria
  • Pepe en Probabilidad básica: cómo entender el azar en nuestra vida diaria
  • CARLOS ARETURO BELLO CACERES en Justicio: La herramienta gratuita de IA para consultas legales
  • Piera en Ecuaciones multilínea en Markdown

Publicidad


Footer

Analytics Lane

  • Acerca de Analytics Lane
  • Boletín de noticias
  • Contacto
  • Libros
  • Lo más popular
  • Noticias
  • Tienda
  • Tiendas afiliadas

Secciones

  • Ciencia de datos
  • Criptografía
  • Herramientas
  • Machine Learning
  • Opinión
  • Productividad
  • Programación
  • Reseñas

Sobre de Analytics Lane

En Analytics Lane tratamos de explicar los principales conceptos de la ciencia e ingeniería de datos con un enfoque práctico. Los principales temas tratados son ciencia de datos, ingeniería de datos, inteligencia artificial, machine learning, deep learning y criptografía. Además, también se habla de los principales lenguajes de programación y herramientas utilizadas por los científicos e ingenieros de datos.

Copyright © 2018-2026 Analytics Lane ·Términos y condiciones ·Política de Cookies ·Política de Privacidad ·Herramientas de privacidad ·Contacto