76  La divergenza di Kullback-Leibler

“La divergenza di Kullback-Leibler non è una vera e propria distanza, ma una misura di informazione relativa. È il prezzo che paghiamo in termini di informazione quando sostituiamo la distribuzione ‘vera’ con una sua approssimazione.”

Christopher M. Bishop, Autore di “Pattern Recognition and Machine Learning”

Introduzione

Nel capitolo precedente abbiamo introdotto l’entropia come misura dell’incertezza di una distribuzione di probabilità. Ora facciamo un passo avanti: invece di misurare l’incertezza di una sola distribuzione, vogliamo misurare quanto una distribuzione differisce da un’altra. Uno strumento cruciale per rispondere a questa domanda è la divergenza di Kullback-Leibler (Kullback & Leibler, 1951), spesso abbreviata come divergenza KL (\(D_{\text{KL}}\)). Essa misura quanto si perde in precisione o efficienza se si utilizza un modello errato per descrivere la realtà.

Panoramica del capitolo

  • Cos’è la divergenza KL e da dove nasce.
  • Come si collega al concetto di entropia.
  • Perché è utile nella scelta tra modelli statistici.
  • Come calcolarla e interpretarla, anche con esempi in R.

  • Per comprendere appieno questo capitolo, dovresti aver già appreso i concetti di entropia e informazione di Shannon (Capitolo 75).
here::here("code", "_common.R") |> 
  source()

# Funzione per il calcolo dei termini della divergenza KL
kl_terms <- function(p, q) {
  stopifnot(length(p) == length(q))
  non_zero <- p > 0 & q > 0
  p <- p[non_zero]
  q <- q[non_zero]
  term <- p * log2(p / q)
  data.frame(x = seq_along(p), p = p, q = q, term = term)
}

# Funzione compatta per il valore totale
kl_divergence <- function(p, q) {
  sum(kl_terms(p, q)$term)
}

# Entropia vera (in bit)
entropy <- function(p) {
  p <- p[p > 0]
  -sum(p * log2(p))
}

# Entropia incrociata (in bit)
cross_entropy <- function(p, q) {
  non_zero <- p > 0 & q > 0
  p <- p[non_zero]
  q <- q[non_zero]
  -sum(p * log2(q))
}

76.1 La generalizzabilità dei modelli e il metodo scientifico

Uno degli obiettivi fondamentali della scienza è la generalizzabilità: un buon modello non deve spiegare solo i dati che abbiamo già, ma anche prevedere correttamente nuovi dati che potremmo raccogliere in futuro. Un modello troppo semplice rischia di sotto-adattarsi ai dati (underfitting), perdendo informazioni importanti; uno troppo complesso rischia di sovra-adattarsi (overfitting), confondendo il rumore casuale con segnali reali. Il problema della generalizzabilità è quindi centrale nel metodo scientifico: vogliamo modelli abbastanza flessibili da catturare i pattern reali, ma non così flessibili da adattarsi anche a variazioni casuali.

Nell’approccio bayesiano, come osserva McElreath (2020), la scelta di un modello implica trovare un equilibrio tra due esigenze:

  1. accuratezza predittiva – il modello deve produrre previsioni affidabili sui dati futuri;
  2. controllo della complessità – il modello non deve introdurre più complessità di quanta ne richieda il fenomeno studiato.

Questo principio è vicino a quello noto come rasoio di Occam: tra due modelli che spiegano altrettanto bene i dati, preferiamo quello più semplice. La differenza è che, in ambito bayesiano, questa preferenza non è solo una regola intuitiva, ma può essere formalizzata in termini quantitativi, misurando quanta “informazione in più” dobbiamo spendere quando il nostro modello si discosta dalla realtà. Questa misura è data dalla divergenza di Kullback–Leibler, che vedremo nel seguito.

76.2 L’entropia relativa

Nel Capitolo 75 abbiamo visto che l’entropia \(H(P)\) misura la lunghezza media del codice più efficiente per descrivere una distribuzione di probabilità \(P\). Ora estendiamo il ragionamento al confronto tra due distribuzioni:

  • \(P\) = distribuzione vera dei dati, cioè quella che genera realmente gli eventi;
  • \(Q\) = distribuzione approssimata, cioè quella fornita dal modello.

