La distribuzione multinominale in NumPy è uno strumento molto utile quando si vuole simulare il risultato di più prove ripetute, nelle quali ogni evento può finire in una tra diverse categorie possibili. È una generalizzazione naturale della distribuzione binomiale: invece di avere soltanto successo o fallimento, qui si lavora con più esiti.
Chi inizia a usare NumPy spesso incontra questa funzione durante simulazioni statistiche, analisi di frequenze, modellazione di esperimenti casuali o test di probabilità applicata. In pratica, serve per rispondere a domande come: se ripeto un esperimento 20 volte, con 3 possibili risultati e probabilità note, quante volte comparirà ciascun esito?
In NumPy, la funzione più usata per questo scopo è multinomial, disponibile tramite il generatore casuale moderno. Il suo comportamento è abbastanza intuitivo: si specifica il numero totale di prove e la probabilità di ogni categoria, e NumPy restituisce un campione con i conteggi osservati.
Dal punto di vista pratico, la distribuzione multinomiale è perfetta per simulare estrazioni, classificazioni casuali, assegnazione di utenti a gruppi, conteggi di categorie in un esperimento e molti altri scenari reali. Il vantaggio principale è che permette di lavorare in modo rapido, leggibile e molto efficiente anche su array di grandi dimensioni.
Come generare campioni con la distribuzione multinomiale in NumPy
Per iniziare, conviene usare il generatore casuale introdotto nelle versioni più recenti di NumPy. Questo approccio è più moderno rispetto alle vecchie API e rende il codice più chiaro. La sintassi base richiede tre elementi:
- il numero di prove totali, indicato come n;
- l’elenco delle probabilità delle categorie, indicato come pvals;
- facoltativamente, la dimensione del campione da generare, cioè size.
Ecco un primo esempio molto semplice:
import numpy as np
rng = np.random.default_rng()
campione = rng.multinomial(
10,
[0.2, 0.5, 0.3]
)
print(campione)
In questo caso stiamo simulando 10 prove totali, distribuite tra tre categorie con probabilità rispettivamente pari a 0.2, 0.5 e 0.3. L’output potrebbe essere qualcosa come [2 5 3], ma cambierà a ogni esecuzione, perché si tratta di un’estrazione casuale.
È importante sapere che la somma delle probabilità dovrebbe essere uguale a 1. Se l’ultimo valore non chiude perfettamente la somma, NumPy può gestire il caso, ma in generale è buona norma fornire probabilità coerenti e ben definite.
Se vuoi generare più campioni in una sola volta, puoi usare il parametro size:
import numpy as np
rng = np.random.default_rng()
campioni = rng.multinomial(
12,
[0.1, 0.6, 0.3],
size=5
)
print(campioni)
Qui NumPy genera 5 campioni distinti, ciascuno composto da 12 prove. Il risultato sarà una matrice in cui ogni riga rappresenta una simulazione diversa. Questo è molto comodo quando si vuole osservare la variabilità dei risultati su più esperimenti.
Un altro accorgimento utile, soprattutto in fase di studio o debugging, è fissare un seed per rendere l’output riproducibile:
import numpy as np
rng = np.random.default_rng(42)
campione = rng.multinomial(
8,
[0.25, 0.25, 0.25, 0.25]
)
print(campione)
In questo modo, eseguendo il codice nelle stesse condizioni, otterrai sempre lo stesso risultato. È una pratica molto diffusa quando si scrivono esempi, test automatici o tutorial didattici.
Dal punto di vista concettuale, ogni campione restituito rappresenta il numero di volte in cui ciascuna categoria è stata osservata. La somma dei valori sarà sempre uguale al numero totale di prove. Questo dettaglio è fondamentale, perché distingue la multinomiale da altre distribuzioni casuali che producono valori indipendenti tra loro.
Sintassi, parametri e comportamento della funzione multinomial
La forma generale è la seguente:
rng.multinomial(
n,
pvals,
size=None
)
- n: numero totale di prove effettuate;
- pvals: sequenza di probabilità associate alle categorie;
- size: numero di campioni da produrre.
Se size non viene indicato, il risultato è un singolo array monodimensionale. Se invece imposti una dimensione, NumPy restituisce un insieme di campioni. Quando si lavora su simulazioni più corpose, questo parametro fa risparmiare tempo e rende il codice decisamente più pulito.
Un aspetto che chi è alle prime armi tende a sottovalutare è che le categorie non vengono restituite come etichette, ma come conteggi. Se per esempio assegni le probabilità a tre possibili classi, il risultato non sarà il nome della classe vincente, bensì il numero di occorrenze di ciascuna classe nel totale delle prove.
Analizzare i campioni ottenuti con la multinomiale di NumPy
Dopo aver generato i campioni, il passaggio successivo consiste nell’analisi dei risultati. Questa fase è importante quanto la generazione stessa, perché permette di interpretare i conteggi, confrontare la simulazione con le probabilità teoriche e verificare se il comportamento osservato è plausibile.
Supponiamo di produrre molti campioni e di voler calcolare la media dei conteggi per categoria:
import numpy as np
rng = np.random.default_rng(7)
campioni = rng.multinomial(
20,
[0.2, 0.5, 0.3],
size=1000
)
medie = campioni.mean(axis=0)
print(medie)
Con un numero elevato di simulazioni, le medie tenderanno ad avvicinarsi ai valori attesi teorici. In questo esempio, i valori attesi sono circa 4, 10 e 6, perché derivano da 20 prove moltiplicate per le rispettive probabilità.
Se vuoi osservare meglio la distribuzione dei risultati, puoi anche contare la frequenza con cui compare una certa configurazione oppure misurare la dispersione dei campioni. Per esempio:
import numpy as np
rng = np.random.default_rng(7)
campioni = rng.multinomial(
15,
[0.3, 0.4, 0.3],
size=500
)
deviazione = campioni.std(axis=0)
somma_righe = campioni.sum(axis=1)
print(deviazione)
print(somma_righe[:10])
La deviazione standard aiuta a capire quanto i conteggi oscillano da una simulazione all’altra. La verifica della somma delle righe, invece, è un controllo semplice ma prezioso: ogni riga deve sommare esattamente a 15, cioè al numero totale di prove.
In un contesto reale, questa analisi può servire per confrontare scenari diversi. Per esempio, potresti simulare:
- la distribuzione di preferenze tra più prodotti;
- la ripartizione di richieste tra categorie di supporto;
- la classificazione di eventi in più classi;
- i risultati di un processo casuale con esiti multipli.
Uno dei punti di forza di NumPy è la possibilità di combinare la distribuzione multinomiale con tutte le altre operazioni sugli array. Questo significa che puoi generare i dati e poi elaborarli con medie, somme, varianze, filtri e confronti, senza uscire dall’ecosistema NumPy.
Interpretazione pratica dei risultati della distribuzione multinominale
Per capire davvero i campioni multinomiali, conviene ragionare in termini concreti. Immagina un piccolo esperimento in cui 30 utenti vengono assegnati casualmente a tre varianti di una pagina web. Se le probabilità sono 0.5, 0.3 e 0.2, un campione come [14 10 6] è perfettamente sensato: non coincide esattamente con i valori teorici, ma resta vicino alle proporzioni attese.
Questo è il punto chiave: la distribuzione multinomiale non restituisce proporzioni perfette, bensì conteggi casuali compatibili con le probabilità indicate. Più alto è il numero di prove, più i risultati tenderanno a stabilizzarsi. Con pochi tentativi, invece, è normale vedere oscillazioni più marcate.
Puoi anche convertire i conteggi in frequenze relative per confrontarli meglio con le probabilità iniziali:
import numpy as np
rng = np.random.default_rng(21)
campione = rng.multinomial(
30,
[0.5, 0.3, 0.2]
)
frequenze = campione / campione.sum()
print(campione)
print(frequenze)
Questo passaggio è spesso molto utile nei tutorial, nelle analisi esplorative e nella validazione di una simulazione. Guardando le frequenze relative, diventa più immediato verificare se il campione segue, almeno in modo approssimativo, la struttura probabilistica di partenza.
Per chi muove i primi passi, vale la pena ricordare anche un errore comune: confondere la distribuzione multinomiale con una semplice scelta casuale tra categorie. Se hai bisogno di contare quanti elementi finiscono in ogni gruppo dopo un certo numero di prove, la multinomiale è lo strumento giusto. Se invece vuoi estrarre una singola categoria alla volta, allora potrebbero essere più adatte funzioni come quelle basate sulla scelta casuale diretta.
Considerazioni finali sulla distribuzione multinominale in NumPy
La distribuzione multinominale NumPy è una funzione estremamente pratica per simulare eventi con più esiti possibili. Anche se il nome può sembrare impegnativo all’inizio, il suo utilizzo è piuttosto lineare: definisci un numero di prove, assegni le probabilità alle categorie e ottieni i conteggi corrispondenti.
Per chi studia statistica, data analysis o programmazione scientifica, è uno strumento da conoscere bene. Permette infatti di creare simulazioni realistiche, verificare ipotesi, costruire esempi didattici e analizzare fenomeni discreti in modo rapido e leggibile.
Il consiglio pratico è di iniziare con esempi piccoli, osservare la forma dell’output e poi passare a simulazioni più ampie. NumPy offre un ambiente molto solido per questo tipo di lavoro, e la funzione multinomial si integra perfettamente con il resto delle sue operazioni vettoriali.
Se stai cercando una soluzione semplice per modellare conteggi distribuiti tra più categorie, la multinomiale è spesso la scelta più naturale. Capirla bene all’inizio ti aiuterà a lavorare con maggiore sicurezza anche su argomenti più avanzati della statistica computazionale.