La Curva di Phillips con Python: esercizi, simulazioni e analisi dei dati
Nel 2022 molte banche centrali si sono trovate davanti allo stesso problema.
L’inflazione correva più velocemente del previsto. I prezzi dell’energia salivano. Le imprese aumentavano i listini. I salari iniziavano a inseguire il costo della vita.
La domanda era semplice da formulare e molto difficile da gestire:
quanto raffreddamento dell’economia serve per riportare l’inflazione sotto controllo?
Dietro questa domanda si nasconde una delle relazioni più discusse della macroeconomia: la Curva di Phillips.
Per decenni economisti, governi e banche centrali hanno cercato di capire se esista davvero un compromesso tra inflazione e disoccupazione e, soprattutto, quanto sia affidabile.
Ma c’è un problema.
Le formule sembrano precise. L’economia reale molto meno.
Le aspettative cambiano. Gli shock energetici spostano gli equilibri. I mercati del lavoro evolvono. Relazioni che sembravano solide possono indebolirsi o addirittura scomparire.
Per questo motivo la Curva di Phillips è un caso di studio perfetto anche per chi si occupa di dati.
La Curva di Phillips è uno dei modelli più noti della macroeconomia perché prova a descrivere una relazione che, per chi prende decisioni economiche, è tutt’altro che astratta: come si muovono inflazione e mercato del lavoro?
Una banca centrale deve decidere quanto rapidamente riportare l’inflazione verso il proprio obiettivo. Un governo deve valutare gli effetti delle proprie politiche sull’occupazione. Un’impresa deve formulare previsioni su salari, prezzi e domanda. In tutti questi casi la domanda di fondo è simile:
Se l’economia rallenta e la disoccupazione aumenta, l’inflazione scenderà davvero? E di quanto?
La risposta della Curva di Phillips non è semplicemente «sì» o «no».
Dipende dalle aspettative, dagli shock di offerta, dalla struttura del mercato del lavoro e dal modo in cui il modello viene stimato. Ed è proprio qui che il tema diventa interessante anche dal punto di vista della Data Science.
Un modello teorico può dirci che esiste una relazione del tipo:
\begin{aligned}
\pi_t = \pi_t^e – \beta(u_t – u_n) + \varepsilon_t
\end{aligned}
[/math]
ma i dati pongono domande più difficili:
- Quanto vale davvero [math]\beta[/math]?
- Il parametro è stabile nel tempo?
- Possiamo stimare il NAIRU?
- Quanto sono incerte le previsioni?
- Un modello con un buon RMSE è necessariamente utile per prendere decisioni?
- Una relazione statistica tra inflazione e disoccupazione implica causalità?
In questo articolo costruiremo un percorso progressivo.
Partiremo dalla Curva di Phillips teorica. Vedremo come cambiano inflazione e disoccupazione in presenza di shock e aspettative adattive. Poi passeremo ai dati: stimeremo una relazione con Python, valuteremo il modello, analizzeremo la sua incertezza e utilizzeremo simulazioni Monte Carlo per ragionare in termini di scenari.
L’obiettivo non è imparare una formula a memoria.
L’obiettivo è capire un passaggio molto più generale:
un modello economico diventa utile quando sappiamo quali ipotesi contiene, come stimarlo, quanto possiamo fidarci dei suoi risultati e quali decisioni può realmente supportare.
La Curva di Phillips: che cosa descrive?
📚 Curva di Phillips, inflazione e disoccupazione
La versione più semplice della Curva di Phillips suggerisce una relazione inversa tra:
- inflazione;
- disoccupazione.
Quando il mercato del lavoro è molto teso e la disoccupazione è bassa, salari e prezzi possono subire maggiori pressioni verso l’alto. Quando la disoccupazione aumenta, queste pressioni tendono invece a ridursi.
La formulazione moderna, che incorpora le aspettative, può essere scritta come:
\begin{aligned}
\pi_t = \pi_t^e – \beta(u_t – u_n) + \varepsilon_t
\end{aligned}
[/math]
dove:
- [math]\pi_t[/math] = inflazione effettiva;
- [math]\pi_t^e[/math] = inflazione attesa;
- [math]u_t[/math] = tasso di disoccupazione;
- [math]u_n[/math] = tasso naturale di disoccupazione o NAIRU;
- [math]\beta > 0[/math] = sensibilità dell’inflazione alle deviazioni della disoccupazione dal suo livello naturale;
- [math]\varepsilon_t[/math] = shock che colpiscono l’economia.
La struttura del modello è semplice da leggere.
Se:
\begin{aligned}
u_t < u_n
\end{aligned}
[/math]
allora:
\begin{aligned}
u_t – u_n < 0
\end{aligned}
[/math]
e quindi il termine:
\begin{aligned}
-\beta(u_t – u_n)
\end{aligned}
[/math]
diventa positivo.
L’inflazione tende quindi a essere superiore alle aspettative.
Se invece:
\begin{aligned}
u_t > u_n
\end{aligned}
[/math]
l’effetto è negativo e l’inflazione tende a essere inferiore a quella attesa.
Questa relazione, però, non deve essere interpretata come una legge meccanica valida in ogni periodo storico.
La Curva di Phillips è un modello. E, come ogni modello, dipende dalle ipotesi.
Prima di usare Python: modello teorico e dati non sono la stessa cosa
Questa distinzione è fondamentale.
Possiamo costruire una curva impostando direttamente:
\begin{aligned}
\pi^e &= 2 \\[4pt]
\beta &= 0.5 \\[4pt]
u_n &= 6
\end{aligned}
[/math]
e calcolare l’inflazione per diversi livelli di disoccupazione.
In questo caso Python esegue semplicemente un modello che abbiamo già definito.
Il flusso è:
scegliamo i parametri → calcoliamo i risultati → visualizziamo la curva.
Quando invece lavoriamo con dati osservati, il problema cambia:
osserviamo inflazione e disoccupazione → stimiamo i parametri → misuriamo l’incertezza → valutiamo il modello.
Questa seconda parte è quella che ci porterà dalla macroeconomia teorica alla Data Science.
Cominciamo comunque dal modello più semplice.
Esercizio 1 — Leggere una Curva di Phillips di breve periodo
Il problema
Supponiamo che un’agenzia di analisi macroeconomica utilizzi per un’economia la seguente Curva di Phillips di breve periodo:
\begin{aligned}
\pi = 2 – 0.5(u – 6)
\end{aligned}
[/math]
Le aspettative di inflazione sono quindi ancorate al 2%.
Vogliamo calcolare l’inflazione quando:
- [math]u = 4\%[/math];
- [math]u = 6\%[/math];
- [math]u = 8\%[/math].
Vogliamo inoltre identificare il livello naturale di disoccupazione e visualizzare la curva.
Soluzione matematica
Confrontiamo l’equazione con la forma generale:
\begin{aligned}
\pi = \pi^e – \beta(u – u_n)
\end{aligned}
[/math]
Otteniamo:
\begin{aligned}
\pi^e &= 2 \\[4pt]
\beta &= 0.5 \\[4pt]
u_n &= 6
\end{aligned}
[/math]
Caso 1: [math]u = 4[/math]
\begin{aligned}
\pi &= 2 – 0.5(4 – 6) \\[4pt]
&= 2 + 1 = 3\%
\end{aligned}
[/math]
La disoccupazione è inferiore al livello naturale e il modello associa questa situazione a una maggiore pressione inflazionistica.
Caso 2: [math]u = 6[/math]
\begin{aligned}
\pi = 2 – 0.5(6 – 6) = 2\%
\end{aligned}
[/math]
Quando:
\begin{aligned}
u = u_n
\end{aligned}
[/math]
l’inflazione coincide con quella attesa.
Caso 3: [math]u = 8[/math]
\begin{aligned}
\pi &= 2 – 0.5(8 – 6) \\[4pt]
&= 1\%
\end{aligned}
[/math]
Una disoccupazione superiore al livello naturale è associata, nel modello, a una minore inflazione.
Implementazione Python
import numpy as np
import matplotlib.pyplot as plt
from dataclasses import dataclass
@dataclass(frozen=True)
class PhillipsCurve:
"""
Curva di Phillips di breve periodo.
Parameters
----------
pi_e : float
Inflazione attesa in punti percentuali.
beta : float
Sensibilità dell'inflazione alla deviazione
della disoccupazione dal livello naturale.
u_n : float
Tasso naturale di disoccupazione.
"""
pi_e: float
beta: float
u_n: float
def __post_init__(self):
if not np.isfinite(self.pi_e):
raise ValueError("pi_e deve essere finito.")
if not np.isfinite(self.beta) or self.beta <= 0:
raise ValueError("beta deve essere positivo e finito.")
if not np.isfinite(self.u_n) or self.u_n < 0:
raise ValueError("u_n deve essere non negativo e finito.")
def predict(self, u: float | np.ndarray) -> np.ndarray:
"""
Calcola l'inflazione prevista.
"""
u = np.asarray(u, dtype=float)
if not np.all(np.isfinite(u)):
raise ValueError("u contiene valori non validi.")
return self.pi_e - self.beta * (u - self.u_n)
# Parametri del modello
pc = PhillipsCurve(
pi_e=2.0,
beta=0.5,
u_n=6.0
)
# Valori da analizzare
u_values = np.array([4.0, 6.0, 8.0])
# Previsioni
pi_values = pc.predict(u_values)
for u, pi in zip(u_values, pi_values):
print(
f"Disoccupazione: {u:.1f}% | "
f"Inflazione prevista: {pi:.2f}%"
)
Output atteso
Disoccupazione: 4.0% | Inflazione prevista: 3.00%
Disoccupazione: 6.0% | Inflazione prevista: 2.00%
Disoccupazione: 8.0% | Inflazione prevista: 1.00%
Validazione del modello
Prima di disegnare un grafico, possiamo verificare che il codice rispetti alcune proprietà teoriche.
assert np.isclose(pc.predict(4.0), 3.0)
assert np.isclose(pc.predict(6.0), 2.0)
assert np.isclose(pc.predict(8.0), 1.0)
print("Tutti i test superati.")
Questi controlli sono semplici, ma introducono una buona abitudine.
Quando implementiamo un modello, non basta ottenere un numero plausibile.
Dobbiamo verificare che il comportamento del codice sia coerente con la teoria.
Visualizzazione
u_grid = np.linspace(2, 10, 200)
pi_grid = pc.predict(u_grid)
plt.figure(figsize=(8, 5))
plt.plot(
u_grid,
pi_grid,
linewidth=2.5,
label="Curva di Phillips"
)
plt.axvline(
pc.u_n,
linestyle="--",
label="NAIRU"
)
plt.axhline(
pc.pi_e,
linestyle=":",
label="Inflazione attesa"
)
plt.scatter(
u_values,
pi_values,
zorder=5
)
plt.xlabel("Disoccupazione (%)")
plt.ylabel("Inflazione (%)")
plt.title("Curva di Phillips di breve periodo")
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
Come leggere il grafico?
La curva è decrescente.
Ma è importante non leggere il grafico come se mostrasse automaticamente una relazione causale.
Il grafico rappresenta il modello che abbiamo imposto.
Non abbiamo ancora dimostrato che nei dati reali la relazione:
\begin{aligned}
\frac{\partial \pi}{\partial u} < 0
\end{aligned}
[/math]
sia stabile, lineare o identica in tutti i periodi.
Questo sarà il passaggio successivo.
Interpretazione decisionale
Supponiamo che la banca centrale osservi una disoccupazione al 4%.
Il modello restituisce:
\begin{aligned}
\pi = 3\%
\end{aligned}
[/math]
La decisione non dovrebbe essere:
L’inflazione sarà certamente del 3%.
La lettura corretta è:
Se le aspettative restano al 2%, il NAIRU è effettivamente al 6% e il parametro [math]\beta[/math] vale 0.5, allora il modello associa una disoccupazione del 4% a un’inflazione del 3%.
La differenza sembra linguistica, ma è sostanziale.
Un modello produce risultati condizionati alle sue ipotesi.
Esercizio 2 — Shock e spostamento della Curva di Phillips
Il problema
Partiamo dalla stessa economia.
Supponiamo ora che si verifichino contemporaneamente due eventi:
- le aspettative di inflazione salgono dal 2% al 3%;
- uno shock energetico aggiunge 1.5 punti percentuali all’inflazione.
Il modello diventa:
\begin{aligned}
\pi = 3 – 0.5(u – 6) + 1.5
\end{aligned}
[/math]
Vogliamo:
- scrivere la nuova equazione;
- confrontarla con quella precedente;
- calcolare quale livello di disoccupazione sarebbe necessario per ottenere [math]\pi = 2\%[/math].
Soluzione
Semplificando:
\begin{aligned}
\pi = 4.5 – 0.5(u – 6)
\end{aligned}
[/math]
Sviluppando ulteriormente:
\begin{aligned}
\pi = 7.5 – 0.5u
\end{aligned}
[/math]
Imponiamo ora:
\begin{aligned}
\pi = 2
\end{aligned}
[/math]
Otteniamo:
\begin{aligned}
2 &= 4.5 – 0.5(u – 6) \\[4pt]
-2.5 &= -0.5(u – 6) \\[4pt]
u – 6 &= 5
\end{aligned}
[/math]
Quindi:
\begin{aligned}
u = 11\%
\end{aligned}
[/math]
Attenzione all’interpretazione
L’11% non è una previsione macroeconomica.
È il risultato del modello sotto ipotesi molto specifiche.
Abbiamo supposto che:
- [math]\beta = 0.5[/math];
- il NAIRU resti al 6%;
- lo shock abbia dimensione fissa;
- le aspettative restino al 3%;
- non esistano effetti dinamici;
- la politica monetaria non modifichi le aspettative.
Quindi il risultato corretto da riportare è:
In questo scenario parametrico, il modello richiede una disoccupazione dell’11% per riportare l’inflazione al 2%.
È molto diverso dal dire:
La banca centrale deve portare la disoccupazione all’11%.
Implementazione Python
pc_old = PhillipsCurve(
pi_e=2.0,
beta=0.5,
u_n=6.0
)
pc_new = PhillipsCurve(
pi_e=3.0,
beta=0.5,
u_n=6.0
)
epsilon = 1.5
u_grid = np.linspace(2, 12, 300)
pi_old = pc_old.predict(u_grid)
pi_new = pc_new.predict(u_grid) + epsilon
target_pi = 2.0
u_target = (
pc_new.pi_e
+ epsilon
- target_pi
) / pc_new.beta + pc_new.u_n
print(
f"Disoccupazione necessaria nel modello: "
f"{u_target:.2f}%"
)
Output
Disoccupazione necessaria nel modello: 11.00%
Grafico
plt.figure(figsize=(8, 5))
plt.plot(
u_grid,
pi_old,
label="Scenario iniziale",
linewidth=2
)
plt.plot(
u_grid,
pi_new,
label="Nuovo scenario",
linewidth=2
)
plt.axhline(
target_pi,
linestyle=":",
label="Target inflazione"
)
plt.axvline(
u_target,
linestyle="--",
label="u richiesto dal modello"
)
plt.scatter(
[u_target],
[target_pi],
zorder=5
)
plt.xlabel("Disoccupazione (%)")
plt.ylabel("Inflazione (%)")
plt.title(
"Come shock e aspettative modificano la Curva di Phillips"
)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
Interpretazione decisionale
Questo esercizio mostra un punto importante.
Uno shock di offerta può modificare il problema della politica economica.
Se l’inflazione aumenta perché la domanda è eccessiva, una politica restrittiva può agire principalmente riducendo la domanda.
Ma uno shock energetico o produttivo può produrre una situazione diversa.
L’inflazione aumenta senza che la banca centrale possa eliminare direttamente la causa dello shock.
Il problema decisionale diventa allora:
Quanto rallentamento economico siamo disposti a tollerare per ridurre un’inflazione generata almeno in parte da uno shock di offerta?
Questa è una domanda di policy. Non una semplice sostituzione in una formula.
Esercizio 3 — Aspettative adattive e accelerazione dell’inflazione
Finora abbiamo considerato le aspettative come un valore fissato.
Ma le aspettative possono cambiare.
Una formulazione semplice è:
\begin{aligned}
\pi_t^e = \pi_{t-1}
\end{aligned}
[/math]
Le persone e le imprese utilizzano quindi l’inflazione osservata nel periodo precedente come riferimento per il periodo successivo.
La Curva di Phillips diventa:
\begin{aligned}
\pi_t = \pi_{t-1} – \beta(u_t – u_n)
\end{aligned}
[/math]
Il problema
Supponiamo:
\begin{aligned}
\pi_0 &= 2\% \\[4pt]
u_t &= 3\% \\[4pt]
u_n &= 5\% \\[4pt]
\beta &= 0.4
\end{aligned}
[/math]
per quattro anni consecutivi.
Soluzione
Poiché:
\begin{aligned}
u_t – u_n = 3 – 5 = -2
\end{aligned}
[/math]
abbiamo:
\begin{aligned}
-\beta(u_t – u_n) = -0.4(-2) = 0.8
\end{aligned}
[/math]
Quindi:
\begin{aligned}
\pi_t = \pi_{t-1} + 0.8
\end{aligned}
[/math]
La traiettoria è:
| Periodo | Inflazione |
|---|---|
| 0 | 2.0% |
| 1 | 2.8% |
| 2 | 3.6% |
| 3 | 4.4% |
| 4 | 5.2% |
La disoccupazione resta costante.
L’inflazione no.
Implementazione Python
def simulate_adaptive(
pi0: float = 2.0,
u: float = 3.0,
u_n: float = 5.0,
beta: float = 0.4,
T: int = 4
) -> np.ndarray:
"""
Simula una Curva di Phillips
con aspettative adattive.
"""
if beta <= 0:
raise ValueError("beta deve essere positivo.")
if T < 1:
raise ValueError("T deve essere almeno 1.")
pi = np.empty(T + 1)
pi[0] = pi0
for t in range(1, T + 1):
pi[t] = (
pi[t - 1]
- beta * (u - u_n)
)
return pi
pi_path = simulate_adaptive()
for t, pi in enumerate(pi_path):
print(f"Anno {t}: inflazione = {pi:.2f}%")
Output
Anno 0: inflazione = 2.00%
Anno 1: inflazione = 2.80%
Anno 2: inflazione = 3.60%
Anno 3: inflazione = 4.40%
Anno 4: inflazione = 5.20%
Grafico della traiettoria
years = np.arange(len(pi_path))
plt.figure(figsize=(8, 5))
plt.plot(
years,
pi_path,
marker="o",
linewidth=2
)
plt.xlabel("Anno")
plt.ylabel("Inflazione (%)")
plt.title(
"Aspettative adattive e accelerazione dell'inflazione"
)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()
Interpretazione
Questo esercizio non dimostra una generica «spirale inflazionistica».
Mostra qualcosa di più preciso.
Se:
- le aspettative coincidono con l’inflazione passata;
- la disoccupazione rimane persistentemente sotto il livello naturale;
- [math]\beta[/math] resta costante;
allora l’inflazione aumenta progressivamente.
Il modello può essere riscritto come:
\begin{aligned}
\Delta\pi_t = -\beta(u_t – u_n)
\end{aligned}
[/math]
Se:
\begin{aligned}
u_t < u_n
\end{aligned}
[/math]
allora:
\begin{aligned}
\Delta\pi_t > 0
\end{aligned}
[/math]
L’inflazione accelera.
Se:
\begin{aligned}
u_t = u_n
\end{aligned}
[/math]
allora:
\begin{aligned}
\Delta\pi_t = 0
\end{aligned}
[/math]
e l’inflazione rimane stabile.
Interpretazione decisionale
Per un decisore il risultato importante non è il valore esatto del 5.2%.
Il punto centrale è la dinamica.
Una politica che mantiene il mercato del lavoro persistentemente oltre il livello compatibile con un’inflazione stabile può produrre effetti che non emergono osservando un singolo anno.
Questo introduce una regola generale per l’analisi dei dati:
Un modello statico può sembrare innocuo. Una dinamica ripetuta nel tempo può produrre conseguenze molto diverse.
Esercizio 4 — Dal modello teorico ai dati: stimare una Curva di Phillips
Finora abbiamo scelto noi il valore di:
\begin{aligned}
\beta
\end{aligned}
[/math]
Ma nella realtà non conosciamo il parametro.
Dobbiamo stimarlo.
Per introdurre il problema senza utilizzare immediatamente un dataset reale, generiamo un dataset sintetico.
Supponiamo che la vera economia segua:
\begin{aligned}
\pi_t = 5 – 0.6u_t + \varepsilon_t
\end{aligned}
[/math]
dove:
\begin{aligned}
\varepsilon_t
\end{aligned}
[/math]
rappresenta shock non osservati.
Creazione del dataset sintetico
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm
rng = np.random.default_rng(seed=42)
n = 120
unemployment = rng.uniform(
low=3,
high=10,
size=n
)
epsilon = rng.normal(
loc=0,
scale=0.8,
size=n
)
inflation = (
5
- 0.6 * unemployment
+ epsilon
)
df = pd.DataFrame({
"unemployment": unemployment,
"inflation": inflation
})
df.head()
Primo controllo visivo
plt.figure(figsize=(8, 5))
plt.scatter(
df["unemployment"],
df["inflation"],
alpha=0.7
)
plt.xlabel("Disoccupazione (%)")
plt.ylabel("Inflazione (%)")
plt.title(
"Inflazione e disoccupazione nel dataset simulato"
)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()
Ora non abbiamo più una linea perfetta.
Abbiamo punti.
Ed è questo il problema reale.
Ogni osservazione contiene:
- una componente sistematica;
- una componente casuale;
- eventuali fattori che il modello non osserva.
Stimiamo il modello
Utilizziamo una regressione lineare:
\begin{aligned}
\pi_t = \alpha + \gamma u_t + \varepsilon_t
\end{aligned}
[/math]
dove ci aspettiamo:
\begin{aligned}
\gamma < 0
\end{aligned}
[/math]
X = sm.add_constant(
df["unemployment"]
)
y = df["inflation"]
model = sm.OLS(
y,
X
).fit()
print(model.summary())
OLS Regression Results
==============================================================================
Dep. Variable: inflation R-squared: 0.670
Model: OLS Adj. R-squared: 0.667
Method: Least Squares F-statistic: 239.3
Date: Fri, 11 Sep 2026 Prob (F-statistic): 3.66e-30
Time: 09:22:58 Log-Likelihood: -144.42
No. Observations: 120 AIC: 292.8
Df Residuals: 118 BIC: 298.4
Df Model: 1
Covariance Type: nonrobust
================================================================================
coef std err t P>|t| [0.025 0.975]
--------------------------------------------------------------------------------
const 5.0032 0.263 19.014 0.000 4.482 5.524
unemployment -0.6016 0.039 -15.469 0.000 -0.679 -0.525
==============================================================================
Omnibus: 3.275 Durbin-Watson: 1.580
Prob(Omnibus): 0.195 Jarque-Bera (JB): 3.215
Skew: 0.395 Prob(JB): 0.200
Kurtosis: 2.868 Cond. No. 24.5
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
Come interpretare l’output?
Il risultato principale sarà il coefficiente associato alla disoccupazione.
Poiché abbiamo costruito i dati con:
\begin{aligned}
-0.6
\end{aligned}
[/math]
ci aspettiamo una stima vicina a questo valore.
Ma non necessariamente identica.
Lo shock casuale introduce variabilità.
Supponiamo, per esempio, di ottenere:
unemployment -0.58
L’interpretazione è:
Nel dataset simulato, un aumento di un punto percentuale della disoccupazione è associato, secondo il modello lineare stimato, a una riduzione media dell’inflazione di circa 0.58 punti percentuali.
La parola importante è associato.
Non abbiamo dimostrato causalità.
Regressione non significa causalità
Questo punto merita una sezione esplicita.
Se stimiamo:
\begin{aligned}
\pi_t = \alpha + \gamma u_t + \varepsilon_t
\end{aligned}
[/math]
e otteniamo:
\begin{aligned}
\gamma < 0
\end{aligned}
[/math]
non possiamo automaticamente concludere che:
aumentando la disoccupazione riduciamo causalmente l’inflazione di [math]|\gamma|[/math].
Perché?
Potrebbero esistere:
- shock che influenzano entrambe le variabili;
- politiche monetarie che reagiscono all’inflazione;
- aspettative non osservate;
- variabili omesse;
- simultaneità.
In altre parole, la regressione descrive una relazione condizionata alla struttura del modello.
Per fare inferenza causale servirebbe un disegno più forte.
Per esempio:
- variabili strumentali;
- esperimenti naturali;
- modelli strutturali;
- disegni quasi-sperimentali.
Interpretazione decisionale
Un decisore non dovrebbe leggere il coefficiente:
\begin{aligned}
-0.58
\end{aligned}
[/math]
come un pulsante.
Non esiste una leva chiamata «aumenta la disoccupazione di un punto».
Il coefficiente può essere utile per:
- costruire scenari;
- confrontare periodi;
- identificare relazioni storiche;
- verificare la stabilità del modello.
Ma trasformare direttamente un coefficiente statistico in una politica economica sarebbe un errore.
Esercizio 5 — Quanto è buono il modello?
Una volta stimata una regressione, la domanda successiva non è:
Il coefficiente è statisticamente significativo?
La domanda è:
Il modello è utile?
Non esiste una sola risposta.
Valuteremo tre aspetti:
- Fit;
- Calibrazione;
- Decision Value.
Fit: quanto bene il modello descrive i dati?
Calcoliamo le previsioni.
df["prediction"] = model.predict(X)
df["residual"] = (
df["inflation"]
- df["prediction"]
)
Ora possiamo calcolare:
- MAE;
- RMSE;
- [math]R^2[/math].
from sklearn.metrics import (
mean_absolute_error,
mean_squared_error,
r2_score
)
mae = mean_absolute_error(
df["inflation"],
df["prediction"]
)
rmse = mean_squared_error(
df["inflation"],
df["prediction"]
) ** 0.5
r2 = r2_score(
df["inflation"],
df["prediction"]
)
print(f"MAE: {mae:.3f}")
print(f"RMSE: {rmse:.3f}")
print(f"R²: {r2:.3f}")
MAE: 0.642
RMSE: 0.806
R²: 0.670
Come leggere queste metriche?
MAE
Il MAE misura l’errore assoluto medio.
Se:
MAE = 0.642
significa che, mediamente, le previsioni differiscono dall’inflazione osservata di circa 0.6 punti percentuali.
RMSE
L’RMSE penalizza maggiormente gli errori grandi.
Se il modello commette raramente errori molto elevati, questa metrica può essere più severa del MAE.
R²
L’[math]R^2[/math] misura quanta variabilità del target viene spiegata dal modello.
Ma un buon [math]R^2[/math] non garantisce:
- causalità;
- stabilità futura;
- utilità decisionale.
Questa distinzione è fondamentale.
Calibrazione: il modello sovrastima o sottostima?
Un modello può avere un buon RMSE ma produrre errori sistematici.
Per verificarlo confrontiamo:
\begin{aligned}
\pi_{osservata}
\end{aligned}
[/math]
con:
\begin{aligned}
\hat{\pi}
\end{aligned}
[/math]
plt.figure(figsize=(7, 7))
plt.scatter(
df["prediction"],
df["inflation"],
alpha=0.7
)
min_value = min(
df["prediction"].min(),
df["inflation"].min()
)
max_value = max(
df["prediction"].max(),
df["inflation"].max()
)
plt.plot(
[min_value, max_value],
[min_value, max_value],
linestyle="--"
)
plt.xlabel("Inflazione prevista")
plt.ylabel("Inflazione osservata")
plt.title(
"Calibrazione: osservato vs previsto"
)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()

