• 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
      • Ajuste de Curvas
      • Calculadora de Matrices
    • 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)
    • Negocios
      • CLV
      • Scoring
    • 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

Test A/B para el Bandido Multibrazo (Multi-Armed Bandit)

febrero 19, 2021 Por Daniel Rodríguez Deja un comentario
Tiempo de lectura: 4 minutos

Recientemente hemos visto el problema del Bandido Multibrazo (Multi-Armed Bandit). Una de las posibles soluciones que tenemos en nuestra mano para resolver este problema es utilizar un Test A/B. Esto es, evaluar durante un periodo de tiempo todos los bandidos por igual y decidir una vez finalizado este periodo de prueba cuál es el óptimo. O, si los datos no son concluyentes, volver a realizar otra prueba con más muestras. Vamos a ver cómo simular la utilización de un Test A/B para el Bandido Multibrazo en Python.

Creación de un objeto para simular el bandido

En primer lugar, para llevar a cabo la simulación es necesario crear una clase que represente a cada uno de los bandidos. Clase en la que solamente es necesario crear un método para simular el resultado de una tirada. Para lo que se puede usar una función de distribución como puede ser la binomial. Siendo los parámetros de la función de distribución diferentes en cada uno bandidos. Así se puede crear la siguiente clase llamada Bandit.

En la que el constructor cuenta con una propiedad llamada mean que es la probabilidad de éxito para el bandido. Debido a que se ultima una distribución binomial con un único ensayo este valor coincidirá la recompensa media.

La caverna del consumo, o cómo Greenspan miraba calzoncillos para hacer política monetaria – El bestiario de los indicadores económicos absurdos (parte 1)
En Analytics Lane
La caverna del consumo, o cómo Greenspan miraba calzoncillos para hacer política monetaria – El bestiario de los indicadores económicos absurdos (parte 1)

Nótese que en el objeto también se guarda el histórico de recompensas, aunque esto es para facilitar el posterior análisis.

Comprobar cuál es el mejor bandido

Ahora deberíamos simular el comportamiento de dos o más bandidos durante un número de casos. Una vez obtenidos los resultados debemos comprobar cuál es el que ofrece la mayor recompensa promedio y comprobar que el resultado no es debido al azar, esto es, la diferencia entre las dos muestras es estadísticamente significativa. Para lo que se puede utilizar por ejemplo un test Z. Un test que podemos encontrar implementado en la función proportions_ztest de la librería Statsmodels de Python.

La función proportions_ztest requiere dos tuplas como parámetros de entrada. La primera debe contener el número de casos favorables y el segundo el número de observaciones. Como resultado se obtiene una tupla con el resultado del z-test y el p-valor de este. Indicando este último la posibilidad de rechazar la hipótesis nula, que en este caso es que los dos resultados provienen de la misma distribución.

Publicidad


Aplicación a múltiples bandidos

La función proportions_ztest solamente funciona con pares, por lo que si hay más de dos bandidos es necesario utilizar una estrategia para probar todas las combinaciones. Como lo que se quiere es identificar el mejor bandido de todos solamente hay que comprobar que los valores de este pasan el test con el resto de los bandidos. Si esto es así, se puede afirmar que el resultado no es debido al azar.

Implementación en Python

Con todo lo que hemos visto se puede realizar la siguiente implementación en Python.

import numpy as np
from itertools import compress
from statsmodels.stats.proportion import proportions_ztest 

np.random.seed(0)

class Bandit:
    def __init__(self, mean):
        self.mean = mean
        self.rewards = []
    
    def pull(self):
        reward = np.random.binomial(1, self.mean)
        self.rewards.append(reward)
        return reward

original = [Bandit(0.02), Bandit(0.04), Bandit(0.06), Bandit(0.08), Bandit(0.10)]

bandits = original
simulations = 500

num_bandits = len(bandits)
num_iter = 0

while num_bandits > 1 and num_iter < 10:
    num_iter = num_iter + 1
    
    for sim in range(simulations):
        for bandit in range(num_bandits):
            bandits[bandit].pull()

    n_reward = [np.sum(bandit.rewards) for bandit in bandits]
    max_reward = max(n_reward)
    nobs = len(bandits[0].rewards)

    p_value = list(map(lambda a : proportions_ztest((a, max_reward), (nobs, nobs))[1], n_reward))
    bandits = list(compress(bandits, np.array(p_value) > 0.05))
    num_bandits = len(bandits)
    
evaluations = len(bandits[0].rewards)
total_evaluations = np.sum([len(bandit.rewards) for bandit in original])
total_reward = np.sum([np.sum(bandit.rewards) for bandit in original])
avg_reward = total_reward / total_evaluations