La divergenza di Kullback–Leibler, \(D_{\text{KL}}(P \parallel Q)\), risponde alla seguente domanda:

in media, quanta informazione in più dobbiamo spendere se usiamo \(Q\) invece di \(P\) per descrivere i dati?

Dal punto di vista della codifica, questa quantità rappresenta l’aumento medio della lunghezza del codice quando si usa un modello impreciso.

76.2.1 Definizione formale

Per una variabile casuale discreta \(X\):

\[ D_{\text{KL}}(P \parallel Q) = \sum_x p(x) \log_2 \frac{p(x)}{q(x)} \tag{76.1}\]

che può essere riscritta come:

\[ D_{\text{KL}}(P \parallel Q) = \sum_x p(x) \left[ \log_2 p(x) - \log_2 q(x) \right]. \tag{76.2}\]

Questa forma mette in evidenza un’interpretazione intuitiva:

  • \(\log_2 p(x)\) è l’informazione (in bit) associata all’esito \(x\) secondo la distribuzione vera \(P\);
  • \(\log_2 q(x)\) è l’informazione associata allo stesso esito secondo il modello \(Q\);
  • la differenza \(\log_2 p(x) - \log_2 q(x)\) indica, per quell’esito, quanto il modello \(Q\) sottostima o sovrastima la sorpresa rispetto a \(P\);
  • moltiplicando per \(p(x)\) e sommando su tutti gli esiti otteniamo una media ponderata (pesata in base a quanto l’esito è probabile nella realtà).

In sintesi, \(D_{\text{KL}}(P \parallel Q)\) è la perdita media di efficienza quando descriviamo la variabile \(X\) con la distribuzione approssimata \(Q\) invece che con la distribuzione vera \(P\).

Se \(P = Q\) la divergenza è 0, perché non vi è alcuna perdita. Quanto più \(Q\) si discosta da \(P\), tanto più grande sarà la divergenza, segnalando un “costo informativo” maggiore.

Supponiamo che la variabile casuale \(X\) possa assumere tre valori: A, B e C.

La distribuzione vera (\(P\)) è:

x \(p(x)\)
A 0.5
B 0.3
C 0.2

Il modello approssimante (\(Q\)) è:

x \(q(x)\)
A 0.4
B 0.4
C 0.2

Calcoliamo la divergenza KL:

\[ \begin{aligned} D_{\text{KL}}(P \parallel Q) &= 0.5 \log_2\!\left(\frac{0.5}{0.4}\right) + 0.3 \log_2\!\left(\frac{0.3}{0.4}\right) + 0.2 \log_2\!\left(\frac{0.2}{0.2}\right) \\[4pt] &= 0.5 \log_2(1.25) + 0.3 \log_2(0.75) + 0.2 \log_2(1) \\[4pt] &\approx 0.160 - 0.125 + 0 \\[4pt] &= 0.035 \ \text{bit}. \end{aligned} \]

Interpretazione

  • Per A, il modello \(Q\) sottostima la probabilità vera (0.4 invece di 0.5). Questo comporta un costo informativo positivo: il codice dovrà essere leggermente più lungo rispetto all’uso di \(P\).
  • Per B, il modello \(Q\) sovrastima la probabilità vera (0.4 invece di 0.3). Qui il costo informativo è negativo, ma va pesato dal fatto che nella divergenza KL la somma è pesata secondo \(P\), e dunque conta di più la stima errata sugli eventi più probabili.
  • Per C, il modello è perfetto (\(p(x) = q(x)\)) e il contributo alla divergenza è nullo.

Il risultato complessivo, 0.035 bit per evento, è molto piccolo: significa che, in media, usando \(Q\) al posto di \(P\) spenderemmo appena 0.035 bit di informazione in più per descrivere ogni osservazione. Le due distribuzioni sono quindi molto simili, ma la divergenza KL rileva comunque la differenza residua.

Supponiamo che la variabile casuale \(X\) possa assumere tre valori: x = 1, 2, 3.

  • Distribuzione vera (\(P\)): \([0.1, \ 0.6, \ 0.3]\)
  • Distribuzione approssimata (\(Q\)): \([0.2, \ 0.5, \ 0.3]\)

Calcoliamo la divergenza KL secondo la formula ?eq-kl-def:

