Esercizio - Filtraggio e smoothing nell'ombrello con la nuova versione di pomegranate (materiale supplementare del laboratorio 6)
Testo (materiale supplementare del laboratorio 6, Additional materials - implementation with new version of pomegranate, corso di Intelligenza Artificiale, Ing. dell'Informazione UniPD). Il materiale ha due parti sullo stesso mondo dell'ombrello (Ragionamento probabilistico nel tempo - catene di Markov, HMM, filtraggio e smoothingPer ragionare sul tempo il mondo è una sequenza di istanti: stato nascosto $X_t$ ed evidenza osservata $E_t$. Ipotesi di Markov del primo ordine $P(X_t\mid X_{0:t-1})=P(X_t\mid X_{t-1})$ (modello di transizione) e ipotesi del sensore $P(E_t\mid X_{0:t},E_{1:t-1})=P(E_t\mid X_t)$ (modello del sensore): congiunta $P(X_0)\prod_t P(X_t\mid X_{t-1})P(E_t\mid X_t)$. Un HMM ha uno stato discreto a $S$ valori: transizione = matrice $\mathbf T$ ($T_{ij}=P(X_t=j\mid X_{t-1}=i)$), sensore = matrici diagonali $\mathbf O_t$. Compiti: filtraggio $P(X_t\mid e_{1:t})$, predizione $P(X_{t+k}\mid e_{1:t})$, smoothing $P(X_{t-k}\mid e_{1:t})$, spiegazione più probabile $\arg\max P(x_{1:t}\mid e_{1:t})$. Filtraggio ricorsivo: $\mathbf f_t=\alpha,\mathbf O_t\mathbf T^\top\mathbf f_{t-1}$ (predizione, poi aggiornamento). Mondo dell'ombrello: $\mathbf f_1=\langle0{,}818;\ 0{,}182\rangle$, $\mathbf f_2=\langle0{,}883;\ 0{,}117\rangle$. Senza normalizzare, $\mathbf s_t=\mathbf O_t\mathbf T^\top\mathbf s_{t-1}$ dà la verosimiglianza $P(e_{1:t})$.Ragionamento probabilistico nel tempo - catene di Markov, HMM, filtraggio e smoothing →): , , , , .
- Esempio : foglio di calcolo per il filtraggio. Un foglio (
Umbrella.xlsx) modella i primi due giorni. In alto la probabilità di pioggia del giorno è il prior; in basso le tabelle del modello di transizione e del sensore. La probabilità predetta per il giorno si calcola dal giorno e dal modello di transizione; la probabilità filtrata del giorno combina la predetta, il modello del sensore e l'informazione sull'ombrello. Esistono due versioni della filtrata: i valori grezzi del calcolo e quelli normalizzati (grezzi scalati perché sommino a ). Nel foglio la probabilità di vale e quella di vale : cosa succede se non si vede l'ombrello (probabilità di , di )? E se non si ha alcuna informazione (probabilità e )? La colonna del giorno ripete i calcoli del giorno partendo dal risultato normalizzato del giorno : la predetta del giorno applica il modello di transizione alla filtrata normalizzata del giorno . Osservare cosa accade al variare delle probabilità di ombrello nei giorni e . - Esempio :
pomegranate(nuova versione) per predizione e filtraggio. Si risolvono reti bayesiane (non dinamiche), quindi il modello è srotolato fino alla profondità voluta. Si chiede la probabilità di pioggia nei giorni e senza evidenza, poi con ombrello al giorno , poi con ombrelli nei giorni e (con un terzo giorno aggiunto).
Parte 1: il foglio di calcolo
Per ogni giorno: predetta ; grezza , con la verosimiglianza dell'evidenza data la pioggia; normalizzata . Se la probabilità di vedere l'ombrello è (un'evidenza "morbida"), .
| ombrello giorno | predetta | grezza | filtrata | predetta | grezza () | filtrata |
|---|---|---|---|---|---|---|
| visto () | ||||||
| non visto () | ||||||
| nessuna informazione () |
Spiegazioni:
- Non visto: gli ombrelli sono più probabili con la pioggia ( contro ), quindi la loro assenza (verosimiglianza contro ) fa scendere la pioggia da a .
- Nessuna informazione: la verosimiglianza è uguale ( e ) per i due stati: la grezza è solo il predetto scalato, la normalizzazione la riporta a e la filtrata coincide con la predetta. Non si impara nulla.
- Giorno : si ripete esattamente lo stesso calcolo (il modello è modulare) partendo dalla filtrata normalizzata del giorno .
I valori sono stati ricalcolati in Python con la ricorsione del filtraggio (stessi numeri della tabella); i valori di per e per ( e ) coincidono con quelli di Esercizio - Filtraggio nell'ombrello con pomegranate (laboratorio 6).
Parte 2: pomegranate (nuova versione)
Nel codice del corso le variabili sono e ; i valori sono (no) e (sì), e le tabelle condizionali hanno la forma , riga = valore del genitore.
from pomegranate.bayesian_network import BayesianNetwork
from pomegranate.distributions import Categorical, ConditionalCategorical
Rain0 = Categorical([[0.5, 0.5]]) # P(Rain0)
Rain1 = ConditionalCategorical([[[0.7, 0.3], # P(Rain1 | Rain0 = n)
[0.3, 0.7]]]) # P(Rain1 | Rain0 = y)
Rain2 = ConditionalCategorical([[[0.7, 0.3], [0.3, 0.7]]])
Umbrella1 = ConditionalCategorical([[[0.8, 0.2], # P(Umbrella1 | Rain1 = n)
[0.1, 0.9]]]) # P(Umbrella1 | Rain1 = y)
Umbrella2 = ConditionalCategorical([[[0.8, 0.2], [0.1, 0.9]]])
model = BayesianNetwork()
model.add_distributions([Rain0, Rain1, Umbrella1, Rain2, Umbrella2])
model.add_edge(Rain0, Rain1); model.add_edge(Rain1, Umbrella1)
model.add_edge(Rain1, Rain2); model.add_edge(Rain2, Umbrella2)Le query con evidenza passano un tensore con nan per i nodi non osservati, nell'ordine [Rain0, Rain1, Umbrella1, Rain2, Umbrella2]; il risultato è, per ogni nodo, la distribuzione a posteriori.
- Nessuna evidenza.
P(~Rain1) = 0.5,P(Rain1) = 0.5, e lo stesso perRain2: prima di vedere ombrelli non si può dire nulla sulla pioggia (la distribuzione rappresenta l'ignoranza, stazionaria per la transizione simmetrica). - Ombrello al giorno (
scenario = [[nan, nan, 1, nan, nan]]): : (filtrata, ); : (predizione, ).pomegranatepropaga l'evidenza in tutta la rete, quindi calcola anche : , cioè la probabilità smoothed di pioggia al giorno , benché non sia stato osservato nulla quel giorno. È il messaggio all'indietro: un ombrello al giorno rende più probabile la pioggia anche il giorno prima (per la persistenza). A mano: con , normalizzato con il prior: . - Un terzo giorno e ombrelli nei giorni e . Si aggiunge (
Rain3 = ConditionalCategorical(...), arco ), si creaBayesianNetwork(nodi, archi)escenario = [[nan, nan, 1, nan, 1, nan]]: : e : . Il valore di è quello filtrato () perché non ha evidenza: i figli senza evidenza non influenzano. Quello di è lo smoothing: con , (stesso numero di per la simmetria di e di nei due giorni).
Nota. pomegranate non esegue il calcolo del corso (forward-backward): calcola direttamente la probabilità a posteriori di ogni variabile nascosta data l'evidenza, quindi restituisce in automatico gli smoothing di tutti i giorni precedenti all'ultima evidenza (e anche le predizioni per i giorni successivi).
Verifica con numpy
Tutti i numeri sono stati ricalcolati in due modi, con codice proprio: per enumerazione sulla rete srotolata e con forward-backward (Ragionamento probabilistico nel tempo - catene di Markov, HMM, filtraggio e smoothingPer ragionare sul tempo il mondo è una sequenza di istanti: stato nascosto $X_t$ ed evidenza osservata $E_t$. Ipotesi di Markov del primo ordine $P(X_t\mid X_{0:t-1})=P(X_t\mid X_{t-1})$ (modello di transizione) e ipotesi del sensore $P(E_t\mid X_{0:t},E_{1:t-1})=P(E_t\mid X_t)$ (modello del sensore): congiunta $P(X_0)\prod_t P(X_t\mid X_{t-1})P(E_t\mid X_t)$. Un HMM ha uno stato discreto a $S$ valori: transizione = matrice $\mathbf T$ ($T_{ij}=P(X_t=j\mid X_{t-1}=i)$), sensore = matrici diagonali $\mathbf O_t$. Compiti: filtraggio $P(X_t\mid e_{1:t})$, predizione $P(X_{t+k}\mid e_{1:t})$, smoothing $P(X_{t-k}\mid e_{1:t})$, spiegazione più probabile $\arg\max P(x_{1:t}\mid e_{1:t})$. Filtraggio ricorsivo: $\mathbf f_t=\alpha,\mathbf O_t\mathbf T^\top\mathbf f_{t-1}$ (predizione, poi aggiornamento). Mondo dell'ombrello: $\mathbf f_1=\langle0{,}818;\ 0{,}182\rangle$, $\mathbf f_2=\langle0{,}883;\ 0{,}117\rangle$. Senza normalizzare, $\mathbf s_t=\mathbf O_t\mathbf T^\top\mathbf s_{t-1}$ dà la verosimiglianza $P(e_{1:t})$.Ragionamento probabilistico nel tempo - catene di Markov, HMM, filtraggio e smoothing →):
| scenario | ||||
|---|---|---|---|---|
| nessuna evidenza | ||||
(valori di per ogni nodo, arrotondati; coincidono con 0.18/0.82, 0.37/0.63 e 0.12/0.88 stampati dal corso).
import numpy as np
T = np.array([[0.7, 0.3], [0.3, 0.7]])
O = {True: np.diag([0.9, 0.2]), False: np.diag([0.1, 0.8])}
f0 = np.array([0.5, 0.5])
def filtro(f, e):
v = O[e] @ T.T @ f
return v / v.sum()
f1 = filtro(f0, True) # filtrata giorno 1 (u1)
f2 = filtro(f1, True) # filtrata giorno 2 (u1, u2)
b = T @ O[True] @ np.ones(2) # messaggio all'indietro b_{2:2} = <0.69, 0.41>
s1 = f1 * b; s1 /= s1.sum() # smoothing del giorno 1
print(f1, f2, s1)Output: [0.818 0.182] [0.883 0.117] [0.883 0.117].
Versione ripasso
- Foglio di calcolo: predetta ; grezza ; filtrata . Il giorno riparte dalla filtrata normalizzata del giorno (calcolo modulare).
- Ombrello visto: , . Non visto al giorno 1: , (con ) . Nessuna informazione: (la filtrata coincide con la predetta).
pomegranate: reti statiche, modello srotolato; tabelle con riga = valore del genitore,nan= non osservato. Nessuna evidenza: ovunque. : (filtrata), (predizione), (smoothing).- Smoothing (forward-backward, con Ragionamento probabilistico nel tempo - catene di Markov, HMM, filtraggio e smoothing →): dà , (filtrata, nessuna evidenza sul giorno ).
- Differenza:
pomegranatecalcola la posteriori di ogni nodo (non il forward-backward) e dà gli smoothing in automatico. - Errori tipici: pensare che non cambi senza evidenza su quel giorno; confondere filtrata e predetta; usare le grezze non normalizzate al giorno successivo.
- Tabella del foglio (pioggia): visto predetta ; non visto ; nessuna informazione . Evidenza morbida con probabilità di ombrello: .
- Ombrello non visto: verosimiglianza contro , la pioggia scende da a . Nessuna informazione: verosimiglianze uguali, la filtrata coincide con la predetta.
- Smoothing a mano: ; con : (stesso valore della predizione di per la simmetria di ).
- Tabella delle posteriori (pioggia): nessuna evidenza ovunque; : , , ; : , , , (predizione).
- Codice numpy:
f1 = filtro(f0, True),f2 = filtro(f1, True),b = T @ O[True] @ np.ones(2),s1 = f1 * bnormalizzato:[0.883 0.117].