Pruebas AB Bayesianas con Pyro

Experimentos AB Bayesianos con Pyro

Una introducción al pensamiento bayesiano y las pruebas AB utilizando Pyro

Crédito: Free-Photos en Pixabay

Este artículo es una introducción a las pruebas AB utilizando el lenguaje de programación probabilística Python (PPL) Pyro, una alternativa a PyMC. La motivación para escribir este artículo fue ampliar mi comprensión de la inferencia estadística bayesiana utilizando el marco de trabajo Pyro y ayudar a otros en el proceso. Por lo tanto, se agradecen y se animan los comentarios.

Introducción

Mi experiencia previa con el modelado bayesiano en Python fue con PyMC. Sin embargo, he encontrado problemas al trabajar con algunas de las últimas versiones. Mi investigación sobre otros lenguajes de programación probabilística me llevó a descubrir Pyro, un PPL universal desarrollado por Uber y respaldado por PyTorch en el backend. La documentación tanto de Pyro como de PyTorch se encuentra enlazada a continuación.

Pyro

Programación Probabilística Universal Profunda

pyro.ai

Documentación de PyTorch – Documentación de PyTorch 2.1

PyTorch es una biblioteca de tensores optimizada para el aprendizaje profundo utilizando GPUs y CPUs. Las funcionalidades se describen en esta documentación…

pytorch.org

Mientras exploraba Pyro, me resultó difícil encontrar tutoriales completos de principio a fin para las pruebas AB utilizando el paquete. Este artículo tiene como objetivo llenar ese vacío.

Este artículo consta de cinco secciones. En la primera sección, daré una introducción al pensamiento bayesiano, un contexto filosófico en el que se fundamenta la metodología. Daré una breve introducción técnica sobre Pyro y los métodos bayesianos utilizados para realizar nuestras inferencias estadísticas. A continuación, realizaré una prueba AB utilizando Pyro y discutiré los resultados. Luego explicaré el caso de las pruebas AB bayesianas en un entorno empresarial. La sección final resumirá todo.

Una introducción al pensamiento bayesiano

El proceso bayesiano es relativamente simple a alto nivel. En primer lugar, tenemos una variable en la que estamos interesados. Establecemos nuestra comprensión actual de esa variable, que expresamos como una distribución de probabilidad (todo en el mundo de Bayes es una distribución de probabilidad). Esto se denomina “prior”. La probabilidad en la inferencia bayesiana es epistémica, lo que significa que surge a través de nuestro grado de conocimiento. Por lo tanto, la distribución de probabilidad que establecemos como prior es una declaración de incertidumbre tanto como de comprensión. Luego observamos eventos del mundo real. Estas observaciones se utilizan para actualizar nuestra comprensión de la variable en la que estamos interesados. El nuevo estado de nuestra comprensión se llama “posterior”. También caracterizamos el posterior con una distribución de probabilidad, la probabilidad de la variable en la que estamos interesados, dada la información que hemos observado. Este proceso se ilustra en el diagrama de flujo a continuación, donde theta es la variable en la que estamos interesados y la información es el resultado de los eventos que hemos observado.

Proceso bayesiano

El proceso bayesiano es realmente cíclico, porque luego repetimos este proceso, empezando de nuevo pero utilizando nuestro conocimiento recién adquirido después de observar el mundo. Nuestro antiguo posterior se convierte en nuestro nuevo prior, observamos nuevos eventos y una vez más actualizamos nuestra comprensión, volviéndonos “menos y menos equivocados” como lo expresó Nate Silver en su libro The Signal and the Noise. Continuamos reduciendo nuestra incertidumbre en relación a la variable, convergiendo hacia un estado de certeza (pero nunca podemos estar seguros). Matemáticamente, esta forma de pensar está encapsulada por el teorema de Bayes.

Teorema de Bayes

En la práctica, el teorema de Bayes se vuelve rápidamente computacionalmente intratable para modelos grandes en dimensiones superiores. Hay numerosos enfoques para resolver este problema, pero el método que usaremos hoy se llama Cadena de Markov Monte Carlo, o MCMC. MCMC es una clase de algoritmos (usaremos uno llamado Hamiltonian Monte Carlo), que extrae muestras de una distribución de probabilidad de manera inteligente. Está fuera del alcance de este artículo adentrarse en esto, pero proporcionaré algunas referencias útiles al final para lectura adicional. Por ahora, es suficiente saber que el teorema de Bayes es demasiado complejo para poder calcularlo, por lo que aprovechamos el poder de algoritmos avanzados, como MCMC, para ayudar. Este artículo se centrará en MCMC utilizando Pyro. Sin embargo, Pyro enfatiza el uso de Inferencia Variacional Estocástica (SVI), un enfoque basado en aproximaciones, que no se cubrirá aquí.

