Introdução
A atualização bayesiana (Bayesian updating) é uma abordagem estatística que nos permite atualizar a probabilidade de uma hipótese à medida que novos dados se tornam disponíveis. Neste laboratório, usaremos Matplotlib para criar uma animação que mostra como a atualização bayesiana funciona. Especificamente, simularemos um experimento de lançamento de moeda e usaremos a atualização bayesiana para estimar a probabilidade da moeda cair com a face "cara" para cima.
Dicas para a VM
Após a inicialização da VM, clique no canto superior esquerdo para mudar para a aba Notebook e acessar o Jupyter Notebook para praticar.
Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.
Se você enfrentar problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão, e resolveremos o problema prontamente para você.
Importar as Bibliotecas Necessárias
Começamos importando as bibliotecas que usaremos no laboratório. Especificamente, usaremos matplotlib.pyplot para visualização, numpy para computação numérica e math para funções matemáticas.
import math
import matplotlib.pyplot as plt
import numpy as np
Definir a PDF da Distribuição Beta
A distribuição beta é uma distribuição de probabilidade contínua que é frequentemente usada para representar a distribuição de probabilidades. Na atualização bayesiana (Bayesian updating), usamos a distribuição beta como uma distribuição a priori (prior distribution) para representar nossas crenças sobre a probabilidade de uma hipótese antes de observar quaisquer dados. Em seguida, atualizamos a distribuição beta à medida que observamos novos dados.
Para simular a atualização bayesiana, precisamos definir uma função que calcula a função densidade de probabilidade (PDF, probability density function) da distribuição beta. Podemos usar a função math.gamma para calcular a função gama, que é usada na PDF da distribuição beta.
def beta_pdf(x, a, b):
return (x**(a-1) * (1-x)**(b-1) * math.gamma(a + b)
/ (math.gamma(a) * math.gamma(b)))
Definir a Classe UpdateDist
Em seguida, definimos uma classe chamada UpdateDist que será usada para atualizar a distribuição beta à medida que novos dados são observados. A classe UpdateDist recebe dois argumentos: o objeto de eixo do Matplotlib e a probabilidade inicial de sucesso.
class UpdateDist:
def __init__(self, ax, prob=0.5):
self.success = 0
self.prob = prob
self.line, = ax.plot([], [], 'k-')
self.x = np.linspace(0, 1, 200)
self.ax = ax
## Set up plot parameters
self.ax.set_xlim(0, 1)
self.ax.set_ylim(0, 10)
self.ax.grid(True)
## This vertical line represents the theoretical value, to
## which the plotted distribution should converge.
self.ax.axvline(prob, linestyle='--', color='black')
O método __init__ inicializa a instância da classe definindo o número inicial de sucessos como zero (self.success = 0) e a probabilidade inicial de sucesso para o valor passado como argumento (self.prob = prob). Também criamos um objeto de linha para representar a distribuição beta e configuramos os parâmetros do gráfico.
O método __call__ é chamado toda vez que a animação é atualizada. Ele simula um experimento de lançamento de moeda e atualiza a distribuição beta de acordo.
def __call__(self, i):
## This way the plot can continuously run and we just keep
## watching new realizations of the process
if i == 0:
self.success = 0
self.line.set_data([], [])
return self.line,
## Choose success based on exceed a threshold with a uniform pick
if np.random.rand() < self.prob:
self.success += 1
y = beta_pdf(self.x, self.success + 1, (i - self.success) + 1)
self.line.set_data(self.x, y)
return self.line,
Se este for o primeiro quadro da animação (if i == 0), redefinimos o número de sucessos para zero e limpamos o objeto de linha. Caso contrário, simulamos um experimento de lançamento de moeda gerando um número aleatório entre 0 e 1 (np.random.rand()) e comparando-o com a probabilidade de sucesso (self.prob). Se o número aleatório for menor que a probabilidade de sucesso, contamos como um sucesso e atualizamos a distribuição beta usando a função beta_pdf. Finalmente, atualizamos o objeto de linha com os novos dados e o retornamos.
Criar Animação
Agora que definimos a classe UpdateDist, podemos criar a animação usando a classe FuncAnimation do Matplotlib. Criamos um objeto de figura e um objeto de eixo e passamos o objeto de eixo para a classe UpdateDist para criar uma nova instância da classe.
fig, ax = plt.subplots()
ud = UpdateDist(ax, prob=0.7)
anim = FuncAnimation(fig, ud, frames=100, interval=100, blit=True)
plt.show()
A classe FuncAnimation recebe vários argumentos:
fig: o objeto de figuraud: a instânciaUpdateDistframes: o número de quadros a serem animadosinterval: o tempo entre os quadros em milissegundosblit: se deve atualizar apenas as partes do gráfico que foram alteradas
Interpretar os Resultados
A animação mostra como a distribuição beta é atualizada à medida que novos dados são observados. A linha tracejada preta representa a verdadeira probabilidade de sucesso (ou seja, a probabilidade da moeda cair com a face "cara" para cima). À medida que a animação progride, vemos que a distribuição beta começa com um pico na probabilidade a priori de sucesso (0.7) e gradualmente se desloca em direção à verdadeira probabilidade de sucesso à medida que mais dados são observados.
Resumo
Neste laboratório, usamos o Matplotlib para criar uma animação que demonstra a atualização bayesiana. Definimos uma função para calcular a PDF (Função Densidade de Probabilidade) da distribuição beta e uma classe para atualizar a distribuição beta à medida que novos dados são observados. Em seguida, usamos a classe FuncAnimation do Matplotlib para criar a animação e interpretar os resultados.