En este ejemplo se han creado cinco bandidos con diferente probabilidad de éxito. En un bucle while se simula 500 veces cada uno de los bandidos y posteriormente se extrae el número de casos existimos en cada uno de ellos. Lo que se almacena en el vector n_reward. A partir del cual se puede extraer fácilmente la recompensa máxima que se almacena en max_reward.

Con esto y el número de casos (nobs) se puede obtener el p-valor (pvalue) de cada una de las muestras respecto al máximo. Seleccionado aquellos bandidos para los cuales no se puede rechazar la hipótesis nula. Usando para ello una probabilidad de 0.05.

Si esta prueba la pasa solamente un bandido será el mejor. En caso contrario es necesario aumentar el número de muestras hasta que solamente quede uno o se alcance el máximo de iteraciones permitidas. Lo que se tienen que incluir para evitar bucles infinitos.

Resultados

Si se ejecuta el código se puede ver que es necesario 7 iteraciones, 3500, simulaciones para identificar el mejor bandido. Aunque solamente para los dos mejores, ya que los tres peores se han podido descartar después de una sola iteración. Resultados que pueden cambiar ligeramente en caso de que se modifique el valor de la semilla.

Con esto, después de 8500 simulaciones se han obtenido 692 casos positivos, lo que corresponde a un 8,1%. Por debajo del 10% máximo que se esperaría del mejor bandido. Aunque una vez obtenido este resultado ya se puede jugar solo con este bandido y mejorar la recompensa media.

Publicidad


Conclusiones

En esta entrada hemos visto cómo se puede emplear un Test A/B para el Bandido Multibrazo. Pudiendo identificar rápidamente el bandido que ofrece la mayor recompensa. Este es un método que requiere muchas pruebas antes de obtener unos resultados concluyentes, por eso podemos estar mucho tiempo jugando con bandidos que no son óptimos. En futuras entregas veamos como hacer esto con otras estrategias como pueden ser Epsilon-greedy, valores iniciales optimistas o UCB1.

Imagen de PIRO4D 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

  • La caverna del consumo, o cómo Greenspan miraba calzoncillos para hacer política monetaria – El bestiario de los indicadores económicos absurdos (parte 1)
  • La vanidad del paisaje, o por qué un becario sale a contar grúas a Manhattan – El bestiario de los indicadores económicos absurdos (parte 2)
  • Augurios deportivos y portadas malditas, o cuando The Economist predice mejor al revés – El bestiario de los indicadores económicos absurdos (parte 3)
  • El Binning en Credit Scoring: El Arte de Discretizar Variables
  • Cómo comparar tendencias con gráficos de líneas en Matplotlib: guía práctica paso a paso
  • Analytics Lane lanza la versión 1.2 del laboratorio con nuevas herramientas de ajuste de curvas y cálculo matricial
  • Subplots en Matplotlib: cómo organizar múltiples gráficos en una sola figura
  • Ley de Benford: cómo detectar datos manipulados con ejemplos reales
  • Síndrome del objeto brillante en ciencia de datos: el error simétrico a los costes hundidos

Publicado en: Ciencia de datos Etiquetado como: Aprendizaje por refuerzo, Estadística, 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

Augurios deportivos y portadas malditas, o cuando The Economist predice mejor al revés – El bestiario de los indicadores económicos absurdos (parte 3)

junio 18, 2026 Por Daniel Rodríguez

El Binning en Credit Scoring: El Arte de Discretizar Variables

junio 16, 2026 Por Daniel Rodríguez

Noticias

Analytics Lane lanza la versión 1.2 del laboratorio con nuevas herramientas de ajuste de curvas y cálculo matricial

junio 12, 2026 Por Daniel Rodríguez

Publicidad

Es tendencia

  • Buscar en Excel con dos o más criterios publicado el septiembre 7, 2022 | en Herramientas
  • Exactitud, precisión, recall… qué mide realmente cada métrica (y qué no) publicado el marzo 3, 2026 | en Ciencia de datos
  • Trazar ejes logarítmicos en Matplotlib publicado el agosto 30, 2022 | en Python
  • Seleccionar filas y columnas en Pandas con iloc y loc publicado el junio 21, 2019 | en Python
  • Creación de gráficos de residuos en Seaborn para análisis de regresión publicado el agosto 24, 2023 | en Python

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.1 (11)

Aplicar el método D’Hondt en Excel

Comentarios recientes

  • bif en JSON en bases de datos: cuándo es buena idea y cuándo no
  • bif en Cómo desinstalar Oracle Database 19c en Windows
  • 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

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