Pruebas AB utilizando Pyro

Consideremos una empresa que ha diseñado una nueva página de inicio del sitio web y quiere entender el impacto que esto tendrá en la conversión, es decir, ¿los visitantes continúan su sesión web en el sitio web después de aterrizar en la página? En el grupo de prueba A, a los visitantes del sitio web se les mostrará la página de inicio actual. En el grupo de prueba B, a los visitantes del sitio web se les mostrará la nueva página de inicio. En el resto del artículo, me referiré al grupo de prueba A como el grupo de control y al grupo B como el grupo de tratamiento. La empresa es escéptica sobre el cambio y ha optado por una división de tráfico de sesión del 80/20. El número total de visitantes y el número total de conversiones de página para cada grupo de prueba se resumen a continuación.

Observaciones de prueba

La hipótesis nula de la prueba AB es que no habrá cambios en la conversión de la página para los dos grupos de prueba. Bajo el marco frecuentista, esto se expresaría de la siguiente manera para una prueba bilateral, donde r_c y r_t son las tasas de conversión de página en los grupos de control y tratamiento, respectivamente.

Hipótesis nula y alternativa

Una prueba de significancia buscaría rechazar o no rechazar la hipótesis nula. Bajo el marco bayesiano, expresamos la hipótesis nula ligeramente diferente al afirmar el mismo prior para cada uno de los grupos de prueba.

Detengámonos y delineemos exactamente lo que está sucediendo durante nuestra prueba. La variable en la que estamos interesados es la tasa de conversión de la página. Esto se calcula simplemente tomando el número de visitantes convertidos distintos sobre el número total de visitantes. El evento que genera esta tasa es si el visitante hace clic en la página. Aquí solo hay dos resultados posibles para cada visitante, o bien el visitante hace clic en la página y convierte, o no lo hace. Algunos de ustedes pueden reconocer que para cada visitante distinto, esto es un ejemplo de una prueba de Bernoulli; hay una prueba y dos resultados posibles. Ahora, cuando recopilamos un conjunto de estas pruebas de Bernoulli, tenemos una distribución binomial. Cuando la variable aleatoria X tiene una distribución binomial, le damos la siguiente notación:

Notación de la distribución binomial

Donde n es el número de visitantes (o el número de pruebas de Bernoulli), y p es la probabilidad del evento en cada prueba. p es lo que nos interesa aquí, queremos entender cuál es la probabilidad de que un visitante convierta en la página en cada grupo de prueba. Hemos observado algunos datos, pero como se mencionó en la sección anterior, primero necesitamos definir nuestro anterior. Como siempre en estadística bayesiana, necesitamos definir este anterior como una distribución de probabilidad. Como se mencionó antes, esta distribución de probabilidad es una caracterización de nuestra incertidumbre. Las distribuciones beta se utilizan comúnmente para modelar probabilidades, ya que están definidas entre los intervalos de [0,1]. Además, usar una distribución beta como nuestro anterior para una función de verosimilitud binomial nos da la propiedad útil de conjugación, lo que significa que nuestro posterior se generará a partir de la misma distribución que nuestro anterior. Decimos que la distribución beta es un anterior conjugado. Una distribución beta está definida por dos parámetros, alfa y confusamente beta.

Notación de Distribución Beta

Con acceso a datos históricos, podemos establecer una suposición previa informada. No necesariamente necesitamos datos históricos, podríamos usar nuestra intuición para informar nuestra comprensión, pero por ahora supongamos que no tenemos ninguno (más adelante en este tutorial utilizaremos suposiciones previas informadas, pero para demostrar el impacto, comenzaré con las no informadas). Supongamos que no tenemos comprensión de la tasa de conversión en el sitio de la empresa y, por lo tanto, definimos nuestra suposición previa como Beta(1,1). Esto se llama una suposición previa plana. La distribución de probabilidad de esta función se parece al gráfico a continuación, es igual a una distribución uniforme definida entre los intervalos [0,1]. Al establecer una suposición previa Beta(1,1), decimos que todos los posibles valores de la tasa de conversión de la página son igualmente probables.

Crédito: Autor

