Errore di specificazione#

Definizione#

L’errore di specificazione che si verifica quando una variabile importante è omessa dal modello può portare a stime dei coefficienti che sono sistematicamente distorte e inconsistenti.

import warnings

import arviz as az
import bambi as bmb
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pingouin as pg

warnings.filterwarnings("ignore")
# set seed to make the results fully reproducible
seed: int = sum(map(ord, "specification_error"))
rng: np.random.Generator = np.random.default_rng(seed=seed)

az.style.use("arviz-darkgrid")
plt.rcParams["figure.dpi"] = 100
plt.rcParams["figure.facecolor"] = "white"

%config InlineBackend.figure_format = "retina"

Dimostrazione#

La dimostrazione algebrica dell’errore di specificazione nel modello di regressione, in caso di omissione di una variabile rilevante, coinvolge l’analisi delle conseguenze che questa omissione ha sulla stima dei coefficienti di regressione.

Quando un modello di regressione omette una variabile rilevante che è correlata sia con la variabile dipendente \( Y \) sia con almeno una delle variabili indipendenti incluse nel modello, il coefficiente stimato per le variabili indipendenti incluse può essere sistematicamente distorto.

Per comprendere il bias causato dall’omissione di una variabile rilevante in un modello di regressione, è essenziale analizzare dettagliatamente il calcolo delle covarianze e varianze coinvolte. Di seguito viene fornita una spiegazione dei passaggi algebrici che portano alla formulazione del bias di omissione variabile (Omitted Variable Bias, OVB).

Modello Completo e Modello Ridotto#

  1. Modello Completo:

    \[ Y = \beta_0 + \beta_1 X + \beta_2 Z + \epsilon \]

    Qui, \( Y \) è la variabile dipendente, \( X \) e \( Z \) sono variabili indipendenti, \( \beta_0, \beta_1, \beta_2 \) sono i coefficienti, e \( \epsilon \) è il termine di errore.

  2. Modello Ridotto (con omissione di \( Z \)):

    \[ Y = \alpha_0 + \alpha_1 X + u \]

    dove \( u = \beta_2 Z + \epsilon \) rappresenta il nuovo termine di errore che ora include l’effetto non osservato di \( Z \).

Decomposizione di \( X \)#

Ipotesi:

\[ X = \gamma_0 + \gamma_1 Z + V \]

dove \( V \) è una parte di \( X \) indipendente da \( Z \), quindi \( \text{Cov}(V, Z) = 0 \).

Sostituzione nel Modello Ridotto#

Sostituendo la decomposizione di \( X \) nel modello ridotto, otteniamo:

\[ Y = \alpha_0 + \alpha_1 (\gamma_0 + \gamma_1 Z + V) + u \]
\[ Y = \alpha_0 + \alpha_1 \gamma_0 + \alpha_1 \gamma_1 Z + \alpha_1 V + \beta_2 Z + \epsilon \]
\[ Y = (\alpha_0 + \alpha_1 \gamma_0) + (\alpha_1 \gamma_1 + \beta_2) Z + \alpha_1 V + \epsilon \]

Calcolo della Covarianza \( \text{Cov}(Y, X) \)#

\[ \text{Cov}(Y, X) = \text{Cov}(\beta_1 X + \beta_2 Z + \epsilon, X) \]
\[ \text{Cov}(Y, X) = \beta_1 \text{Var}(X) + \beta_2 \text{Cov}(Z, X) \]

dove si usa che \( \text{Cov}(\epsilon, X) = 0 \) poiché \( \epsilon \) è indipendente da \( X \).

Calcolo della Varianza di \( X \)#

\[ \text{Var}(X) = \text{Var}(\gamma_0 + \gamma_1 Z + V) \]
\[ \text{Var}(X) = \gamma_1^2 \text{Var}(Z) + \text{Var}(V) \]

Ancora, \( \text{Cov}(Z, V) = 0 \) perché \( V \) è definito come indipendente da \( Z \).

Formula del Coefficiente Stimato \( \hat{\alpha}_1 \)#

\[ \hat{\alpha}_1 = \frac{\text{Cov}(Y, X)}{\text{Var}(X)} \]
\[ \hat{\alpha}_1 = \beta_1 + \beta_2 \frac{\text{Cov}(Z, X)}{\text{Var}(X)} \]

Interpretazione del Bias#

Il bias nel coefficiente stimato \( \alpha_1 \), rispetto al vero coefficiente \( \beta_1 \), è dato da:

\[ \text{Bias}(\hat{\alpha}_1) = \beta_2 \frac{\text{Cov}(Z, X)}{\text{Var}(X)} \]

Questo risultato dimostra che il bias è direttamente proporzionale al coefficiente \( \beta_2 \) della variabile omessa \( Z \) e al rapporto di covarianza tra \( Z \) e \( X \) diviso per la varianza di \( X \). Questo bias può essere positivo o negativo a seconda della direzione della correlazione tra \( X \) e \( Z\), e della grandezza di \( \beta_2 \).

Conclusioni#

In sintesi, l’omissione di \( Z \) introduce un bias nella stima di \( \alpha_1 \) che non riflette accuratamente \( \beta_1 \) se \( Z \) è correlata sia con \( Y \) che con \( X \). Questo errore di specificazione può portare a conclusioni errate sull’effetto di \( X \) su \( Y \) e compromettere l’accuratezza delle inferenze tratte dal modello di regressione.

