O que são redes bayesianas?
Redes bayesianas são modelos gráficos probabilísticos que representam relações de dependência entre variáveis. Cada nó é uma variável aleatória, e cada aresta direcionada indica influência causal ou condicional. A estrutura é um grafo acíclico direcionado (DAG), que proíbe ciclos de dependência. Cada nó possui uma tabela de probabilidade condicional (CPT) dado seus pais. A rede codifica a distribuição conjunta de todas as variáveis de forma fatorada. Isso reduz drasticamente o número de parâmetros necessários para modelar sistemas complexos. Por exemplo, com 10 variáveis binárias, a tabela conjunta teria 2^10 = 1024 valores. Com uma rede esparsa, esse número cai para poucas dezenas. Portanto, redes bayesianas são eficientes e interpretáveis para inferência sob incerteza.
Características fundamentais
As redes bayesianas possuem três características principais que as definem. Primeiro, elas são baseadas no teorema de Bayes para atualização de crenças. Segundo, a independência condicional é codificada pela estrutura do grafo. Dado seus pais, cada nó é independente de todos os seus não-descendentes. Terceiro, a inferência pode ser exata (por eliminação de variáveis) ou aproximada (MCMC). Elas também permitem aprendizado estrutural (descobrir o grafo) e paramétrico (estimar CPTs). Além disso, lidam naturalmente com dados faltantes usando expectativa-maximização. Redes bayesianas são robustas a overfitting quando prioris são usados.
Vantagens e aplicações típicas
A principal vantagem é a capacidade de raciocínio causal e diagnóstico. Elas são usadas em sistemas de suporte à decisão médica (ex.: diagnóstico de doenças). Também são aplicadas em detecção de falhas, mineração de dados e bioinformática. Outra vantagem é a transparência: cada aresta tem uma interpretação clara. Contudo, aprender a estrutura ótima é um problema NP-difícil em geral. Ainda assim, heurísticas como busca gulosa ou algoritmos genéticos são usadas.
A construção de uma rede bayesiana começa com a definição das variáveis relevantes. Em seguida, o especialista ou algoritmo define as arestas baseadas em dependências. Cada nó tem uma CPT que especifica P(nó | pais) para todas as combinações. A distribuição conjunta é o produto de todas as CPTs: P(X₁,…,Xₙ) = ∏ P(Xᵢ | pais). A inferência responde a perguntas como: qual a probabilidade de doença dado um sintoma? Isso é feito por propagação de crenças em redes com estrutura de árvore. Para redes gerais, usa-se o algoritmo de eliminação de variáveis ou amostragem. A amostragem de Gibbs é comum para aproximações quando o grafo é grande. Redes bayesianas dinâmicas estendem o modelo para séries temporais. Elas incluem arestas entre estados consecutivos, como em filtros de Kalman. Aprendizado de estrutura busca o DAG que melhor explica os dados observados. Medidas como BIC (Bayesian Information Criterion) ou AIC são usadas. A busca é feita por operadores de adição, remoção ou inversão de arestas. Assim, redes bayesianas são ferramentas versáteis para modelagem probabilística.
Um exemplo clássico é a rede de diagnóstico de pneumonia com variáveis: Febre, Tosse, Raio-X, e Doença. A febre e a tosse são sintomas que podem ser causados pela pneumonia. O raio-X é um teste que também depende da doença. A rede permite calcular P(Pneumonia | Febre=True, Tosse=True, Raio-X=Anormal).
Enunciado do exemplo clássico
Implemente uma rede bayesiana para o problema “Chuva” e “Gramado Molhado”. Variáveis: Chuva (R), Irrigação (I), Gramado Molhado (G), e Tempo Nublado (N). Relações: N influencia R; R e I influenciam G (cada um independente). Defina probabilidades condicionais manualmente. Calcule P(G | R=True) e P(R | G=True, I=False) usando inferência exata. Plote a estrutura da rede (grafo) e uma tabela com as probabilidades solicitadas.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
import numpy as np import matplotlib.pyplot as plt import networkx as nx # Definição da rede bayesiana (estrutura e CPTs) # Nós: N (Nublado), R (Chuva), I (Irrigação), G (Gramado Molhado) # Todos binários: 0 = Falso, 1 = Verdadeiro # Prior: P(N) P_N = {0: 0.4, 1: 0.6} # Condicional: P(R | N) P_R_dado_N = { (0,0): 0.1, (0,1): 0.9, # N=0, R=0 e R=1 (1,0): 0.3, (1,1): 0.7 # N=1, R=0 e R=1 } # Prior: P(I) P_I = {0: 0.5, 1: 0.5} # Condicional: P(G | R, I) P_G_dado_R_I = { (0,0,0): 0.1, (0,0,1): 0.9, # R=0, I=0, G=0 e G=1 (0,1,0): 0.2, (0,1,1): 0.8, # R=0, I=1 (1,0,0): 0.3, (1,0,1): 0.7, # R=1, I=0 (1,1,0): 0.4, (1,1,1): 0.6 # R=1, I=1 } # Função de inferência por enumeração (exata) def inferir(variavel, evidencia): # Lista de todas as variáveis na ordem: N, R, I, G # evidencia: dicionário {var: valor} # Retorna P(variavel | evidencia) vars_ = ['N', 'R', 'I', 'G'] # Gerar todas as combinações (0/1) comb = [(n,r,i,g) for n in (0,1) for r in (0,1) for i in (0,1) for g in (0,1)] prob_total = {0: 0.0, 1: 0.0} for n,r,i,g in comb: # Verificar evidência ok = True for v, val in evidencia.items(): if v == 'N' and n != val: ok = False if v == 'R' and r != val: ok = False if v == 'I' and i != val: ok = False if v == 'G' and g != val: ok = False if not ok: continue # Probabilidade conjunta p = P_N[n] * P_R_dado_N[(n,r)] * P_I[i] * P_G_dado_R_I[(r,i,g)] # Se a variável alvo é N if variavel == 'N': prob_total[n] += p elif variavel == 'R': prob_total[r] += p elif variavel == 'I': prob_total[i] += p elif variavel == 'G': prob_total[g] += p # Normalizar para somar 1 soma = sum(prob_total.values()) if soma > 0: prob_total[0] /= soma prob_total[1] /= soma return prob_total # Calcular P(G | R=True) P_G_dado_R = inferir('G', {'R': 1}) print(f"P(G | R=True): P(G=0)={P_G_dado_R[0]:.4f}, P(G=1)={P_G_dado_R[1]:.4f}") # Calcular P(R | G=True, I=False) P_R_dado_G_I = inferir('R', {'G': 1, 'I': 0}) print(f"P(R | G=True, I=False): P(R=0)={P_R_dado_G_I[0]:.4f}, P(R=1)={P_R_dado_G_I[1]:.4f}") # Plotar estrutura da rede G = nx.DiGraph() G.add_edges_from([('N', 'R'), ('R', 'G'), ('I', 'G')]) pos = {'N': (0, 1), 'R': (1, 1), 'I': (1, 0), 'G': (2, 0.5)} plt.figure(figsize=(12, 4)) plt.subplot(1, 2, 1) nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, font_size=12, font_weight='bold', arrowsize=20, edge_color='gray', width=2) plt.title('Estrutura da Rede Bayesiana\n(Chuva e Gramado Molhado)') plt.subplot(1, 2, 2) # Tabela de probabilidades calculadas dados_tabela = [ ['P(G=1 | R=1)', f'{P_G_dado_R[1]:.4f}'], ['P(G=0 | R=1)', f'{P_G_dado_R[0]:.4f}'], ['P(R=1 | G=1, I=0)', f'{P_R_dado_G_I[1]:.4f}'], ['P(R=0 | G=1, I=0)', f'{P_R_dado_G_I[0]:.4f}'] ] plt.axis('off') plt.table(cellText=dados_tabela, colLabels=['Consulta', 'Probabilidade'], loc='center', cellLoc='center', colWidths=[0.6, 0.3]) plt.title('Resultados da Inferência') plt.tight_layout() plt.show() |
Este código implementa uma rede bayesiana manual com inferência por enumeração. A estrutura do grafo mostra as dependências causais entre as variáveis. Os resultados da inferência respondem perguntas condicionais diretamente. A enumeração é exata para redes pequenas, mas escala mal para muitas variáveis. Para iniciantes, este exemplo demonstra a mecânica fundamental das redes bayesianas. Elas são, portanto, uma ferramenta poderosa e didática para raciocínio probabilístico.