Ahora tenemos toda la información que necesitamos, las suposiciones previas y los datos. Vamos a entrar en el código. El código proporcionado aquí proporcionará un marco para comenzar con las pruebas AB usando Pyro; por lo tanto, descuida algunas características del paquete. Para ayudar a optimizar aún más el código y aprovechar al máximo las capacidades de Pyro, recomiendo consultar la documentación oficial.

Primero, debemos importar nuestros paquetes. La última línea es una buena práctica, especialmente cuando se trabaja en notebooks, para borrar el almacén de parámetros que hemos acumulado.

import pyroimport pyro.distributions as distfrom pyro.infer import NUTS, MCMCimport torchfrom torch import tensorimport matplotlib.pyplot as pltimport seaborn as snsfrom functools import partialimport pandas as pdpyro.clear_param_store()

Los modelos en Pyro se definen como funciones regulares de Python. Esto es útil ya que resulta intuitivo de seguir.

def modelo(beta_alpha, beta_beta):    def _modelo_(traffic: tensor, number_of_conversions: tensor):        # Definir Primitivas Estocásticas        prior_c = pyro.sample('prior_c', dist.Beta(beta_alpha, beta_beta))        prior_t = pyro.sample('prior_t', dist.Beta(beta_alpha, beta_beta))        priors = torch.stack([prior_c, prior_t])        # Definir las Primitivas Estocásticas Observadas        with pyro.plate('datos'):            observations = pyro.sample('obs', dist.Binomial(traffic, priors),\                             obs = number_of_conversions)    return partial(_modelo_)

Algunos puntos para analizar y explicar aquí. Primero, tenemos una función envuelta dentro de una función externa; la función externa devuelve la función parcial de la función interna. Esto nos permite cambiar nuestras suposiciones previas sin necesidad de cambiar el código. Me he referido a las variables definidas en la función interna como primitivas, piensa en las primitivas como variables en el modelo. Tenemos dos tipos de primitivas en el modelo, estocásticas y estocásticas observadas. En Pyro, no tenemos que definir explícitamente la diferencia, simplemente agregamos el argumento obs al método de muestreo cuando es una primitiva observada e Pyro lo interpreta en consecuencia. Las primitivas observadas están contenidas dentro del administrador de contexto pyro.plate(), lo cual es una buena práctica y hace que nuestro código luzca más limpio. Nuestras primitivas estocásticas son nuestras dos suposiciones previas, caracterizadas por distribuciones Beta, gobernadas por los parámetros alfa y beta que pasamos desde la función externa. Como se mencionó anteriormente, afirmamos la hipótesis nula definiéndolas como iguales. Luego apilamos estas dos primitivas juntas usando tensor.stack(), que realiza una operación similar a la concatenación de una matriz de Numpy. Esto devolverá un tensor, la estructura de datos requerida para la inferencia en Pyro. Hemos definido nuestro modelo, ahora pasemos a la etapa de inferencia.

Como se mencionó anteriormente, este tutorial utilizará el MCMC. La función a continuación tomará el modelo que hemos definido anteriormente y el número de muestras que deseamos usar para generar nuestra distribución posterior como un parámetro. También pasamos nuestros datos a la función, como lo hicimos para el modelo.

def ejecutar_inferencia(modelo, numero_de_muestras, trafico, numero_de_conversiones):    kernel = NUTS(modelo)    mcmc = MCMC(kernel, num_samples = numero_de_muestras, warmup_steps = 200)    mcmc.run(trafico, numero_de_conversiones)    return mcmc

La primera línea dentro de esta función define nuestro núcleo. Usamos la clase NUTS para definir nuestro núcleo, que significa No-U-Turn Sampler, una versión de Hamiltonian Monte Carlo con ajuste automático. Esto le indica a Pyro cómo muestrear del espacio de probabilidad posterior. Nuevamente, está más allá del alcance de este artículo profundizar en este tema, pero por ahora es suficiente saber que NUTS nos permite muestrear de forma inteligente el espacio de probabilidad. Luego, el núcleo se utiliza para inicializar la clase MCMC en la segunda línea, especificando que use NUTS. Pasamos el argumento number_of_samples en la clase MCMC, que es el número de muestras utilizado para generar la distribución posterior. Asignamos la clase MCMC inicializada a la variable mcmc y llamamos al método run(), pasando nuestros datos como parámetros. La función devuelve la variable mcmc.

Esto es todo lo que necesitamos; el siguiente código define nuestros datos y llama a las funciones que acabamos de crear usando la prior Beta(1,1).