# Definizione delle distribuzioni
P <- c(0.1, 0.6, 0.3)  # distribuzione vera
Q <- c(0.2, 0.5, 0.3)  # distribuzione approssimata
# Calcolo dei contributi per ciascun esito
df_kl_terms <- kl_terms(P, Q)
print(df_kl_terms)
#>   x   p   q    term
#> 1 1 0.1 0.2 -0.1000
#> 2 2 0.6 0.5  0.1578
#> 3 3 0.3 0.3  0.0000
# Visualizzazione dei contributi
ggplot(df_kl_terms, aes(x = factor(x), y = term)) +
  geom_col(fill = "steelblue") +
  geom_hline(yintercept = 0, color = "black", linewidth = 0.3) +
  labs(
    x = "Valori possibili di X",
    y = "Contributo alla Divergenza KL",
    title = "Contributo di ciascun esito alla Divergenza KL"
  )

Infine, sommiamo i contributi per ottenere la divergenza totale:

KL_total <- sum(df_kl_terms$term)
cat(sprintf("Divergenza KL da P a Q: %.4f bit\n", KL_total))
#> Divergenza KL da P a Q: 0.0578 bit

Interpretazione

  • Esito 1 (\(p=0.1\), \(q=0.2\)) – Il modello \(Q\) sovrastima un evento raro. Il contributo alla divergenza è negativo, ma l’impatto è ridotto perché l’evento è poco probabile nella realtà (\(p\) piccolo).
  • Esito 2 (\(p=0.6\), \(q=0.5\)) – Il modello sottostima l’evento più frequente. Poiché \(p\) è alto, questa sottostima ha un peso maggiore nella media ponderata, generando il contributo positivo più grande.
  • Esito 3 (\(p=0.3\), \(q=0.3\)) – Qui il modello è perfetto: \(p(x) = q(x)\), quindi il contributo alla divergenza è zero.

Il valore complessivo di \(D_{\text{KL}}\) è la somma di questi contributi: rappresenta la perdita media di efficienza (in bit per evento) quando si usa \(Q\) al posto di \(P\).

In questo caso, il risultato indica che usare \(Q\) comporta una leggera inefficienza: la codifica o le previsioni richiedono, in media, un po’ più informazione di quanto sarebbe necessario usando la distribuzione vera.

76.2.2 Legame con l’entropia e l’entropia incrociata

La divergenza di Kullback–Leibler può essere riscritta come differenza tra entropia incrociata e entropia vera:

\[ D_{\text{KL}}(P \parallel Q) = H(P, Q) - H(P), \tag{76.3}\]

dove:

  • \(H(P)\) è l’entropia della distribuzione vera \(P\) (incertezza media/lunghezza media del codice ottimale quando conosciamo la distribuzione corretta);
  • \(H(P, Q)\) è l’entropia incrociata, cioè l’incertezza media se codifichiamo dati generati da \(P\) utilizzando un codice ottimizzato per \(Q\):

\[ H(P, Q) = -\sum_x p(x)\log_2 q(x). \tag{76.4}\]

Intuizione. Con questa forma, \(D_{\text{KL}}\) è la sorpresa extra media (o costo informativo in bit per evento) che paghiamo quando usiamo il modello approssimato \(Q\) al posto della distribuzione vera \(P\). Poiché \(H(P)\) non dipende dal modello, minimizzare \(D_{\text{KL}}\) equivale a minimizzare \(H(P,Q)\).

Perché serve per ELPD e LOO

Criteri predittivi come ELPD e LOO stimano, in media, la stessa quantità di cui vogliamo minimizzare il valore: l’entropia incrociata \(H(P,Q)\). Per questo, massimizzare ELPD (o ridurre la perdita di log-verosimiglianza predittiva) è un modo pratico per avvicinare \(Q\) a \(P\), ossia per ridurre indirettamente \(D_{\text{KL}}(P\parallel Q)\).

Utilizziamo le funzioni definite sopra (entropy(), cross_entropy(), kl_divergence()) sullo stesso esempio discusso in precedenza:

# Esempio: distribuzione vera P e modello Q
P <- c(0.1, 0.6, 0.3)
Q <- c(0.2, 0.5, 0.3)