Un esempio numerico#

Immaginiamo di analizzare l’impatto di due variabili indipendenti, la motivazione e l’ansia, sulla prestazione in un compito specifico. Supponiamo che l’ansia influenzi negativamente la prestazione, mentre la motivazione abbia un effetto positivo.

La nostra simulazione evidenzia due scenari distinti:

  1. Modello Completo: Quando sia la motivazione che l’ansia sono incluse nel modello di regressione, il coefficiente di regressione per l’ansia viene stimato correttamente come negativo, riflettendo il suo impatto negativo sulla prestazione. Questo conferma che, quando tutte le variabili rilevanti sono presenti, la stima dei loro effetti è accurata e non distorta.

  2. Modello Ridotto (omissione della motivazione): Se la motivazione, che è positivamente correlata alla prestazione e positivamente correlata all’ansia, viene omessa dal modello, osserviamo un cambiamento notevole nel coefficiente di regressione per l’ansia. In questo modello ridotto, il coefficiente per l’ansia può addirittura diventare positivo, suggerendo erroneamente che l’ansia abbia un effetto benefico sulla prestazione. Questo fenomeno si verifica perché l’effetto indiretto e non osservato della motivazione sull’ansia porta a una stima distorta quando la motivazione non è controllata nel modello.

# Generiamo dati casuali
np.random.seed(42)
n = 100  # Numero di osservazioni

# Variabili indipendenti con correlazione negativa tra loro
motivazione = np.random.normal(100, 10, n)
ansia = 200 + 0.75 * motivazione + np.random.normal(0, 5, n)

# Variabile dipendente, con peso maggiore sulla motivazione rispetto all'ansia
prestazione = 5 * motivazione - 1 * ansia + np.random.normal(0, 50, n)

# Creazione DataFrame
data = pd.DataFrame(
    {"Motivazione": motivazione, "Ansia": ansia, "Prestazione": prestazione}
)
model_full = bmb.Model("Prestazione ~ Motivazione + Ansia", data=data)
results_full = model_full.fit(nuts_sampler="numpyro")
Hide code cell output
az.summary(results_full, round_to=2)
mean sd hdi_3% hdi_97% mcse_mean mcse_sd ess_bulk ess_tail r_hat
Ansia -1.11 1.12 -3.25 0.88 0.02 0.02 2105.71 2604.24 1.0
Intercept -87.85 243.86 -556.95 355.76 4.87 3.44 2503.36 2737.24 1.0
Motivazione 6.23 0.95 4.37 7.95 0.02 0.01 2034.55 2237.52 1.0
Prestazione_sigma 54.30 3.81 47.15 61.22 0.06 0.04 3769.41 2829.23 1.0
# Analisi di regressione con pingouin
results_full = pg.linear_regression(data[["Motivazione", "Ansia"]], data["Prestazione"])
results_full
names coef se T pval r2 adj_r2 CI[2.5%] CI[97.5%]
0 Intercept -84.058695 244.261908 -0.344133 7.314908e-01 0.467656 0.456679 -568.850966 400.733576
1 Motivazione 6.222523 0.977770 6.363994 6.510176e-09 0.467656 0.456679 4.281920 8.163125
2 Ansia -1.122768 1.143817 -0.981597 3.287403e-01 0.467656 0.456679 -3.392928 1.147393
model_ansia_only = bmb.Model("Prestazione ~ Ansia", data=data)
results_ansia_only = model_ansia_only.fit(nuts_sampler="numpyro")
Hide code cell output
az.summary(results_ansia_only, round_to=2)
mean sd hdi_3% hdi_97% mcse_mean mcse_sd ess_bulk ess_tail r_hat
Ansia 4.65 0.84 3.15 6.32 0.01 0.01 4138.00 2886.12 1.0
Intercept -1050.91 230.73 -1500.45 -631.77 3.62 2.72 4100.74 2885.36 1.0
Prestazione_sigma 64.20 4.53 56.46 73.56 0.07 0.05 4091.20 3220.06 1.0
results_ansia_only = pg.linear_regression(data[["Ansia"]], data["Prestazione"])
results_ansia_only
names coef se T pval r2 adj_r2 CI[2.5%] CI[97.5%]
0 Intercept -1052.984249 226.249178 -4.654091 1.020933e-05 0.245386 0.237686 -1501.968379 -604.000119
1 Ansia 4.653853 0.824399 5.645148 1.608208e-07 0.245386 0.237686 3.017861 6.289846

Questa dimostrazione mette in luce l’importanza di includere tutte le variabili rilevanti in un modello di regressione per evitare conclusioni fuorvianti e garantire che le stime dei coefficienti riflettano veramente le relazioni causali tra le variabili.

Informazioni sull’Ambiente di Sviluppo#

%load_ext watermark
%watermark -n -u -v -iv -w -m 
Last updated: Sun Jun 16 2024

Python implementation: CPython
Python version       : 3.12.3
IPython version      : 8.25.0

Compiler    : Clang 16.0.6 
OS          : Darwin
Release     : 23.4.0
Machine     : arm64
Processor   : arm
CPU cores   : 8
Architecture: 64bit

arviz     : 0.18.0
bambi     : 0.13.0
pandas    : 2.2.2
numpy     : 1.26.4
matplotlib: 3.8.4
pingouin  : 0.5.4

Watermark: 2.4.3