traffic = torch.tensor([5523., 1379.])conversions =torch.tensor([2926., 759.])inference = run_infernce(model(1,1), number_of_samples = 1000, \               traffic = traffic, number_of_conversions = conversions)

El primer elemento de los tensores traffic y conversions son los conteos para el grupo de control, y el segundo elemento en cada tensor es el conteo para el grupo de tratamiento. Pasamos la función model, con los parámetros para gobernar nuestra distribución previa, junto con los tensores que hemos definido. Al ejecutar este código, se generarán nuestras muestras posteriores. Ejecutamos el siguiente código para extraer las muestras posteriores y pasarlas a un dataframe de Pandas.

posterior_samples = inference.get_samples()posterior_samples_df = pd.DataFrame(posterior_samples)

Observa que los nombres de columna de este dataframe son las cadenas que pasamos cuando definimos nuestras primitivas en la función model. Cada fila en nuestro dataframe contiene muestras extraídas de la distribución posterior, y cada una de estas muestras representa una estimación de la tasa de conversión de la página, el valor de probabilidad p que gobierna nuestra distribución binomial. Ahora que hemos devuelto las muestras, podemos trazar nuestras distribuciones posteriores.

Resultados

Una forma perspicaz de visualizar los resultados de la prueba AB con dos grupos de prueba es mediante un gráfico conjunto de densidad de núcleo. Nos permite visualizar la densidad de las muestras en el espacio de probabilidad en ambas distribuciones. El siguiente gráfico se puede producir a partir del dataframe que acabamos de construir.

Crédito: Autor

El espacio de probabilidad contenido en el gráfico anterior se puede dividir en su diagonal, cualquier cosa por encima de la línea indicaría regiones donde la estimación de la tasa de conversión es mayor en el grupo de tratamiento que en el de control y viceversa. Como se ilustra en el gráfico, las muestras extraídas de la posterior están densamente pobladas en la región que indicaría que la tasa de conversión es mayor en el grupo de tratamiento. Es importante destacar que la distribución posterior para el grupo de tratamiento es más amplia que la del grupo de control, lo que refleja un mayor grado de incertidumbre. Esto es resultado de observar menos datos en el grupo de tratamiento. Sin embargo, el gráfico indica firmemente que el grupo de tratamiento ha superado al grupo de control. Al recolectar una serie de muestras de la posterior y tomar la diferencia elemento por elemento, podemos decir que la probabilidad de que el grupo de tratamiento supere al grupo de control es del 90,4%. Esta cifra sugiere que el 90,4% de las muestras extraídas de la posterior se ubicarán por encima de la diagonal en el gráfico de densidad conjunto anterior.

Estos resultados se lograron utilizando una prior plana (no informada). El uso de una prior informada puede ayudar a mejorar el modelo, especialmente cuando la disponibilidad de datos observados es limitada. Un ejercicio útil es explorar los efectos del uso de diferentes priors. El gráfico siguiente muestra la función de densidad de probabilidad Beta(2,2) y el gráfico conjunto que produce cuando volvemos a ejecutar el modelo. Podemos ver que el uso de la prior Beta(2,2) produce una distribución posterior muy similar para ambos grupos de prueba.

Crédito: Autor

Las muestras extraídas de la posterior sugieren que hay un 91,5% de probabilidad de que el grupo de tratamiento tenga un mejor rendimiento que el de control. Por lo tanto, creemos con un mayor grado de certeza que el grupo de tratamiento es mejor que el de control en comparación con el uso de una prior plana. Sin embargo, en este ejemplo la diferencia es insignificante.

Hay una cosa más que me gustaría destacar sobre estos resultados. Cuando ejecutamos la inferencia, le dijimos a Pyro que generara 1000 muestras del posterior. Este es un número arbitrario, seleccionar un número diferente de muestras puede cambiar los resultados. Para resaltar el efecto de aumentar el número de muestras, realicé una prueba AB donde las observaciones de los grupos de control y tratamiento fueron las mismas, cada una con una tasa de conversión general del 50%. El uso de un prior Beta(2,2) genera las siguientes distribuciones posteriores a medida que incrementamos incrementalmente el número de muestras.

Crédito: Autor