H_P   <- entropy(P)           # H(P)
H_PQ  <- cross_entropy(P, Q)  # H(P,Q)
DKL   <- kl_divergence(P, Q)  # D_KL(P||Q)

cat(sprintf("H(P)    = %.4f bit\n", H_P))
#> H(P)    = 1.2955 bit
cat(sprintf("H(P,Q)  = %.4f bit\n", H_PQ))
#> H(P,Q)  = 1.3533 bit
cat(sprintf("H(P,Q)-H(P) = %.4f bit (D_KL)\n", H_PQ - H_P))
#> H(P,Q)-H(P) = 0.0578 bit (D_KL)
cat(sprintf("D_KL(P||Q)  = %.4f bit (controllo)\n", DKL))
#> D_KL(P||Q)  = 0.0578 bit (controllo)

Interpretazione

  • \(H(P)\) è il limite inferiore: la miglior compressione ottenibile conoscendo la verità (\(P\)).
  • \(H(P,Q)\) è la compressione che otterremmo usando il modello (\(Q\)).
  • La loro differenza è esattamente \(D_{\text{KL}}(P\parallel Q)\): la quantità di informazione “sprecata” in media per evento usando \(Q\) al posto di \(P\).

In due esempi successivi rendiamo \(Q\) sempre più diverso da \(P\) e osserviamo come cambiano entropia incrociata e divergenza KL.

# Distribuzione vera fissata
P  <- c(0.1, 0.6, 0.3)
H_P <- entropy(P)  # costante rispetto al modello

# Due modelli: uno moderatamente errato (Q1), uno molto errato (Q2)
Q1 <- c(0.35, 0.30, 0.35)
Q2 <- c(0.60, 0.30, 0.10)

# Calcolo di entropia incrociata e divergenza KL
H_PQ1 <- cross_entropy(P, Q1)
H_PQ2 <- cross_entropy(P, Q2)

KL1 <- kl_divergence(P, Q1)
KL2 <- kl_divergence(P, Q2)

cat(sprintf("H(P)     = %.4f bit (fissa)\n", H_P))
#> H(P)     = 1.2955 bit (fissa)
cat(sprintf("H(P,Q1)  = %.4f bit   -> D_KL(P||Q1) = %.4f bit\n", H_PQ1, KL1))
#> H(P,Q1)  = 1.6480 bit   -> D_KL(P||Q1) = 0.3525 bit
cat(sprintf("H(P,Q2)  = %.4f bit   -> D_KL(P||Q2) = %.4f bit\n", H_PQ2, KL2))
#> H(P,Q2)  = 2.1125 bit   -> D_KL(P||Q2) = 0.8170 bit

Interpretazione

Poiché \(H(P)\) non cambia, quando \(Q\) si allontana da \(P\) cresce \(H(P,Q)\) e, di conseguenza, aumenta

\[ D_{\text{KL}}(P \parallel Q) = H(P, Q) - H(P) . \]

  • Q1: il modello redistribuisce massa probabilistica, sottostimando l’esito più probabile e sovrastimando gli altri. Gli errori sugli esiti che \(P\) considera frequenti pesano di più nella media, aumentando \(H(P,Q1)\) e quindi \(D_{\text{KL}}\).
  • Q2: l’errore è estremo: la probabilità più alta viene assegnata all’esito meno probabile secondo \(P\). I contributi positivi (sottostima degli esiti comuni) dominano, facendo crescere molto \(D_{\text{KL}}\).

Questo esempio mostra che minimizzare \(H(P,Q)\) (e quindi \(D_{\text{KL}}\)) significa allineare il più possibile le probabilità del modello con quelle “vere”, soprattutto per gli esiti a cui \(P\) assegna più massa.

Partiamo dalla definizione come differenza tra entropia incrociata ed entropia vera:

\[ D_{\text{KL}}(P \parallel Q) = H(P, Q) - H(P). \]

Sostituendo: \[ H(P,Q) = -\sum_x p(x) \log_2 q(x), \quad H(P) = -\sum_x p(x) \log_2 p(x), \]

ottieni:

\[ D_{\text{KL}}(P \parallel Q) = \left[ - \sum_x p(x) \log_2 q(x) \right] - \left[ - \sum_x p(x) \log_2 p(x) \right]. \]

Eliminando i segni negativi:

