Ci hanno sempre raccontato una bugia sull’algebra lineare: che serve a risolvere sistemi di equazioni su un foglio a quadretti. La verità è molto più sporca e interessante. Quelle righe e colonne non sono scatole vuote; sono il codice genetico di un sistema dinamico.
Immaginate di dover gestire una riserva di pesca o di dover calcolare se l’INPS reggerà tra trent’anni. Non vi serve una sfera di cristallo, vi serve una matrice. Il Modello di Leslie è esattamente questo: lo strumento che prende una fotografia statica di oggi — quanti giovani, adulti e anziani abbiamo — e proietta un film sul loro futuro.
Il Modello di Leslie non è un semplice esercizio da lavagna: è il ponte che collega la matematica pura alla vita reale. È lo strumento che permette a un biologo, a un ecologo o a un moderno Data Scientist di guardare una popolazione oggi e “vedere” la sua evoluzione tra cinquant’anni.
In questo articolo, smontiamo il giocattolo. Partiamo dalla matematica pura, la traduciamo in Python e poi, visto che la realtà è caotica, la bombardiamo con disastri simulati per vedere se il sistema regge.
1. Oltre il numero: la popolazione strutturata
In natura, non tutti gli individui sono uguali. Un cucciolo consuma risorse, un adulto produce prole, un anziano ha probabilità di sopravvivenza diverse. Per questo dividiamo la popolazione in classi di età.
Immaginiamo una popolazione divisa in tre gruppi:
- Classe 1: Giovani (fase di crescita)
- Classe 2: Adulti giovani (picco riproduttivo)
- Classe 3: Adulti anziani (fase finale)
Il vettore stato al tempo [math]t[/math] è rappresentato da:
[math]
\displaystyle x(t) = \begin{pmatrix} x_1(t) \\ x_2(t) \\ x_3(t) \end{pmatrix}
[/math]
2. La Matrice di Leslie: Il motore del sistema
Il destino di questa popolazione è scritto in una matrice [math]L[/math] che contiene due informazioni vitali:
- Fertilità ([math]f_k[/math]): Quanti nuovi nati produce in media un individuo della classe [math]k[/math].
- Sopravvivenza ([math]s_k[/math]): Qual è la probabilità che un individuo passi alla classe d’età successiva.
La struttura standard della matrice è:
[math]
\displaystyle \begin{pmatrix}
f_1 & f_2 & f_3 \\
s_1 & 0 & 0 \\
0 & s_2 & 0
\end{pmatrix}
[/math]
La dinamica è un sistema iterativo: [math]x(t+1) = L \cdot x(t)[/math]. In pratica, stiamo dicendo che il futuro è un’elaborazione lineare del presente.
3. Autovalori e Autovettori: Il destino e la forma
Perché un Data Scientist dovrebbe interessarsi agli autovalori di questa matrice? Perché essi rispondono alle due domande fondamentali di ogni modello predittivo:
L’Autovalore Dominante ([math]\lambda[/math]): “Quanto cresceremo?”
L’autovalore reale positivo più grande ci dice tutto sul destino a lungo termine:
- [math]\lambda > 1[/math]: La popolazione esplode (crescita esponenziale).
- [math]\lambda = 1[/math]: La popolazione è in equilibrio (stazionaria).
- [math]\lambda < 1[/math]: La popolazione è destinata all’estinzione.
L’Autovettore ([math]v[/math]): “Come saremo fatti?”
Mentre il numero totale di individui cambia, la proporzione tra le classi tende a stabilizzarsi. Questa “struttura stabile per età” è esattamente l’autovettore corrispondente a [math]\lambda[/math]. Indica, ad esempio, che col tempo avremo sempre il 60% di giovani, il 30% di adulti e il 10% di anziani, indipendentemente dal numero iniziale.
4. Esercizio Pratico e Analisi
Prendiamo una popolazione con questi parametri:
- Nessuna nascita dai giovani; gli adulti producono 4 figlie; gli anziani 2.
- Sopravvivenza dei giovani: 50%; sopravvivenza degli adulti: 60%.
La nostra matrice sarà:
[math]
\displaystyle L = \begin{pmatrix} 0 & 4 & 2 \\ 0.5 & 0 & 0 \\ 0 & 0.6 & 0 \end{pmatrix}
[/math]
Calcolando il polinomio caratteristico [math]\det(L – \lambda I) = 0[/math], otteniamo l’equazione:
[math]
\displaystyle \lambda^3 – 2\lambda – 0.6 = 0
[/math]
Risolvendo, troviamo l’autovalore dominante [math]\lambda \approx 1.55[/math].
Analisi: La popolazione cresce del 55% ogni ciclo temporale. È un tasso altissimo, tipico di specie pioniere o situazioni di assenza di predatori.
5. Implementazione in Python con NumPy
Per un Data Scientist, risolvere equazioni di terzo grado a mano non è efficiente. NumPy ci permette di analizzare popolazioni enormi in millisecondi.
import numpy as np
# Definiamo la matrice di Leslie
L = np.array([
[0, 4, 2],
[0.5, 0, 0],
[0, 0.6, 0]
])
# Calcoliamo autovalori e autovettori
eigenvalues, eigenvectors = np.linalg.eig(L)
# Cerchiamo l'autovalore reale dominante
dominant_idx = np.argmax(np.real(eigenvalues))
lambda_dom = np.real(eigenvalues[dominant_idx])
v_dom = np.real(eigenvectors[:, dominant_idx])
# Normalizziamo l'autovettore per avere le percentuali (somma = 1)
stable_age_dist = v_dom / np.sum(v_dom)
print(f"Tasso di crescita (lambda): {lambda_dom:.2f}")
print(f"Struttura stabile (percentuali): {stable_age_dist}")
# Simulazione di 10 anni partendo da 100 giovani
pop = np.array([100, 0, 0])
for t in range(10):
pop = L @ pop
print(f"Anno {t+1}: {pop.astype(int)}")
Tasso di crescita (lambda): 1.55
Struttura stabile (percentuali): [0.69005655 0.223262 0.08668145]
Anno 1: [ 0 50 0]
Anno 2: [200 0 30]
Anno 3: [ 60 100 0]
Anno 4: [400 30 60]
Anno 5: [240 200 18]
Anno 6: [836 120 120]
Anno 7: [720 418 72]
Anno 8: [1816 360 250]
Anno 9: [1941 908 216]
Anno 10: [4064 970 544]
Perché questo approccio è interessante?
- Scalabilità: Puoi gestire matrici con 100 classi d’età (es. demografia umana anno per anno) senza sforzo.
- Simulazione: Oltre agli autovalori, puoi simulare l’effetto di “shock” esterni (es. una pandemia che dimezza [math]s_k[/math]) e vedere come reagisce il sistema.
- Ottimizzazione: Puoi capire quale classe d’età proteggere per massimizzare la sopravvivenza della specie.
Il passaggio dal modello lineare a quello non lineare segna il momento in cui la matematica smette di descrivere un mondo ideale e inizia a mappare la complessità della natura. Se il modello di Leslie classico è una “linea retta” verso l’infinito, l’introduzione dei vincoli di risorse introduce il concetto di feedback.
In Data Science, questo significa passare da una semplice moltiplicazione matriciale a un sistema dinamico in cui i parametri cambiano a ogni step.
Il Limite della Crescita: La “Density Dependence”
In un ambiente reale, il cibo, lo spazio e l’accumulo di rifiuti agiscono come freni. Questo fenomeno si chiama dipendenza dalla densità. Esistono due modi principali per rendere il modello di Leslie non lineare:
-
-
Modello di Beverton-Holt: La sopravvivenza o la fertilità diminuiscono progressivamente all’aumentare della popolazione.
-
Fattore di Feedback Globale: Si moltiplica l’intera matrice per un fattore che dipende dalla popolazione totale [math]N(t)[/math].
-
La Logica Matematica
Definiamo [math]N(t)[/math] come la somma di tutti gli individui nel vettore [math]x(t)[/math].
Introduciamo un fattore di smorzamento [math]q(N)[/math]:
[math]\displaystyle
\begin{aligned}
q(N(t)) = \frac{1}{1 + a \cdot N(t)}
\end{aligned}
[/math]
Dove [math]a[/math] è un parametro che rappresenta la scarsità di risorse.
La nuova equazione di stato diventa:
[math]\displaystyle
\begin{aligned}
x(t+1) = \left[ q(N(t)) \cdot L \right] \cdot x(t)
\end{aligned}
[/math]
Implementazione in Python: Leslie + Feedback
Ecco come possiamo modificare il codice precedente per simulare una popolazione che si scontra con il “tetto” delle risorse (la cosiddetta Carrying Capacity).
import numpy as np
import matplotlib.pyplot as plt
# Parametri originali (Matrice di Leslie ideale)
L = np.array([
[0, 4, 2],
[0.5, 0, 0],
[0, 0.6, 0]
])
# Parametri del vincolo (Non-linearità)
K = 1000 # Capacità portante teorica dell'ambiente
a = 0.001 # Coefficiente di competizione
def simulate_nonlinear(steps, initial_pop):
history = []
current_pop_vector = initial_pop
for _ in range(steps):
# 1. Calcoliamo la popolazione totale attuale
total_n = np.sum(current_pop_vector)
history.append(total_n)
# 2. Calcoliamo il fattore di smorzamento (non-lineare)
# Più N è grande, più damping si avvicina a 0
damping = 1 / (1 + a * total_n)
# 3. Applichiamo la matrice con il feedback
current_pop_vector = (damping * L) @ current_pop_vector
return history
# Simulazione
steps = 50
initial_v = np.array([10, 5, 2])
pop_history = simulate_nonlinear(steps, initial_v)
# Visualizzazione
plt.figure(figsize=(10, 5))
plt.plot(pop_history, label="Popolazione con vincoli (Non-lineare)", color='teal', lw=2)
plt.axhline(y=520, color='r', linestyle='--', label="Equilibrio dinamico stimato") # Valore indicativo
plt.title("Evoluzione della Popolazione: Verso l'Equilibrio")
plt.xlabel("Tempo (Anni)")
plt.ylabel("Numero totale di individui")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
Perché questo approccio è fondamentale per un Data Scientist?
Implementare vincoli non lineari trasforma il modello da uno strumento puramente descrittivo a uno strumento decisionale e predittivo avanzato:
-
Identificazione dei Punti di Equilibrio: Mentre nel modello lineare la popolazione o esplode o muore, qui il sistema tende a un punto fisso. In Data Science, questo è l’equivalente di trovare lo “stato stazionario” di un sistema economico o biologico.
-
Analisi di Sensibilità: Puoi testare come cambia il destino della popolazione se <strong>[math]a[/math]</strong> (la competizione) aumenta a causa del cambiamento climatico o della perdita di habitat.
-
Gestione del Rischio: Nelle assicurazioni o nella gestione delle risorse ittiche, questi modelli servono a calcolare il Maximum Sustainable Yield (il prelievo massimo che non distrugge la popolazione).
Una curiosità applicativa: L’instabilità
Se aumenti drasticamente la fertilità nella matrice di Leslie in un modello non lineare, potresti osservare comportamenti caotici o oscillazioni cicliche. È lo stesso principio alla base dei modelli meteo e dei mercati finanziari.
Nel mondo reale, i modelli deterministici sono “fotografie” di un ufficio perfettamente in ordine. Ma la natura assomiglia più a un cantiere aperto: piove quando non dovrebbe, scoppiano epidemie e le risorse fluttuano.
Per un Data Scientist, “sporcare” il modello con la stocasticità significa passare dalla previsione singola alla gestione del rischio. Non ci interessa più solo sapere cosa accadrà, ma cosa potrebbe accadere nel peggiore o nel migliore dei casi.
La Matematica dell’Incertezza
Esistono due modi principali per inserire il caso nel Modello di Leslie:
- Stocasticità Ambientale (Shocks): Eventi rari ma catastrofici (siccità, incendi, epidemie) che colpiscono l’intera popolazione contemporaneamente.
- Variazione Parametrica: Piccole fluttuazioni annuali nei tassi di sopravvivenza e fertilità (un anno più freddo, un anno con più cibo).
In termini di calcolo, la nostra equazione diventa:
[math]\displaystyle \begin{aligned} x(t+1) = \left[ \epsilon_t \cdot q(N(t)) \cdot L \right] \cdot x(t) \end{aligned} [/math]
Dove [math]\epsilon_t[/math] è una variabile casuale che rappresenta lo “stato del mondo” al tempo [math]t[/math].
Implementazione in Python: Simulazione Monte Carlo
Per analizzare un modello stocastico, non facciamo una sola simulazione, ma ne facciamo migliaia. Questo metodo è chiamato Simulazione Monte Carlo.
import numpy as np
import matplotlib.pyplot as plt
# Matrice di Leslie e parametri non lineari
L = np.array([[0, 4, 2], [0.5, 0, 0], [0, 0.6, 0]])
a = 0.001 # Competizione
def simulate_stochastic(steps, initial_pop, p_disaster=0.05, impact=0.4):
history = []
current_pop = initial_pop
for _ in range(steps):
total_n = np.sum(current_pop)
damping = 1 / (1 + a * total_n)
# Introduciamo l'evento casuale (Epidemia/Siccità)
# Se esce un numero < p_disaster, accade il disastro
shock = 1.0
if np.random.rand() < p_disaster:
shock = impact # La sopravvivenza/fertilità crolla al 40%
# Applichiamo anche una piccola variazione annuale standard (rumore bianco)
noise = np.random.normal(1.0, 0.05)
current_pop = (damping * shock * noise * L) @ current_pop
history.append(np.sum(current_pop))
return history
# Eseguiamo 100 simulazioni diverse (Scenari possibili)
n_simulations = 100
plt.figure(figsize=(12, 6))
all_histories = []
for i in range(n_simulations):
hist = simulate_stochastic(steps=60, initial_pop=np.array([50, 20, 10]))
all_histories.append(hist)
plt.plot(hist, color='gray', alpha=0.2) # Linee sottili per ogni scenario
# Calcoliamo e visualizziamo la media degli scenari
mean_history = np.mean(all_histories, axis=0)
plt.plot(mean_history, color='red', lw=3, label="Andamento Medio")
plt.title("Simulazione Monte Carlo: Impatto di Epidemie Casuali sulla Popolazione")
plt.xlabel("Anni")
plt.ylabel("Popolazione Totale")
plt.legend()
plt.grid(alpha=0.3)
plt.show()
Interpretazione del Grafico Monte Carlo
Guardando il risultato delle 100 simulazioni (le linee grigie), un analista trae conclusioni strategiche che la media (linea rossa) non può fornire:
-
Rischio di Estinzione: Sebbene la media sia stabile, alcune traiettorie grigie potrebbero toccare lo zero in presenza di shock consecutivi. Questo è il dato cruciale per i piani di conservazione.
-
Fascia di Incertezza: La dispersione delle linee grigie dopo l’anno 10 indica quanto sia “prevedibile” il sistema. Più l’area occupata dalle linee è vasta, maggiore è l’incertezza decisionale.
-
Tempo di Recupero (Resilienza): Nota come, dopo ogni crollo improvviso (shock), la linea tenda a risalire verso l’equilibrio. La pendenza di questa risalita indica la capacità di ripresa della specie.
Perché questo approccio “spacca” in ambito Data Science?
L’approccio stocastico sposta l’obiettivo dalla previsione puntuale (spesso errata) alla gestione dell’incertezza. In un mondo dominato dai dati, non vince chi indovina il numero esatto, ma chi sa fornire un intervallo di rischio affidabile.
Ecco come questi concetti trasformano la tua analisi in uno strumento di alto livello:
Intervalli di Confidenza: Abbandonare il “Numero Magico”
Nel modello deterministico, ottieni un unico valore: λ. Ma nella Data Science applicata, quel valore è solo una media. Introducendo la stocasticità, puoi calcolare i percentili. Dire che la popolazione sarà 500 è un’ipotesi; dire che c’è il 95% di probabilità che oscillerà tra 350 e 650 è un’analisi professionale che permette di pianificare scenari di budget o di gestione delle risorse.
Probabilità di Estinzione: Analisi delle Code (Tail Risk)
Il grafico Monte Carlo generato mostra che, nonostante la media (linea rossa) sia rassicurante, alcune linee grigie crollano.
-
Business Intelligence: Questo rappresenta il rischio di fallimento di un progetto o di esaurimento di uno stock.
-
Conservazione: Se il 10% delle tue simulazioni finisce con la popolazione sotto la soglia di sopravvivenza, quel 10% è il dato più importante del report, non la media.
Resilienza e Recovery Time
Misurare la resilienza significa osservare la capacità del sistema di “rimbalzare” dopo un evento avverso.
-
Stress Test: Esattamente come le banche simulano crisi finanziarie, tu simuli un’epidemia (
impact=0.4) per vedere quanto tempo impiega la curva a tornare al suo equilibrio dinamico. -
Decision Making: Se il tempo di recupero è troppo lungo, il sistema è fragile e occorrono interventi correttivi sui parametri di sopravvivenza.
Un passo avanti: Analisi della Probabilità di Estinzione
Per rendere il tuo report ancora più potente, potresti aggiungere una sezione che calcola numericamente il rischio basandosi sulle tue simulazioni:
# Calcoliamo la probabilità di estinzione (soglia < 100 individui)
final_populations = [h[-1] for h in all_histories]
extinct_sims = sum(1 for p in final_populations if p < 100)
prob_extinction = (extinct_sims / n_simulations) * 100
print(f"Probabilità di collasso della popolazione: {prob_extinction}%")
Probabilità di collasso della popolazione: 0.0%
Questo trasforma il codice in un vero motore di Risk Assessment.
Una riflessione
Questa struttura è identica a quella usata nei modelli finanziari per simulare i portafogli azionari (dove la matrice di Leslie è sostituita dai rendimenti degli asset) o nei modelli epidemiologici per prevedere l’ondata di un virus.
Il Modello di Leslie stocastico ci insegna che la matematica non serve a eliminare l’incertezza, ma a darle una forma, a misurarla e, infine, a non averne paura.
Conclusione: Il valore della visione critica
Il modello di Leslie è geniale nella sua semplicità, ma come ogni modello lineare ha un limite: assume risorse infinite. Nella realtà, interviene la competizione (modelli non lineari). Tuttavia, resta la base fondamentale per la Data Science ecologica e la demografia attuariale.
Capire questi concetti significa smettere di “risolvere matrici” e iniziare a modellare il mondo.
Articoli di approfondimento
📘 Autovalori e autovettori di una matrice
📘 Matrici e algebra lineare: 6 esercizi pratici, dal supermercato all’AI
📘 Tutto (ma proprio tutto) sulle matrici
📘 Terremoti: scala Richter, Mercalli e magnitudo momento
📘 Teoria delle catastrofi: discontinuità e salti improvvisi
(79)
Altri articoli nella categoria "Le matrici"
- Classificazione delle Coniche con Autovalori e Autovettori: Teoria ed Esercizi Svolti
- Diagonalizzazione di una Matrice: Guida Pratica con 6 Esercizi Svolti e Applicazioni
- Matrici non diagonalizzabili: teoria, metodo in 3 passi ed esercizi svolti per riconoscere il punto critico
- Matrici e Microeconomia: Equilibrio, Elasticità e Modello di Leontief (Esercizi Svolti)
- Rango di una Matrice: 7 Esercizi Svolti e Spiegati (da Facile a Difficile)
- Le Trasformazioni Affini spiegate: Geometria, Matrici e Applicazioni Reali
- Trasformazioni Geometriche e Matrici: Guida Pratica al Calcolo dell’Area e Determinanti
- Matrici a Gradini ed Eliminazione di Gauss: Esercizi Svolti e Guida Pratica
- Autovalori e Autovettori: Guida Intuitiva al Cuore dell’Algebra Lineare e dell’IA
- Guida Geometrica alle Trasformazioni Lineari: Visualizzare le Matrici con Python

