Path: blob/master/site/es-419/probability/examples/Modeling_with_JointDistribution.ipynb
25118 views
Copyright 2019 The TensorFlow Authors.
Licensed under the Apache License, Version 2.0 (the "License");
Modelización bayesiana con distribución conjunta
JointDistributionSequential
es una clase similar a una distribución recientemente introducida que permite a los usuarios crear rápidamente prototipos de modelos bayesianos. Le permite encadenar múltiples distribuciones y usar la función lambda para introducir dependencias. Se diseñó para construir modelos bayesianos de tamaño pequeño a mediano, incluidos muchos modelos de uso común, como GLM, modelos de efectos mixtos, modelos de mezcla y más. Habilita todas las caracterÃsticas necesarias para un flujo de trabajo bayesiano: muestreo predictivo previo, podrÃa conectarse a otro modelo gráfico bayesiano o red neuronal más grande. En este Colab, se muestran algunos ejemplos de cómo usar JointDistributionSequential
para alcanzar su flujo de trabajo bayesiano diario.
Dependencias y requisitos previos
¡Aceleremos el proceso!
Antes de sumergirnos, asegurémonos de que estamos usando una GPU para esta demostración.
Para hacer esto, seleccione "Tiempo de ejecución" -> "Cambiar tipo de tiempo de ejecución" -> "Acelerador de hardware" -> "GPU".
El siguiente fragmento verificará si tenemos acceso a una GPU.
Nota: Si, por alguna razón, no puede acceder a una GPU, esta colaboración seguirá funcionando. (El entrenamiento simplemente llevará más tiempo).
JointDistribution
Notas: Esta clase de distribución es útil cuando solo tienes un modelo simple. "Simple" significa gráficos en forma de cadena; aunque el enfoque técnicamente funciona para cualquier PGM con un grado máximo de 255 para un solo nodo (porque las funciones de Python pueden tener como máximo tantos argumentos).
La idea básica es que el usuario especifique una lista de callable
que produzcan instancias tfp.Distribution
, una para cada vértice en su PGM. El callable
tendrá como máximo tantos argumentos como su Ãndice en la lista. (Para comodidad del usuario, los argumentos se pasarán en orden inverso al de creación). Internamente, "recorreremos el gráfico" simplemente pasando el valor de cada RV anterior a cada invocable. Al hacerlo, implementamos la [regla de la cadena de probabilidad](https://en.wikipedia.org/wiki/Chain_rule_(probability)#More_than_two_random_variables): ParseError: KaTeX parse error: Expected '}', got '&' at position 29: …od_i^d p(x_i|x{&̲lt;i}).
La idea es bastante simple, incluso como código Python. Este es el punto esencial:
Puede encontrar más información en la cadena de documentación de JointDistributionSequential
, pero lo esencial es que pasa una lista de distribuciones para inicializar la Clase, si algunas distribuciones en la lista dependen de la salida de otra distribución/variable ascendente, simplemente la envuelve con una función lambda. ¡Ahora veamos cómo funciona en acción!
Regresión lineal (robusta)
Desde la documentación PyMC3 GLM: Regresión robusta con detección de valores atÃpicos
Modelo OLS convencional
Ahora, configuremos un modelo lineal, un problema simple de regresión de intersección + pendiente:
A continuación, puede consultar el gráfico del modelo para ver la dependencia. Tenga en cuenta que x
está reservado como el nombre del último nodo y no puede asegurarlo como argumento lambda en su modelo JointDistributionSequential.
El muestreo del modelo es bastante simple:
...que da una lista de tf.Tensor. Puede conectarlo inmediatamente a la función log_prob para calcular la log_prob del modelo:
Mmm, aquà hay algo que no está bien: ¡deberÃamos obtener una log_prob escalar! De hecho, podemos verificar más a fondo si algo anda mal llamando a .log_prob_parts
, que proporciona la log_prob
de cada nodo en el modelo gráfico:
... ¡resulta que el último nodo no está ejecutando reduce_sum a lo largo de la dimensión/eje i. i. d.! Cuando sumamos, las dos primeras variables se transmiten incorrectamente.
El truco aquà es usar tfd.Independent
para reinterpretar la forma del lote (de modo que el resto del eje se reduzca correctamente):
Ahora, verifiquemos el último nodo/distribución del modelo, puede ver que la forma del evento ahora se interpreta correctamente. Tenga en cuenta que puede ser necesario un poco de prueba y error para obtener los reinterpreted_batch_ndims
correctos, pero siempre puede imprimir fácilmente la distribución o el tensor muestreado para verificar la forma.
Otra API JointDistribution*
MLE
¡Y ahora podemos hacer inferencias! Se puede usar el optimizador para encontrar la estimación de máxima verosimilitud.
Modelo de versión por lotes y MCMC
En la inferencia bayesiana, normalmente queremos trabajar con muestras del MCMC, ya que cuando las muestras son posteriores, podemos conectarlas a cualquier función para calcular las expectativas. Sin embargo, la API del MCMC requiere que escribamos modelos que sean compatibles con lotes, y podemos comprobar que nuestro modelo en realidad no es "compatible con lotes" al invocar sample([...])
En este caso, es relativamente sencillo ya que solo tenemos una función lineal dentro de nuestro modelo, bastarÃa con expandir la forma:
Podemos volver a probar y evaluar log_prob_parts para ejecutar algunas comprobaciones:
Algunas notas al margen:
Queremos trabajar con la versión por lotes del modelo porque es la más rápida para el MCMC de cadenas múltiples. En los casos en que no pueda reescribir el modelo como una versión por lotes (por ejemplo, modelos ODE), puede asignar la función log_prob con
tf.map_fn
para lograr el mismo efecto.Ahora
mdl_ols_batch.sample()
podrÃa no funcionar ya que tenemos previa escaladora, pues no podemos hacerscaler_tensor[:, None]
. En este caso, la solución consiste en expandir el tensor escalador al rango 1 y envolvertfd.Sample(..., sample_shape=1)
.Se recomienda escribir el modelo como una función para que sea más fácil modificar parámetros como los hiperparámetros.
MCMC mediante el uso de No-U-Turn Sampler
Método Student t
Tenga en cuenta que a partir de ahora siempre se trabaja con la versión por lotes de un modelo.
Muestra prospectiva (muestreo predictivo previo)
MLE
MCMC
Agrupamiento jerárquico parcial
De PyMC3 datos de béisbol sobre 18 jugadores de Efron y Morris (1975)
Muestra prospectiva (muestreo predictivo previo)
De nuevo, observe que si no se usa Independent terminará con una log_prob que tiene una batch_shape incorrecta.
MLE
Una caracterÃstica bastante sorprendente de tfp.optimizer
es que se puede optimizar en paralelo para lotes k de puntos de inicio y especificar el kwarg stopping_condition
: puede configurarlo en tfp.optimizer.converged_all
para ver si todos encuentran el mismo mÃnimo o tfp.optimizer.converged_any
. tfp.optimizer.converged_any
para encontrar una solución local rápidamente.
LBFGS no convergió.
MCMC
Modelo de efectos mixtos (Radon)
El último modelo del documento PyMC3: Introducción a los métodos bayesianos para el modelado multinivel
Algunos cambios en la previa (menor escala, etc.)
Para modelos con transformación compleja, la implementación en un estilo funcional facilitarÃa mucho la escritura y las pruebas. Además, facilita la generación programática de la función log_prob condicionada a (minilotes) de datos ingresados:
Inferencia variacional
Una caracterÃstica muy poderosa de JointDistribution*
es que puede generar fácilmente una aproximación para la VI. Por ejemplo, para ejecutar ADVI de campo medio, simplemente inspecciona el grafo y reemplaza todas las distribuciones no observadas con una distribución Normal.
ADVI de campo medio
También puede usar la caracterÃstica experimental en tensorflow_probability/python/experimental/vi para construir una aproximación variacional, que es esencialmente la misma lógica que se usa a continuación (es decir, el uso de JointDistribution para construir una aproximación), pero con la salida de la aproximación en el espacio original en lugar del espacio ilimitado.
ADVI de rango completo
Para ADVI de rango completo, queremos aproximar la posterior con una gaussiana multivariada.
Modelo mixto Beta-Bernoulli
Un modelo mixto en el que varios revisores etiquetan algunos elementos, con etiquetas latentes (verdaderas) desconocidas.