La linea diagonale rappresenta:
\begin{aligned}
osservato = previsto
\end{aligned}
[/math]
Se i punti sono sistematicamente sopra la linea, il modello tende a sottostimare.
Se sono sistematicamente sotto, tende a sovrastimare.
Interpretazione decisionale
Immaginiamo due modelli.
Modello A
RMSE leggermente migliore.
Ma tende a sottostimare l’inflazione durante i periodi più critici.
Modello B
RMSE leggermente peggiore.
Ma individua meglio le fasi di forte accelerazione.
Quale scegliamo?
Dipende dalla decisione.
Per una banca centrale, sottostimare sistematicamente un’accelerazione inflazionistica può essere molto più costoso di un piccolo errore medio aggiuntivo.
Ed è qui che entra il terzo elemento.
Decision Value: un modello utile per chi?
La qualità statistica non coincide automaticamente con il valore decisionale.
Supponiamo che il target di inflazione sia:
\begin{aligned}
2\%
\end{aligned}
[/math]
e che un decisore consideri particolarmente costoso sottostimare l’inflazione quando supera il 4%.
Possiamo definire una funzione di perdita semplice.
threshold = 4.0
actual = df["inflation"].to_numpy()
predicted = df["prediction"].to_numpy()
absolute_error = np.abs(
actual - predicted
)
high_inflation_error = np.where(
actual > threshold,
absolute_error * 2,
absolute_error
)
decision_loss = high_inflation_error.mean()
print(
f"Decision Loss: "
f"{decision_loss:.3f}"
)
Qui stiamo facendo una scelta esplicita.
Gli errori non hanno tutti lo stesso costo.
Un errore di:
\begin{aligned}
0.5
\end{aligned}
[/math]
punti percentuali può essere tollerabile in un periodo di bassa inflazione.
Lo stesso errore può essere molto più rilevante se l’inflazione sta accelerando rapidamente.
Fit, Calibrazione e Decision Value
Possiamo quindi riassumere il modello con tre domande.
Fit
Quanto sono vicine, in media, le previsioni ai dati?
Metriche:
- MAE;
- RMSE;
- [math]R^2[/math].
Calibrazione
Il modello tende sistematicamente a sovrastimare o sottostimare?
Analizziamo:
- osservato vs previsto;
- bias;
- residui.
Decision Value
Gli errori più importanti per la decisione vengono gestiti bene?
Definiamo:
- soglie;
- costi;
- scenari;
- funzioni di perdita.
Esercizio 6 — Analisi dei residui
I residui sono:
\begin{aligned}
e_t = \pi_t – \hat{\pi}_t
\end{aligned}
[/math]
Rappresentano la parte dell’inflazione che il modello non riesce a spiegare.
Visualizziamoli.
plt.figure(figsize=(8, 5))
plt.scatter(
df["prediction"],
df["residual"],
alpha=0.7
)
plt.axhline(
0,
linestyle="--"
)
plt.xlabel("Inflazione prevista")
plt.ylabel("Residuo")
plt.title(
"Analisi dei residui"
)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()
Cosa cerchiamo?
Idealmente i residui dovrebbero apparire:
- distribuiti attorno allo zero;
- senza pattern evidenti;
- senza una struttura sistematica.
Se invece osserviamo una curva nei residui, potrebbe significare che una relazione lineare non è sufficiente.
Se la variabilità aumenta con l’inflazione, potremmo avere eteroschedasticità.
Se lavoriamo con dati temporali, potremmo avere autocorrelazione.
In altre parole:
il grafico dei residui spesso ci dice ciò che il [math]R^2[/math] non riesce a dirci.
Interpretazione decisionale
Se un modello sbaglia sempre nello stesso tipo di situazione, il problema non è soltanto statistico.
È operativo.
Un modello che funziona bene durante periodi tranquilli ma fallisce sistematicamente durante shock energetici potrebbe essere poco utile proprio quando il decisore ha più bisogno di supporto.
Esercizio 7 — La Curva di Phillips non è necessariamente stabile
Un errore frequente consiste nello stimare un parametro su molti anni e trattarlo come se fosse una costante economica universale.
Possiamo invece stimare il modello su finestre mobili.
L’idea è semplice.
Stimiamo:
\begin{aligned}
\pi_t = \alpha + \gamma u_t + \varepsilon_t
\end{aligned}
[/math]
su:
- primi 40 periodi;
- poi periodi 2–41;
- poi 3–42;
e così via.
Rolling regression
window = 40
rolling_beta = []
rolling_index = []
for start in range(
len(df) - window + 1
):
subset = df.iloc[
start:start + window
]
X_subset = sm.add_constant(
subset["unemployment"]
)
y_subset = subset["inflation"]
result = sm.OLS(
y_subset,
X_subset
).fit()
rolling_beta.append(
result.params["unemployment"]
)
rolling_index.append(
start + window
)
plt.figure(figsize=(9, 5))
plt.plot(
rolling_index,
rolling_beta
)
plt.axhline(
0,
linestyle="--"
)
plt.xlabel("Fine della finestra")
plt.ylabel("Coefficiente stimato")
plt.title(
"Stabilità del coefficiente della disoccupazione"
)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()
Come interpretare il risultato?
Se il coefficiente rimane relativamente stabile, il modello può avere una relazione robusta almeno all’interno del periodo analizzato.
Se cambia molto:
\begin{aligned}
-0.2 \rightarrow -0.8 \rightarrow +0.1
\end{aligned}
[/math]
allora dobbiamo porci una domanda.
Stiamo davvero stimando una relazione stabile?
Oppure il sistema economico è cambiato?
Interpretazione decisionale
Un parametro instabile rende rischioso utilizzare una singola stima per decisioni di lungo periodo.
In questo caso potrebbe essere preferibile:
- utilizzare scenari;
- stimare modelli diversi per periodi diversi;
- usare coefficienti dinamici;
- aggiornare frequentemente le stime.
Un numero molto preciso può essere meno utile di un intervallo realistico.
Esercizio 8 — Il NAIRU non è direttamente osservabile
Negli esercizi precedenti abbiamo impostato:
\begin{aligned}
u_n = 6\%
\end{aligned}
[/math]
Ma nella realtà il problema è più complesso.
Il NAIRU non appare normalmente in una colonna di un dataset insieme a:
Anno
Inflazione
Disoccupazione
NAIRU
Il NAIRU è una quantità stimata.
Può cambiare nel tempo a causa di:
- struttura del mercato del lavoro;
- produttività;
- mismatch tra domanda e offerta di competenze;
- istituzioni;
- composizione demografica;
- mobilità;
- dinamiche salariali.
Questo significa che:
\begin{aligned}
u_n
\end{aligned}
[/math]
può essere una variabile latente.
Una semplice analisi di sensibilità
Supponiamo di non sapere se il NAIRU sia:
- 5%;
- 6%;
- 7%.
Calcoliamo la curva per tutti e tre gli scenari.
u_grid = np.linspace(
2,
10,
200
)
nairu_values = [
5.0,
6.0,
7.0
]
beta = 0.5
pi_e = 2.0
plt.figure(figsize=(8, 5))
for u_n in nairu_values:
pi = (
pi_e
- beta * (u_grid - u_n)
)
plt.plot(
u_grid,
pi,
label=f"NAIRU = {u_n:.0f}%"
)
plt.xlabel("Disoccupazione (%)")
plt.ylabel("Inflazione (%)")
plt.title(
"Sensibilità della Curva di Phillips al NAIRU"
)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
Interpretazione
Il risultato mostra una forma di incertezza diversa da quella degli shock casuali.
Non siamo incerti soltanto sul futuro.
Siamo incerti anche sui parametri del modello.
Questo è un punto centrale nel modeling.
Possiamo distinguere almeno due forme di incertezza.
Incertezza sugli eventi
Per esempio:
\begin{aligned}
\varepsilon_t
\end{aligned}
[/math]
Lo shock futuro non è noto.
Incertezza sui parametri
Per esempio:
\begin{aligned}
\beta
\end{aligned}
[/math]
oppure:
\begin{aligned}
u_n
\end{aligned}
[/math]
Non conosciamo esattamente il valore corretto.
Interpretazione decisionale
Se una decisione cambia completamente passando da:
\begin{aligned}
u_n = 5\%
\end{aligned}
[/math]
a:
\begin{aligned}
u_n = 6\%
\end{aligned}
[/math]
allora la decisione è fragile rispetto all’incertezza del parametro.
In questi casi è più utile presentare:
se il NAIRU è vicino al 5%, scenario A;
se è vicino al 6%, scenario B;
se è vicino al 7%, scenario C.
Questo approccio è spesso più onesto e più utile di una singola previsione apparentemente precisa.
Esercizio 9 — Simulazione Monte Carlo della dinamica inflazionistica
Introduciamo ora gli shock casuali.
Consideriamo una Curva di Phillips con aspettative adattive:
\begin{aligned}
\pi_t = \pi_{t-1} – \beta(u – u_n) + \varepsilon_t
\end{aligned}
[/math]
dove:
- [math]\pi_t[/math] è l’inflazione al tempo [math]t[/math];
- [math]\pi_{t-1}[/math] è l’inflazione del periodo precedente;
- [math]u[/math] è il tasso di disoccupazione;
- [math]u_n[/math] è il livello naturale di disoccupazione;
- [math]\beta[/math] misura la sensibilità dell’inflazione alla disoccupazione;
- [math]\varepsilon_t[/math] è uno shock casuale.
Assumiamo che gli shock seguano una distribuzione normale:
\begin{aligned}
\varepsilon_t \sim N(0, \sigma^2)
\end{aligned}
[/math]
Il valore futuro dello shock non è noto. Possiamo però simulare molte possibili traiettorie dell’inflazione e analizzare la distribuzione dei risultati.
Ipotesi dello scenario
Supponiamo:
\begin{aligned}
\pi_0 &= 2\% \\[4pt]
u &= 4\% \\[4pt]
u_n &= 5\% \\[4pt]
\beta &= 0.4
\end{aligned}
[/math]
e:
\begin{aligned}
\sigma = 0.5
\end{aligned}
[/math]
Simuleremo l’inflazione per quattro anni e costruiremo 10.000 possibili traiettorie.
Poiché la disoccupazione è inferiore al livello naturale:
\begin{aligned}
u – u_n = 4 – 5 = -1
\end{aligned}
[/math]
l’effetto deterministico sull’inflazione è:
\begin{aligned}
-\beta(u – u_n) = -0.4(-1) = 0.4
\end{aligned}
[/math]
In assenza di shock, l’inflazione aumenterebbe quindi di 0,4 punti percentuali ogni anno:
2.0% → 2.4% → 2.8% → 3.2% → 3.6%
Gli shock casuali fanno però variare ogni traiettoria rispetto a questo percorso centrale.
Implementazione Monte Carlo
import numpy as np
def simulate_monte_carlo(
pi0: float,
u: float,
u_n: float,
beta: float,
sigma: float,
T: int,
n_simulations: int,
seed: int = 42
) -> np.ndarray:
"""
Simula molte traiettorie dell'inflazione
con aspettative adattive e shock casuali.
Returns
-------
np.ndarray
Matrice di dimensione
(n_simulations, T + 1).
Ogni riga rappresenta una traiettoria.
La prima colonna contiene l'inflazione iniziale.
"""
values = [pi0, u, u_n, beta, sigma]
if not all(np.isfinite(value) for value in values):
raise ValueError(
"Tutti i parametri numerici devono essere finiti."
)
if beta <= 0:
raise ValueError(
"beta deve essere positivo."
)
if sigma < 0:
raise ValueError(
"sigma deve essere non negativo."
)
if not isinstance(T, int) or T < 1:
raise ValueError(
"T deve essere un intero almeno pari a 1."
)
if not isinstance(n_simulations, int) or n_simulations < 1:
raise ValueError(
"n_simulations deve essere un intero almeno pari a 1."
)
rng = np.random.default_rng(seed)
paths = np.empty(
(n_simulations, T + 1)
)
paths[:, 0] = pi0
deterministic_effect = (
-beta * (u - u_n)
)
for t in range(1, T + 1):
shocks = rng.normal(
loc=0.0,
scale=sigma,
size=n_simulations
)
paths[:, t] = (
paths[:, t - 1]
+ deterministic_effect
+ shocks
)
return paths
Eseguiamo la simulazione:
paths = simulate_monte_carlo(
pi0=2.0,
u=4.0,
u_n=5.0,
beta=0.4,
sigma=0.5,
T=4,
n_simulations=10_000,
seed=42
)
Analisi dei risultati
Consideriamo l’inflazione al termine del quarto anno:
final_inflation = paths[:, -1]
median = np.median(
final_inflation
)
p05 = np.percentile(
final_inflation,
5
)
p95 = np.percentile(
final_inflation,
95
)
probability_above_5 = np.mean(
final_inflation > 5.0
)
print(
f"Inflazione mediana: "
f"{median:.2f}%"
)
print(
f"5° percentile: "
f"{p05:.2f}%"
)
print(
f"95° percentile: "
f"{p95:.2f}%"
)
print(
f"P(π > 5%): "
f"{probability_above_5:.2%}"
)
Output
Con seed=42 e 10.000 simulazioni, otteniamo:
Inflazione mediana: 3.60%
5° percentile: 1.97%
95° percentile: 5.26%
P(π > 5%): 8.33%
I valori possono cambiare leggermente se modifichiamo il seme casuale o il numero di simulazioni. Il valore di seed=42 serve a rendere l’esempio riproducibile.
Come interpretare il risultato?
La traiettoria deterministica, cioè quella senza shock, porta l’inflazione al 3,6% dopo quattro anni.
La simulazione Monte Carlo mostra invece una distribuzione di risultati possibili:
- la mediana dell’inflazione finale è pari al 3,60%;
- il 5% delle simulazioni produce un’inflazione inferiore a circa il 1,97%;
- il 95% delle simulazioni produce un’inflazione inferiore a circa il 5,26%;
- la probabilità stimata di superare il 5% è pari a circa l’8,33%.
L’intervallo compreso tra il 5° e il 95° percentile non è una previsione certa. Rappresenta un intervallo di scenari compatibile con le ipotesi del modello e con la distribuzione degli shock scelta.
È importante inoltre distinguere tra:
- incertezza parametrica, dovuta al fatto che valori come [math]\beta[/math] e [math]u_n[/math] potrebbero non essere conosciuti con precisione;
- incertezza sugli shock, dovuta al fatto che gli eventi futuri [math]\varepsilon_t[/math] non sono prevedibili esattamente.
In questo esercizio stiamo simulando soltanto la seconda forma di incertezza. I parametri [math]\beta[/math], [math]u_n[/math], [math]\sigma[/math] e il tasso di disoccupazione sono mantenuti fissi.
Perché questo risultato è più informativo di una singola previsione?
Una previsione deterministica potrebbe indicare:
\begin{aligned}
\pi_4 = 3.6\%
\end{aligned}
[/math]
Questa informazione descrive soltanto il percorso centrale del modello.
La simulazione Monte Carlo aggiunge invece:
- una mediana;
- un intervallo di scenari;
- una misura della dispersione;
- una probabilità di superare una soglia critica.
Passiamo quindi dalla domanda:
Quale sarà l’inflazione?
a una domanda più utile:
Quali risultati sono plausibili e qual è la probabilità che l’inflazione superi una determinata soglia?
Visualizzazione delle simulazioni
import matplotlib.pyplot as plt
years = np.arange(
paths.shape[1]
)
plt.figure(figsize=(9, 5))
for i in range(100):
plt.plot(
years,
paths[i],
color="steelblue",
alpha=0.08
)
median_path = np.median(
paths,
axis=0
)
p05_path = np.percentile(
paths,
5,
axis=0
)
p95_path = np.percentile(
paths,
95,
axis=0
)
plt.plot(
years,
median_path,
color="black",
linewidth=2.5,
label="Mediana"
)
plt.plot(
years,
p05_path,
color="darkorange",
linestyle="--",
label="5° percentile"
)
plt.plot(
years,
p95_path,
color="darkorange",
linestyle="--",
label="95° percentile"
)
plt.axhline(
5.0,
color="red",
linestyle=":",
label="Soglia del 5%"
)
plt.xlabel("Anno")
plt.ylabel("Inflazione (%)")
plt.title(
"Scenari Monte Carlo dell'inflazione"
)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()