Cuando ejecutamos nuestra inferencia con solo 10 muestras, la distribución posterior para los grupos de control y tratamiento es relativamente amplia y adopta formas diferentes. A medida que aumenta el número de muestras que extraemos, las distribuciones convergen, generando en última instancia distribuciones casi idénticas. Además, observamos dos propiedades de las distribuciones estadísticas, el teorema del límite central y la ley de los grandes números. El teorema del límite central establece que la distribución de las medias de las muestras tiende hacia una distribución normal a medida que aumenta el número de muestras, y podemos ver eso en el gráfico anterior. Además, la ley de los grandes números establece que a medida que el tamaño de la muestra crece, la media de la muestra tiende hacia la media de la población. Podemos ver que la media de las distribuciones en la esquina inferior derecha es aproximadamente 0.5, la tasa de conversión observada en cada una de las muestras de prueba.

El caso empresarial para las pruebas AB Bayesianas

Las pruebas AB Bayesianas pueden ayudar a elevar la cultura de prueba y aprendizaje de un negocio. La inferencia estadística bayesiana permite detectar rápidamente pequeños incrementos en la prueba, ya que no depende de las probabilidades a largo plazo para sacar conclusiones. Las conclusiones de las pruebas se pueden alcanzar más rápido y, por lo tanto, aumenta la velocidad de aprendizaje. Las pruebas AB Bayesianas también permiten detener tempranamente una prueba, si los resultados obtenidos a través de “espiar” indican que los grupos de prueba están funcionando significativamente peor que el grupo de control, entonces la prueba se puede detener. Por lo tanto, el costo de oportunidad de las pruebas puede reducirse significativamente. Este es un beneficio importante de las pruebas AB Bayesianas; los resultados se pueden monitorear constantemente y nuestras distribuciones posteriores se actualizan constantemente. Por el contrario, la detección temprana de un aumento en el objeto de prueba puede ayudar a las empresas a implementar cambios más rápido, reduciendo la latencia de implementación de cambios que mejoran los ingresos. Las empresas orientadas al cliente deben poder implementar y analizar rápidamente los resultados de las pruebas, lo cual es facilitado por el marco de pruebas AB Bayesianas.

Resumen

Este artículo ha brindado una breve introducción al pensamiento bayesiano y ha explorado los resultados de las pruebas AB bayesianas utilizando Pyro. Espero que haya encontrado este artículo esclarecedor. Como se mencionó en la introducción, se agradece y se anima el feedback. Como prometí, he vinculado algunos materiales de lectura adicional a continuación.

Material recomendado

Los siguientes libros ofrecen una buena visión de la inferencia bayesiana:

  • The Signal and the Noise: The Art and Science of Prediction — Nate Silver
  • The Book of Why: The New Science of Cause and Effect — Judea Pearl y Dana Mackenzie. Aunque este libro se centra en gran medida en la causalidad, el capítulo 3 es una lectura valiosa sobre Bayes.
  • Bayesian Methods for Hackers: Probabilistic Programming and Bayesian Inference — Cameron Davidson-Pilon. Este libro también está disponible en Git, lo he vinculado a continuación.

GitHub — CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers: también conocido como “Bayesian…

también conocido como “Bayesian Methods for Hackers”: Una introducción a los métodos bayesianos + programación probabilística con…

github.com

Estos artículos de VoAGI proporcionan explicaciones detalladas de MCMC.

Explicación de la cadena de Markov Monte Carlo (MCMC)

Los métodos MCMC son una familia de algoritmos que utilizan cadenas de Markov para realizar estimaciones de Monte Carlo.

towardsdatascience.com

Problema de inferencia bayesiana, MCMC e inferencia variacional

Visión general del problema de inferencia bayesiana en estadísticas.

towardsdatascience.com

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

Clave maestra para la separación de fuentes de audio Presentamos AudioSep para separar cualquier cosa que describas

La Análisis de Escena Auditiva Computacional (CASA, por sus siglas en inglés) es un campo dentro del procesamiento de...

Inteligencia Artificial

Investigadores de CMU proponen GILL un método de IA para fusionar LLMs con modelos de codificador y decodificador de imágenes

Con el lanzamiento del nuevo GPT 4 de OpenAI, se ha introducido la multimodalidad en los Modelos de Lenguaje Grandes....

Inteligencia Artificial

El (Largo) Cola Mueve al Perro Las Consecuencias Inesperadas del Arte Personalizado de la IA

La reciente presentación de Meta de Emu en el mundo de las películas generativas marca un punto de inflexión, un mome...

Noticias de Inteligencia Artificial

Utilice AWS CDK para implementar configuraciones del ciclo de vida de Amazon SageMaker Studio.

Amazon SageMaker Studio es el primer entorno de desarrollo integrado (IDE) completamente para machine learning (ML). ...