Introduzione: perchè la Probabilità e Fondamentale per l'AI
Il machine learning e, nella sua essenza, un problema di ragionamento sotto incertezza. I dati sono rumorosi, i modelli sono approssimazioni, e le predizioni sono sempre probabilistiche. La probabilità ci da il framework matematico per quantificare questa incertezza e prendere decisioni informate.
In questo articolo esploreremo dalle basi (probabilità condizionata, distribuzioni) fino a concetti avanzati come il teorema di Bayes, la Maximum Likelihood Estimation, e il confronto tra approccio frequentista e bayesiano.
Cosa Imparerai
- Probabilità condizionata e indipendenza
- Distribuzioni: Gaussiana, Bernoulli, Categorica, Poisson
- Teorema di Bayes: aggiornare le credenze con i dati
- Maximum Likelihood Estimation (MLE)
- Maximum A Posteriori (MAP) e approccio bayesiano
- Central Limit Theorem e le sue implicazioni
Fondamenti: Probabilità e Variabili Aleatorie
La probabilità di un evento A e un numero tra 0 e 1 che misura quanto e verosimile che quell'evento si verifichi: P(A) \\in [0, 1].
La probabilità condizionata di A dato B misura la probabilità di A sapendo che B e avvenuto:
Due eventi sono indipendenti se P(A \\cap B) = P(A) \\cdot P(B), cioe sapere che uno e avvenuto non cambia la probabilità dell'altro.
Valore Atteso e Varianza
Il valore atteso (media) di una variabile aleatoria X:
La varianza misura la dispersione attorno alla media:
La deviazione standard \\sigma = \\sqrt{\\text{Var}(X)} ha la stessa unita di misura di X, quindi e più interpretabile.
Distribuzioni Fondamentali per il ML
Distribuzione di Bernoulli
Modella un singolo esperimento con due esiti (successo/fallimento). Parametro: p (probabilità di successo).
In ML: modella classificazione binaria. L'output di un neurone con sigmoid e il parametro p di una Bernoulli.
Distribuzione Gaussiana (Normale)
La distribuzione più importante in statistica e ML, parametrizzata da media \\mu e varianza \\sigma^2:
perchè e ovunque: per il Teorema del Limite Centrale, la somma di molte variabili aleatorie indipendenti tende a una Gaussiana, indipendentemente dalla distribuzione originale.
In ML: inizializzazione dei pesi (Gaussiana con \\mu = 0), rumore nei dati, Gaussian Mixture Models, VAE (variational autoencoders).
Distribuzione Categorica (Multinomiale)
Generalizzazione della Bernoulli a K classi con probabilità p_1, p_2, \\ldots, p_K dove \\sum_i p_i = 1:
In ML: l'output di softmax modella una distribuzione categorica su K classi.
import numpy as np
from scipy import stats
# Bernoulli: lancio di una moneta truccata (p=0.7)
bernoulli = stats.bernoulli(p=0.7)
samples = bernoulli.rvs(size=1000)
print(f"Bernoulli - Media empirica: {samples.mean():.3f} (attesa: 0.7)")
# Gaussiana: altezze (media=170cm, std=10cm)
gaussian = stats.norm(loc=170, scale=10)
heights = gaussian.rvs(size=1000)
print(f"Gaussiana - Media: {heights.mean():.1f}, Std: {heights.std():.1f}")
# Probabilità di essere tra 160 e 180
prob = gaussian.cdf(180) - gaussian.cdf(160)
print(f"P(160 < X < 180) = {prob:.4f}")
# Categorica: dadi a 6 facce
probs = np.array([1/6] * 6)
categorical_samples = np.random.choice(6, size=1000, p=probs) + 1
print(f"Dado - Media: {categorical_samples.mean():.2f} (attesa: 3.5)")
Teorema di Bayes: Aggiornare le Credenze
Il teorema di Bayes e uno degli strumenti più potenti per il ragionamento probabilistico. Ci permette di aggiornare la nostra credenza sulla probabilità di un'ipotesi dopo aver osservato dei dati:
dove:
- P(\\theta | D) - Posterior: credenza aggiornata dopo i dati
- P(D | \\theta) - Likelihood: quanto i dati sono probabili dato il modello
- P(\\theta) - Prior: credenza iniziale prima dei dati
- P(D) - Evidence: probabilità marginale dei dati (costante di normalizzazione)
Intuizione: Bayes ci dice di partire con una credenza iniziale (prior), osservare i dati (likelihood), e combinare le due informazioni per ottenere una credenza aggiornata (posterior). Più dati osserviamo, più il posterior e dominato dalla likelihood e meno dal prior.
Esempio Pratico: Classificatore Naive Bayes
import numpy as np
from collections import Counter
# Dataset: email spam detection
# Feature: numero di parole "gratis", "offerta", "ciao"
X_train = np.array([
[3, 2, 0], # spam
[4, 3, 1], # spam
[0, 0, 3], # non-spam
[1, 0, 4], # non-spam
[5, 4, 0], # spam
[0, 1, 2], # non-spam
])
y_train = np.array([1, 1, 0, 0, 1, 0]) # 1=spam, 0=non-spam
# Naive Bayes: P(spam|features) proporzionale a P(features|spam) * P(spam)
# Calcolo prior
n_spam = np.sum(y_train == 1)
n_ham = np.sum(y_train == 0)
p_spam = n_spam / len(y_train)
p_ham = n_ham / len(y_train)
print(f"P(spam) = {p_spam:.3f}, P(ham) = {p_ham:.3f}")
# Calcolo media e varianza per feature (likelihood Gaussiana)
spam_mean = X_train[y_train == 1].mean(axis=0)
spam_var = X_train[y_train == 1].var(axis=0) + 1e-6
ham_mean = X_train[y_train == 0].mean(axis=0)
ham_var = X_train[y_train == 0].var(axis=0) + 1e-6
def gaussian_log_likelihood(x, mean, var):
return -0.5 * np.sum(np.log(2 * np.pi * var) + (x - mean)**2 / var)
# Classifica nuova email
x_new = np.array([4, 3, 0])
log_p_spam = np.log(p_spam) + gaussian_log_likelihood(x_new, spam_mean, spam_var)
log_p_ham = np.log(p_ham) + gaussian_log_likelihood(x_new, ham_mean, ham_var)
print(f"Log P(spam|x) proporzionale a: {log_p_spam:.4f}")
print(f"Log P(ham|x) proporzionale a: {log_p_ham:.4f}")
print(f"Classificazione: {'SPAM' if log_p_spam > log_p_ham else 'HAM'}")
Maximum Likelihood Estimation (MLE)
La MLE trova i parametri del modello che rendono i dati osservati più probabili. Data una serie di osservazioni indipendenti D = \\{x_1, \\ldots, x_n\\}, la likelihood e:
In pratica lavoriamo con la log-likelihood (trasforma prodotti in somme):
Per trovare il massimo, calcoliamo la derivata e poniamola a zero: \\frac{d\\ell}{d\\theta} = 0.
Esempio: MLE per una Gaussiana
Per dati Gaussiani, la MLE dei parametri e:
Cioe la media e la varianza campionaria sono le stime MLE. La connessione con il ML e profonda: minimizzare la cross-entropy loss equivale a massimizzare la log-likelihood.
Maximum A Posteriori (MAP)
La MAP aggiunge un prior ai parametri, combinando likelihood e prior:
Con un prior Gaussiano P(\\theta) \\sim \\mathcal{N}(0, \\sigma_p^2), il termine \\log P(\\theta) diventa una penalita L2 sui pesi: ecco perchè la regolarizzazione L2 (Ridge) e equivalente a un prior Gaussiano sui pesi.
import numpy as np
from scipy.optimize import minimize_scalar
# Dati osservati (altezze in cm)
data = np.array([168, 172, 175, 170, 173, 169, 171, 174, 176, 170])
# MLE: media e varianza campionaria
mu_mle = np.mean(data)
sigma2_mle = np.var(data)
print(f"MLE: mu={mu_mle:.2f}, sigma^2={sigma2_mle:.2f}")
# Log-likelihood function
def neg_log_likelihood(mu, data=data, sigma2=sigma2_mle):
n = len(data)
return 0.5 * n * np.log(2 * np.pi * sigma2) + np.sum((data - mu)**2) / (2 * sigma2)
# MAP con prior Gaussiano: mu ~ N(170, 5^2)
prior_mu = 170
prior_sigma2 = 25
def neg_log_posterior(mu):
nll = neg_log_likelihood(mu)
neg_log_prior = (mu - prior_mu)**2 / (2 * prior_sigma2)
return nll + neg_log_prior
result_mle = minimize_scalar(neg_log_likelihood, bounds=(150, 190), method='bounded')
result_map = minimize_scalar(neg_log_posterior, bounds=(150, 190), method='bounded')
print(f"MLE mu: {result_mle.x:.4f}")
print(f"MAP mu: {result_map.x:.4f} (shrunk verso prior {prior_mu})")
Central Limit Theorem
Il Teorema del Limite Centrale (CLT) afferma che la somma (o media) di molte variabili aleatorie indipendenti, qualunque sia la loro distribuzione originale, tende a una distribuzione Gaussiana:
Questo spiega perchè la Gaussiana appare ovunque: peso di un neurone = somma di tanti piccoli aggiornamenti, rumore nei sensori = somma di tante piccole perturbazioni, etc.
Riepilogo e Connessioni con il ML
Punti Chiave da Ricordare
- Bayes: P(\\theta|D) \\propto P(D|\\theta) P(\\theta) - aggiorna credenze con dati
- Gaussiana: la distribuzione più comune, appare ovunque grazie al CLT
- MLE: trova parametri che massimizzano la probabilità dei dati osservati
- MAP: MLE + prior, equivalente alla regolarizzazione
- Cross-entropy loss = negativa log-likelihood: il collegamento fondamentale
- Regolarizzazione L2 = prior Gaussiano: connessione probabilistica
Nel Prossimo Articolo: esploreremo l'ottimizzazione per il ML. Vedremo Gradient Descent, SGD, Adam, momentum, e le strategie di learning rate scheduling che determinano se un modello converge o diverge.