Il grafico mostra alcune traiettorie individuali, la traiettoria mediana e l’intervallo compreso tra il 5° e il 95° percentile.
Interpretazione decisionale
Supponiamo che un decisore consideri particolarmente rischioso superare il 5% di inflazione.
Il risultato della simulazione indica una probabilità stimata dell’8,33% nello scenario considerato. Questo valore non determina automaticamente una decisione di politica economica.
La risposta dipende dal costo attribuito ai diversi scenari.
Un decisore prudente potrebbe ritenere l’8,33% un rischio troppo elevato e richiedere ulteriori misure o informazioni.
Un decisore più tollerante al rischio potrebbe considerare il valore compatibile con una strategia di attesa e monitoraggio.
La stessa distribuzione può quindi portare a decisioni diverse, perché la decisione dipende anche da:
- soglie di rischio;
- costi degli errori;
- durata dello scenario;
- affidabilità dei parametri;
- disponibilità di informazioni aggiuntive.
Il modello non decide al posto del decisore.
Il modello rende più espliciti:
- gli scenari possibili;
- le ipotesi utilizzate;
- l’incertezza;
- il rischio di superare una soglia;
- il rapporto tra costi e benefici delle alternative.
Nota metodologica
Il risultato Monte Carlo dipende dalle ipotesi del modello. In particolare, qui assumiamo che:
- la disoccupazione rimanga costante;
- il livello naturale [math]u_n[/math] rimanga costante;
- il coefficiente [math]\beta[/math] rimanga costante;
- gli shock siano indipendenti;
- gli shock seguano una distribuzione normale;
- la deviazione standard degli shock sia pari a 0,5.
Queste ipotesi sono utili per costruire un esercizio riproducibile, ma non devono essere interpretate come una descrizione completa dell’economia reale.
Una simulazione più realistica potrebbe includere:
- disoccupazione variabile nel tempo;
- shock persistenti o autocorrelati;
- incertezza su [math]\beta[/math];
- incertezza sul NAIRU;
- cambiamenti nelle aspettative;
- shock energetici separati dagli altri shock;
- parametri stimati da dati reali.
La simulazione Monte Carlo non elimina l’incertezza. La rende invece visibile e quantificabile.
Esercizio 10 — Analisi di sensibilità del parametro β
Il parametro:
\begin{aligned}
\beta
\end{aligned}
[/math]
determina quanto l’inflazione risponde alla distanza tra:
\begin{aligned}
u
\end{aligned}
[/math]
e:
\begin{aligned}
u_n
\end{aligned}
[/math]
Ma raramente conosciamo il suo valore con certezza.
Confrontiamo:
\begin{aligned}
\beta &= 0.2 \\[4pt]
\beta &= 0.5 \\[4pt]
\beta &= 0.8
\end{aligned}
[/math]
u_grid = np.linspace(
2,
10,
200
)
beta_values = [
0.2,
0.5,
0.8
]
pi_e = 2.0
u_n = 6.0
plt.figure(figsize=(8, 5))
for beta in beta_values:
pi = (
pi_e
- beta * (u_grid - u_n)
)
plt.plot(
u_grid,
pi,
label=f"β = {beta}"
)
plt.xlabel("Disoccupazione (%)")
plt.ylabel("Inflazione (%)")
plt.title(
"Analisi di sensibilità del parametro β"
)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
Come cambia la curva?
Con un valore basso di:
\begin{aligned}
\beta
\end{aligned}
[/math]
la curva è più piatta.
L’inflazione reagisce meno alle variazioni della disoccupazione.
Con un valore elevato la curva è più ripida.
Interpretazione decisionale
Questo grafico può cambiare completamente la valutazione di una politica.
Supponiamo di voler ridurre l’inflazione aumentando la disoccupazione.
Se:
\begin{aligned}
\beta = 0.2
\end{aligned}
[/math]
l’effetto previsto è relativamente limitato.
Se:
\begin{aligned}
\beta = 0.8
\end{aligned}
[/math]
l’effetto è molto più forte.
Quindi, prima di discutere:
Quanto dobbiamo intervenire?
dobbiamo chiederci:
Quanto siamo sicuri del parametro che collega l’intervento al risultato?
Cosa possiamo imparare dalla Curva di Phillips?
A questo punto possiamo distinguere diversi livelli.
Livello 1 — Il modello teorico
La Curva di Phillips fornisce una struttura:
\begin{aligned}
\pi_t = \pi_t^e – \beta(u_t – u_n) + \varepsilon_t
\end{aligned}
[/math]
Ci aiuta a ragionare su:
- aspettative;
- disoccupazione;
- inflazione;
- shock.
Livello 2 — La simulazione
Fissiamo i parametri.
Vediamo le conseguenze delle ipotesi.
Possiamo costruire:
- scenari;
- grafici;
- dinamiche temporali.
Livello 3 — La stima statistica
Utilizziamo dati per stimare:
- coefficienti;
- intervalli;
- errori.
Qui il modello smette di essere soltanto una formula.
Livello 4 — La validazione
Verifichiamo:
- MAE;
- RMSE;
- [math]R^2[/math];
- residui;
- calibrazione;
- stabilità.
Livello 5 — La decisione
Chiediamo:
Quale errore costa di più?
Quale scenario è accettabile?
Quanto è robusta la decisione rispetto all’incertezza?
Fit, Calibrazione e Decision Value: sintesi finale
| Dimensione | Domanda | Strumenti |
|---|---|---|
| Fit | Il modello descrive bene i dati? | MAE, RMSE, R² |
| Calibrazione | Sovrastima o sottostima sistematicamente? | Osservato vs previsto, bias |
| Stabilità | I parametri cambiano nel tempo? | Rolling regression |
| Incertezza | Quali scenari sono plausibili? | Monte Carlo, percentili |
| Decision Value | Il modello aiuta davvero una decisione? | Loss function, soglie, scenari |
Cosa facciamo con questo modello?
Questa è forse la domanda più importante.
Una buona analisi non dovrebbe terminare con:
β = -0.58
p-value < 0.05
R² = 0.42
Dovrebbe continuare.
Situazione 1 — Il coefficiente è negativo ma instabile
Cosa significa?
La relazione esiste nel campione, ma cambia nel tempo.
Cosa facciamo?
Evitiamo di utilizzare un unico parametro storico.
Consideriamo:
- finestre mobili;
- scenari;
- modelli dinamici.
Situazione 2 — Il RMSE è buono ma il modello sottostima le crisi
Cosa significa?
Il modello funziona mediamente bene, ma fallisce nelle situazioni più importanti.
Cosa facciamo?
Cambiamo la funzione di valutazione.
Non ottimizziamo soltanto l’errore medio.
Situazione 3 — Il NAIRU è molto incerto
Cosa significa?
La decisione dipende fortemente da una variabile non direttamente osservabile.
Cosa facciamo?
Utilizziamo intervalli e analisi di sensibilità.
Situazione 4 — Gli shock dominano la dinamica
Cosa significa?
La relazione media tra inflazione e disoccupazione spiega solo una parte del problema.
Cosa facciamo?
Introduciamo:
- scenari;
- distribuzioni;
- Monte Carlo;
- variabili aggiuntive.
Limiti del modello
La Curva di Phillips è utile.
Ma non è sufficiente per descrivere tutta l’inflazione.
Il modello semplice utilizzato in questo articolo non include esplicitamente:
- dinamica salariale;
- produttività;
- prezzi delle materie prime;
- politica fiscale;
- tassi di interesse;
- tasso di cambio;
- shock geopolitici;
- aspettative razionali;
- struttura settoriale;
- cambiamenti tecnologici.
Inoltre, una regressione tra inflazione e disoccupazione non identifica automaticamente una relazione causale.
Questo non rende inutile il modello.
Rende necessario usarlo per ciò che è:
una rappresentazione semplificata di un sistema complesso.
Conclusione
La Curva di Phillips viene spesso presentata come una semplice relazione inversa tra inflazione e disoccupazione.
Ma quando proviamo a utilizzarla con Python e con i dati, scopriamo che il problema è più interessante.
Prima scegliamo una formula.
Poi dobbiamo stimare i parametri.
Poi dobbiamo capire quanto sono incerti.
Poi dobbiamo verificare se il modello continua a funzionare.
Infine dobbiamo decidere quale tipo di errore siamo disposti ad accettare.
È qui che un esercizio di macroeconomia diventa un problema di Data Science.
La lezione più importante non è che:
\begin{aligned}
\pi \downarrow \quad \text{quando} \quad u \uparrow
\end{aligned}
[/math]
La lezione più importante è un’altra:
un modello non diventa utile quando produce un numero. Diventa utile quando sappiamo interpretare le ipotesi che hanno prodotto quel numero, misurare la sua incertezza e capire se può migliorare una decisione reale.
La Curva di Phillips è quindi un ottimo esempio di come possano incontrarsi:
- teoria economica;
- statistica;
- Python;
- simulazione;
- econometria;
- analisi dell’incertezza;
- decision science.
Ed è proprio in questo passaggio, dalla formula alla decisione, che i dati iniziano davvero a diventare conoscenza.
Domande di riflessione
1. Se una regressione stima un coefficiente negativo tra disoccupazione e inflazione, possiamo concludere che aumentare la disoccupazione riduce causalmente l’inflazione?
No. Il coefficiente descrive una relazione statistica condizionata al modello. Possono esistere simultaneità, variabili omesse e shock comuni.
2. Un modello con RMSE più basso è sempre il migliore?
No. Può avere un buon errore medio ma fallire sistematicamente nelle situazioni che hanno il maggiore costo decisionale.
3. Perché il NAIRU introduce incertezza anche se osserviamo perfettamente la disoccupazione?
Perché il NAIRU non è normalmente osservato direttamente. È una quantità stimata e dipende dal modello e dalle ipotesi utilizzate.
4. Perché usare Monte Carlo invece di una sola previsione?
Perché molte decisioni dipendono dalla distribuzione dei risultati possibili e dalla probabilità di superare soglie critiche, non soltanto dal valore medio.
5. Qual è la differenza tra incertezza sugli shock e incertezza sui parametri?
Gli shock rappresentano eventi futuri non prevedibili con precisione. L’incertezza sui parametri riguarda invece il fatto che non conosciamo esattamente i valori corretti del modello, come [math]\beta[/math] o [math]u_n[/math].
Esercizio finale
Hai stimato una Curva di Phillips e ottenuto:
Coefficiente disoccupazione: -0.42
R²: 0.38
RMSE: 0.74
MAE: 0.56
La rolling regression mostra però che il coefficiente varia nel tempo tra:
-0.15
e
-0.80
Inoltre il modello tende a sottostimare l’inflazione durante gli shock energetici.
Domande
- Utilizzeresti il coefficiente -0.42 come parametro fisso per una previsione a cinque anni?
- Quali problemi emergono dalla rolling regression?
- Perché un RMSE di 0.74 potrebbe essere insufficiente per valutare il modello?
- Come modificheresti il modello?
- Quali scenari simuleresti prima di prendere una decisione?
La soluzione più interessante non consiste nel trovare un singolo numero corretto.
Consiste nel progettare un processo migliore:
stimare → validare → analizzare l’incertezza → confrontare scenari → decidere.
Ed è questo, in fondo, uno dei compiti più importanti della Data Science.