\[ D_{\text{KL}}(P \parallel Q) = \sum_x p(x) \log_2 p(x) - \sum_x p(x) \log_2 q(x). \]

Raccogliendo in un’unica somma:

\[ D_{\text{KL}}(P \parallel Q) = \sum_x p(x) \left[ \log_2 p(x) - \log_2 q(x) \right]. \]

Applicando la proprietà dei logaritmi:

\[ D_{\text{KL}}(P \parallel Q) = \sum_x p(x) \log_2 \frac{p(x)}{q(x)}. \]

Interpretazione: questa è la forma esplicita più usata della \(D_{\text{KL}}\). Mostra chiaramente che si tratta di una media ponderata secondo \(P\) della differenza di informazione tra \(P\) e \(Q\) per ciascun esito \(x\).

76.2.3 Interpretazione della divergenza KL

La divergenza \(D_{\text{KL}}(P \parallel Q)\) misura l’inefficienza media che si introduce quando si usa la distribuzione \(Q\) per descrivere dati che in realtà seguono \(P\). In termini informativi, rappresenta il costo aggiuntivo di sorpresa: quanti bit in più, in media, servono per codificare gli eventi generati da \(P\) se utilizziamo un codice ottimizzato per \(Q\) invece che per \(P\).

Questa quantità:

  • è sempre non negativa: il modello vero (\(P\)) non può mai essere peggiore, in media, del modello approssimato (\(Q\));
  • è asimmetrica: \(D_{\text{KL}}(P \parallel Q) \neq D\_{\text{KL}}(Q \parallel P)\). L’ordine è importante: invertire \(P\) e \(Q\) cambia il significato della misura, perché cambia quale distribuzione stiamo trattando come “vera”.

Per questo motivo, la divergenza KL non è una “distanza” in senso geometrico, ma una misura direzionale di perdita di informazione o di inefficienza di codifica.

76.2.4 Proprietà fondamentali della divergenza KL

  • Non-negatività: \(D_{\text{KL}}(P \parallel Q) \geq 0\) per ogni coppia di distribuzioni \(P\) e \(Q\). Il valore minimo (0) si ottiene se e solo se \(P = Q\).

  • Asimmetria: \(D_{\text{KL}}(P \parallel Q) \neq D\_{\text{KL}}(Q \parallel P)\) in generale. Non soddisfa quindi le proprietà di una distanza simmetrica.

  • Unità di misura: dipende dalla base del logaritmo:

    • base 2 → misura in bit;
    • base \(e\) → misura in nat (unità naturale di informazione).

76.3 Uso della divergenza \(D_{\text{KL}}\) nella selezione di modelli

In teoria, la selezione del modello consiste nello scegliere il modello \(Q\) che minimizza la divergenza dalla distribuzione vera \(P\):

\[ \text{Modello ottimale} = \arg\min_Q D_{\text{KL}}(P \parallel Q). \]

In altre parole, il modello ideale è quello che si avvicina di più a \(P\) e quindi riduce al minimo la perdita media di informazione quando lo usiamo per descrivere i dati.

Problema: nella pratica, \(P\) è sconosciuta — non possiamo osservare direttamente la distribuzione vera che ha generato i dati. Di conseguenza, non possiamo calcolare \(D_{\text{KL}}\) in modo esatto.

76.3.1 Come procedere nella pratica

Anche se \(P\) è ignota, possiamo comunque confrontare modelli in termini di divergenza KL sfruttando il legame con l’entropia incrociata \(H(P,Q)\). Infatti, ricordiamo che:

\[ D_{\text{KL}}(P \parallel Q) = H(P,Q) - H(P). \]

L’entropia \(H(P)\) non dipende dal modello \(Q\): è una costante rispetto al confronto tra modelli. Se prendiamo la differenza di divergenza KL tra due modelli \(Q_1\) e \(Q_2\), questa costante si annulla:

\[ D_{\text{KL}}(P \parallel Q_1) - D_{\text{KL}}(P \parallel Q_2) = H(P,Q_1) - H(P,Q_2). \tag{76.5}\]

Quindi, per confrontare modelli non serve conoscere \(H(P)\): basta confrontare le loro entropie incrociate \(H(P,Q)\), che dipendono solo da \(Q\) e che possono essere stimate dai dati.

Nel prossimo capitolo vedremo due strumenti dell’approccio bayesiano che stimano proprio \(H(P,Q)\) (o, più precisamente, il suo opposto \(-H(P,Q)\)):

  • Leave-One-Out Cross-Validation (LOO-CV) – valuta quanto bene il modello predice dati non usati nella stima;
  • Expected Log Predictive Density (ELPD) – fornisce la stima della qualità predittiva media del modello.

Questi metodi permettono di confrontare modelli in termini di differenza di divergenza KL, avvicinandoci così alla scelta del modello che, tra quelli considerati, è più vicino alla distribuzione vera \(P\).

Immaginiamo di voler prevedere il punteggio di ansia settimanale di uno studente.

  • Modello A: utilizza come predittore solo il punteggio di coping (capacità di fronteggiare lo stress).
  • Modello B: utilizza coping + supporto sociale.

Supponiamo che, valutando le loro prestazioni predittive, entrambi i modelli ottengano buoni risultati, ma il Modello B presenti una divergenza KL leggermente inferiore rispetto al Modello A.

Interpretazione:

  • la divergenza KL più bassa del Modello B indica che, in media, le sue previsioni sono leggermente più vicine alla distribuzione “vera” dei dati (minore perdita di informazione);
  • tuttavia, se la differenza è piccola, potremmo preferire il Modello A per la sua maggiore semplicità e interpretabilità, applicando il principio di parsimonia (o rasoio di Occam).

Questo esempio illustra che la selezione del modello non dipende solo dalla precisione predittiva, ma anche dal bilanciamento tra accuratezza e complessità.

Riflessioni conclusive

In questo capitolo abbiamo approfondito un concetto fondamentale della teoria dell’informazione: la divergenza di Kullback–Leibler. Nata in origine per valutare l’efficienza dei codici di trasmissione, la D-KL è oggi uno strumento essenziale anche nella statistica moderna, perché misura in modo preciso quanto una distribuzione di probabilità approssimata \(Q\) (cioè un modello) si discosti dalla distribuzione vera \(P\) che genera i dati.

Abbiamo visto che la D-KL può essere interpretata come:

  • perdita media di informazione quando si usa \(Q\) invece di \(P\);
  • eccesso di sorpresa o inefficienza di codifica introdotta da un modello imperfetto;
  • differenza tra entropia incrociata e entropia vera, il che rende possibile stimarla indirettamente.

Questo legame con l’entropia incrociata è cruciale: sebbene \(P\) non sia nota e la D-KL non possa essere calcolata in valore assoluto, possiamo confrontare modelli stimando le differenze di D-KL, perché la componente costante \(H(P)\) si annulla nel confronto.

Nel prossimo capitolo ci concentreremo proprio su come effettuare questi confronti in pratica. Vedremo come strumenti come la Leave-One-Out Cross-Validation (LOO-CV) e l’Expected Log Predictive Density (ELPD) permettano di stimare la capacità predittiva dei modelli e di identificare quello che, tra le alternative considerate, è il più vicino alla distribuzione vera dei dati.

Sintesi finale
  • La divergenza KL quantifica la perdita media di informazione usando \(Q\) al posto di \(P\).
  • Si può scrivere come \(\sum_x p(x) \log \frac{p(x)}{q(x)}\) o come \(H(P,Q) - H(P)\).
  • È uno strumento chiave per valutare quanto bene un modello rappresenta la realtà.
  • In pratica, può essere confrontata tra modelli stimando \(H(P,Q)\) con tecniche come LOO-CV ed ELPD.

Esercizi

Esercizio 76.1 Cosideriamo due distribuzioni di probabilità discrete, \(p\) e \(q\):

p <- c(0.2, 0.5, 0.3)
q <- c(0.1, 0.2, 0.7)

Si calcoli l’entropia di \(p\), l’entropia incrociata tra \(p\) e \(q\), la divergenza di Kullback-Leibler da \(p\) a \(q\).

Si consideri q = c(0.2, 0.55, 0.25) e si calcoli di nuovo a divergenza di Kullback-Leibler da \(p\) a \(q\). Si confronti con il risultato precedente e si interpreti.

Esercizio 76.2 Sia \(p\) una distribuzione binomiale di parametri \(\theta = 0.2\) e \(n = 5\). Sia \(q_1\) una approssimazione a \(p\): q1 = c(0.46, 0.42, 0.10, 0.01, 0.01). Sia \(q_2\) una distribuzione uniforme: q2 <- rep(0.2, 5). Si calcoli la divergenza \(\mathbb{KL}\) di \(q_1\) da \(p\) e da \(q_2\) da \(p\) e si interpretino i risultati.

sessionInfo()
#> R version 4.5.1 (2025-06-13)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sequoia 15.6.1
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib 
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1
#> 
#> locale:
#> [1] C/UTF-8/C/C/C/C
#> 
#> time zone: Europe/Zagreb
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] pillar_1.11.0         tinytable_0.11.0      patchwork_1.3.1      
#>  [4] ggdist_3.3.3          tidybayes_3.0.7       bayesplot_1.13.0     
#>  [7] ggplot2_3.5.2         reliabilitydiag_0.2.1 priorsense_1.1.0     
#> [10] posterior_1.6.1       loo_2.8.0             rstan_2.32.7         
#> [13] StanHeaders_2.32.10   brms_2.22.0           Rcpp_1.1.0           
#> [16] sessioninfo_1.2.3     conflicted_1.2.0      janitor_2.2.1        
#> [19] matrixStats_1.5.0     modelr_0.1.11         tibble_3.3.0         
#> [22] dplyr_1.1.4           tidyr_1.3.1           rio_1.2.3            
#> [25] here_1.0.1           
#> 
#> loaded via a namespace (and not attached):
#>  [1] svUnit_1.0.6         tidyselect_1.2.1     farver_2.1.2        
#>  [4] fastmap_1.2.0        TH.data_1.1-3        tensorA_0.36.2.1    
#>  [7] digest_0.6.37        timechange_0.3.0     estimability_1.5.1  
#> [10] lifecycle_1.0.4      survival_3.8-3       magrittr_2.0.3      
#> [13] compiler_4.5.1       rlang_1.1.6          tools_4.5.1         
#> [16] knitr_1.50           labeling_0.4.3       bridgesampling_1.1-2
#> [19] htmlwidgets_1.6.4    curl_6.4.0           pkgbuild_1.4.8      
#> [22] RColorBrewer_1.1-3   abind_1.4-8          multcomp_1.4-28     
#> [25] withr_3.0.2          purrr_1.1.0          grid_4.5.1          
#> [28] stats4_4.5.1         colorspace_2.1-1     xtable_1.8-4        
#> [31] inline_0.3.21        emmeans_1.11.2       scales_1.4.0        
#> [34] MASS_7.3-65          cli_3.6.5            mvtnorm_1.3-3       
#> [37] rmarkdown_2.29       ragg_1.4.0           generics_0.1.4      
#> [40] RcppParallel_5.1.10  cachem_1.1.0         stringr_1.5.1       
#> [43] splines_4.5.1        parallel_4.5.1       vctrs_0.6.5         
#> [46] V8_6.0.5             Matrix_1.7-3         sandwich_3.1-1      
#> [49] jsonlite_2.0.0       arrayhelpers_1.1-0   systemfonts_1.2.3   
#> [52] glue_1.8.0           codetools_0.2-20     distributional_0.5.0
#> [55] lubridate_1.9.4      stringi_1.8.7        gtable_0.3.6        
#> [58] QuickJSR_1.8.0       htmltools_0.5.8.1    Brobdingnag_1.2-9   
#> [61] R6_2.6.1             textshaping_1.0.1    rprojroot_2.1.0     
#> [64] evaluate_1.0.4       lattice_0.22-7       backports_1.5.0     
#> [67] memoise_2.0.1        broom_1.0.9          snakecase_0.11.1    
#> [70] rstantools_2.4.0     coda_0.19-4.1        gridExtra_2.3       
#> [73] nlme_3.1-168         checkmate_2.3.2      xfun_0.52           
#> [76] zoo_1.8-14           pkgconfig_2.0.3

Bibliografia

Kullback, S., & Leibler, R. A. (1951). On information and sufficiency. The Annals of Mathematical Statistics, 22(1), 79–86.
McElreath, R. (2020). Statistical rethinking: A Bayesian course with examples in R and Stan (2nd Edition). CRC Press.