Open In Colab

13. Le relazioni tra variabili#

Obiettivi di apprendimento

Dopo aver completato questo capitolo, sarai in grado di:

  • Generare grafici per visualizzare la distribuzione congiunta di due variabili.

  • Comprendere i concetti di covarianza e correlazione.

  • Calcolare la covarianza e la correlazione usando Python.

  • Comprendere che la correlazione non implica una relazione di causa-effetto.

  • Comprendere il concetto di correlazione per variabili ordinali.

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
from scipy.constants import golden
from scipy import stats
import arviz as az
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
# Initialize random number generator
RANDOM_SEED = 8927
rng = np.random.default_rng(RANDOM_SEED)

plt.style.use("bmh")
plt.rcParams["figure.figsize"] = [10, 6]
plt.rcParams["figure.dpi"] = 100
plt.rcParams["figure.facecolor"] = "white"

sns.set_theme(palette="colorblind")

%load_ext autoreload
%autoreload 2
%config InlineBackend.figure_format = "svg"

In questo capitolo, esploreremo i metodi per visualizzare e misurare la relazione tra due variabili quantitative. Introdurremo inizialmente un diagramma a dispersione, un utile strumento grafico per rappresentare l’associazione tra le due variabili. Successivamente, esamineremo due indici statistici fondamentali: la covarianza e la correlazione. Questi indici ci permetteranno di quantificare la forza e la direzione dell’associazione lineare tra le due variabili quantitative.

13.1. Diagramma a dispersione#

Il diagramma a dispersione è un grafico che rappresenta le coppie di punti individuate da due variabili, solitamente rappresentate sull’asse delle ascisse e sulle ordinate. Un esempio concreto di utilizzo del diagramma a dispersione si trova nella ricerca condotta da Zetsche et al. (2019), in cui i ricercatori hanno utilizzato due scale psicometriche, il Beck Depression Inventory II (BDI-II) e la Center for Epidemiologic Studies Depression Scale (CES-D), per misurare il livello di depressione dei soggetti. l BDI-II è uno strumento self-report che valutare la presenza e l’intensità di sintomi depressivi in pazienti adulti e adolescenti di almeno 13 anni di età con diagnosi psichiatrica mentre la CES-D è una scala self-report progettata per misurare i sintomi depressivi che sono stati vissuti nella settimana precedente nella popolazione generale, specialmente quella degli adolescenti/giovani adulti. Ponendo i valori BDI-II sull’asse delle ascisse e quelli del CES-D sull’asse delle ordinate, ogni punto sul grafico rappresenta un individuo del quale si conosce il livello di depressione misurato dalle due scale.

È evidente che i valori delle scale BDI-II e CES-D non possono essere gli stessi per due ragioni: (1) la presenza degli errori di misurazione e (2) l’uso di unità di misura arbitrarie per le due variabili. L’errore di misurazione è un fattore che compromette sempre, almeno in parte, qualsiasi misurazione, ed è particolarmente rilevante in psicologia dove la precisione degli strumenti di misurazione è generalmente inferiore rispetto ad altre discipline, come la fisica. Il secondo motivo per cui i valori delle scale BDI-II e CES-D non possono essere uguali è che l’unità di misura della depressione è una questione arbitraria e non standardizzata. Tuttavia, nonostante le differenze derivanti dall’errore di misurazione e dall’uso di unità di misura diverse, ci si aspetta che, se le due scale misurano lo stesso costrutto (la depressione), i valori prodotti dalle due scale dovrebbero essere linearmente associati tra di loro. Per comprendere meglio il concetto di “associazione lineare”, è possibile esaminare i dati attraverso l’utilizzo di un diagramma a dispersione.

Leggiamo i dati di Diagramma a dispersione.

df = pd.read_csv("data/data.mood.csv", index_col=0)
df = df[["esm_id", "group", "bdi", "cesd_sum"]]
df = df.drop_duplicates(keep="first")
df = df[pd.notnull(df["bdi"])]

Consideriamo la relazione tra i punteggi BDI-II e CESD.

plt.scatter(df["bdi"], df["cesd_sum"])
plt.rcParams.update({"figure.figsize": (10, 10), "figure.dpi": 100})
plt.xlabel("BDI-II")
plt.ylabel("CESD")
plt.axvline(np.mean(df.bdi), alpha=0.2)
plt.axhline(np.mean(df.cesd_sum), alpha=0.2)
<matplotlib.lines.Line2D at 0x121178350>
_images/f35e69a2de14d0466f64442102e7bec491ea18e4bf39e79701f282febafe9c87.svg

Dall’osservazione del diagramma a dispersione, possiamo notare che i dati mostrano una tendenza a distribuirsi intorno ad una retta. In termini statistici, ciò significa che i punteggi CES-D e BDI-II sono linearmente associati. Tuttavia, la relazione lineare tra le due variabili è lontana dall’essere perfetta, poiché se fosse perfetta, tutti i punti nel diagramma sarebbero allineati perfettamente lungo una retta. Pertanto, sorge la necessità di trovare un indice numerico che descriva la forza e la direzione della relazione lineare tra le due variabili e che misuri la deviazione della nube di punti da una relazione lineare perfetta. Ci sono diversi indici statistici disponibili per questo scopo.

13.2. Covarianza#

Iniziamo a considerare il più importante di tali indici, chiamato covarianza. In realtà la definizione di questo indice non ci sorprenderà più di tanto in quanto, in una forma solo apparentemente diversa, l’abbiamo già incontrata in precedenza. Ci ricordiamo infatti che la varianza di una generica variabile \(X\) è definita come la media degli scarti quadratici di ciascuna osservazione dalla media:

\[ S_{XX} = \frac{1}{n} \sum_{i=1}^n(X_i - \bar{X}) (X_i - \bar{X}). \]

La varianza viene talvolta descritta come la “covarianza di una variabile con sé stessa”. Adesso facciamo un passo ulteriore. Invece di valutare la dispersione di una sola variabile, ci chiediamo come due variabili \(X\) e \(Y\) “variano insieme” (co-variano). È facile capire come una risposta a tale domanda possa essere fornita da una semplice trasformazione della formula precedente che diventa:

(13.1)#\[ S_{XY} = \frac{1}{n} \sum_{i=1}^n(X_i - \bar{X}) (Y_i - \bar{Y}). \]

L’eq. (13.1) ci fornisce la definizione della covarianza.

13.2.1. Interpretazione#

Per capire il significato dell’eq. (13.1), supponiamo di dividere il grafico riportato nella sezione Diagramma a dispersione in quattro quadranti definiti da una retta verticale passante per la media dei valori BDI-II e da una retta orizzontale passante per la media dei valori CES-D. Numeriamo i quadranti partendo da quello in basso a sinistra e muovendoci in senso antiorario.

Se prevalgono punti nel I e III quadrante, allora la nuvola di punti avrà un andamento crescente (per cui a valori bassi di \(X\) tendono ad associarsi valori bassi di \(Y\) e a valori elevati di \(X\) tendono ad associarsi valori elevati di \(Y\)) e la covarianza avrà segno positivo. Mentre se prevalgono punti nel II e IV quadrante la nuvola di punti avrà un andamento decrescente (per cui a valori bassi di \(X\) tendono ad associarsi valori elevati di \(Y\) e a valori elevati di \(X\) tendono ad associarsi valori bassi di \(Y\)) e la covarianza avrà segno negativo. Dunque, il segno della covarianza ci informa sulla direzione della relazione lineare tra due variabili: l’associazione lineare si dice positiva se la covarianza è positiva, negativa se la covarianza è negativa.

Esercizio. Implemento la (13.1) in Python.

def cov_value(x, y):

    mean_x = sum(x) / float(len(x))
    mean_y = sum(y) / float(len(y))

    sub_x = [i - mean_x for i in x]
    sub_y = [i - mean_y for i in y]

    sum_value = sum([sub_y[i] * sub_x[i] for i in range(len(x))])
    denom = float(len(x))

    cov = sum_value / denom
    return cov

Per i dati mostrati nel diagramma, la covarianza tra BDI-II e CESD è 207.4

x = df["bdi"]
y = df["cesd_sum"]

cov_value(x, y)
207.42653810835637

Oppure, in maniera più semplice:

np.mean((x - np.mean(x)) * (y - np.mean(y)))
207.42653810835628

Lo stesso risultato si ottiene con la funzione cov di NumPy.

np.cov(x, y, ddof=0)
array([[236.23875115, 207.42653811],
       [207.42653811, 222.83379247]])

13.3. Correlazione#

La direzione della relazione tra le variabili è indicata dal segno della covarianza, ma il valore assoluto di questo indice non fornisce informazioni utili poiché dipende dall’unità di misura delle variabili. Ad esempio, considerando l’altezza e il peso delle persone, la covarianza sarà più grande se l’altezza è misurata in millimetri e il peso in grammi, rispetto al caso in cui l’altezza è in metri e il peso in chilogrammi. Pertanto, per descrivere la forza e la direzione della relazione lineare tra due variabili in modo adimensionale, si utilizza l’indice di correlazione.

La correlazione è ottenuta standardizzando la covarianza tramite la divisione delle deviazioni standard (\(s_X\), \(s_Y\)) delle due variabili:

(13.2)#\[ r_{XY} = \frac{S_{XY}}{S_X S_Y}. \]

La quantità che si ottiene in questo modo viene chiamata correlazione di Bravais-Pearson (dal nome degli autori che, indipendentemente l’uno dall’altro, l’hanno introdotta).

13.3.1. Proprietà#

Il coefficiente di correlazione ha le seguenti proprietà:

  • ha lo stesso segno della covarianza, dato che si ottiene dividendo la covarianza per due numeri positivi;

  • è un numero puro, cioè non dipende dall’unità di misura delle variabili;

  • assume valori compresi tra -1 e +1.

13.3.2. Interpretazione#

All’indice di correlazione possiamo assegnare la seguente interpretazione:

  1. \(r_{XY} = -1\) \(\rightarrow\) perfetta relazione negativa: tutti i punti si trovano esattamente su una retta con pendenza negativa (dal quadrante in alto a sinistra al quadrante in basso a destra);

  2. \(r_{XY} = +1\) \(\rightarrow\) perfetta relazione positiva: tutti i punti si trovano esattamente su una retta con pendenza positiva (dal quadrante in basso a sinistra al quadrante in alto a destra);

  3. \(-1 < r_{XY} < +1\) \(\rightarrow\) presenza di una relazione lineare di intensità diversa;

  4. \(r_{XY} = 0\) \(\rightarrow\) assenza di relazione lineare tra \(X\) e \(Y\).

Esercizio. Per i dati riportati nel diagramma della sezione Diagramma a dispersione, la covarianza è 207.4. Il segno positivo della covarianza ci dice che tra le due variabili c’è un’associazione lineare positiva. Per capire quale sia l’intensità della relazione lineare calcoliamo la correlazione. Essendo le deviazioni standard del BDI-II e del CES-D rispettavamente uguali a 15.37 e 14.93, la correlazione diventa uguale a \(\frac{207.426}{15.38 \cdot 14.93} = 0.904.\) Tale valore è prossimo a 1.0, il che vuol dire che i punti del diagramma a dispersione non si discostano troppo da una retta con una pendenza positiva.

Troviamo la correlazione con la funzione corrcoef():

np.corrcoef(x, y)
array([[1.        , 0.90406202],
       [0.90406202, 1.        ]])

Replichiamo il risultato implementando l’eq. (13.2):

s_xy = np.mean((x - np.mean(x)) * (y - np.mean(y)))
s_x = x.std(ddof=0)
s_y = y.std(ddof=0)
r_xy = s_xy / (s_x * s_y)
print(r_xy)
0.9040620189474857

Un altro modo ancora per trovare la correlazione tra i punteggi BDI-II e CESD è quello di standardizzare le due variabili per poi applicare la formula della covarianza:

z_x = (x - np.mean(x)) / np.std(x, ddof=0)
z_y = (y - np.mean(y)) / np.std(y, ddof=0)
np.mean(z_x * z_y)
0.9040620189474858

13.4. Correlazione e causazione#

È fondamentale ricordare che la correlazione rappresenta solo un indice descrittivo della relazione lineare tra due variabili e non può in alcun modo essere utilizzata per trarre conclusioni sulle relazioni causali tra le variabili. L’espressione ben nota “correlazione non implica causalità” sottolinea questo concetto importante. Un esempio illustrativo delle correlazioni spurie può essere trovato sul sito spurious correlations.

13.4.1. Confounding#

Il seguente semplice esempio aiuta a chiarire che la correlazione non può informarci sulle relazioni causali.

Supponiamo che b rappresenti una variabile di confondimento.

b = np.random.rand(100)

Nella simulazione, le variabili a e c sono indipendenti tra di loro dal punto di vista causale, ma entrambe sono influenzate dalla variabile b.

a = b + .1 * np.random.rand(100)
c = b + .3 * np.random.rand(100)

Esaminiamo ora la correlazione tra a e c.

coef, p_val = stats.pearsonr(a, c)
print(coef)
0.9568438973227098

In altre parole, anche se le variabili a e c sono causalmente indipendenti, la presenza di una terza variabile b (variabile di confondimento) che le influenza entrambe fa sì che a e c siano correlate tra di loro.

# Il codice è tratto da A. Molak (2023) "Causal Inference and Discovery in Python".

COLORS = ["#00B0F0", "#FF0000"]

variables = {"a": a, "b": b, "c": c}

plt.figure(figsize=(12, 7))

for i, (var_1, var_2) in enumerate([("b", "a"), ("b", "c"), ("c", "a")]):
    color = COLORS[1]

    if "b" in [var_1, var_2]:
        color = COLORS[0]

    plt.subplot(2, 2, i + 1)
    plt.scatter(variables[var_1], variables[var_2], alpha=0.8, color=color)

    plt.xlabel(f"${var_1}$", fontsize=16)
    plt.ylabel(f"${var_2}$", fontsize=16)

plt.suptitle("Relazioni a coppie tra $a$, $b$ e $c$")
plt.subplots_adjust(hspace=0.25, wspace=0.25)
plt.show()
_images/f10f8d8884eefe9fad21214b77aa9c0c35ae6c257a5ea58fbbaf14e30782457d.svg

13.5. Usi della correlazione#

Pur non essendo adatta per stabilire relazioni causali, la correlazione trova ampio utilizzo nel contesto psicometrico, ad esempio nella valutazione della validità concorrente di un test psicologico. Se un test psicologico misura in modo accurato ciò che si prefigge di misurare (come ad esempio la depressione nel caso specifico), ci aspettiamo che esso mostri una forte correlazione con i risultati di altri test che misurano lo stesso costrutto, come evidenziato dai dati di Zetsche et al. [ZBR19]. Un’altra proprietà importante di un test psicometrico è la validità divergente, ossia la mancanza di associazione tra i risultati di test che misurano costrutti diversi. Pertanto, in tale contesto, ci aspettiamo una bassa correlazione tra i risultati di test che misurano costrutti differenti.

13.6. Correlazione di Spearman#

Un’alternativa per valutare la relazione lineare tra due variabili è il coefficiente di correlazione di Spearman, che si basa esclusivamente sull’ordine dei dati e non sugli specifici valori. Questo indice di associazione è particolarmente adatto quando gli psicologi sono in grado di misurare solo le relazioni di ordine tra diverse modalità di risposta dei soggetti, ma non l’intensità della risposta stessa. Tali variabili psicologiche che presentano questa caratteristica sono definite come “ordinali”.

Nota

È importante ricordare che, nel caso di una variabile ordinale, non è possibile utilizzare le statistiche descrittive convenzionali come la media e la varianza per sintetizzare le osservazioni. Tuttavia, è possibile riassumere le osservazioni attraverso una distribuzione di frequenze delle diverse modalità di risposta. Come abbiamo appena visto, la direzione e l’intensità dell’associazione tra due variabili ordinali possono essere descritte utilizzando il coefficiente di correlazione di Spearman.

Per fornire un esempio, consideriamo due variabili di scala ordinale e calcoliamo la correlazione di Spearman tra di esse.

stats.spearmanr([1, 2, 3, 4, 5], [5, 6, 7, 8, 7])
SignificanceResult(statistic=0.8207826816681233, pvalue=0.08858700531354381)

13.7. Correlazione nulla#

Un aspetto finale da sottolineare riguardo alla correlazione è che essa descrive la direzione e l’intensità della relazione lineare tra due variabili. Tuttavia, la correlazione non cattura relazioni non lineari tra le variabili, anche se possono essere molto forti. È fondamentale comprendere che una correlazione pari a zero non implica l’assenza di una relazione tra le due variabili, ma indica solamente l’assenza di una relazione lineare tra di esse.

La figura seguente fornisce tredici esempi di correlazione nulla in presenza di una chiara relazione (non lineare) tra due variabili. In questi tredici insiemi di dati i coefficienti di correlazione di Pearson sono sempre uguali a 0. Ma questo non significa che non vi sia alcuna relazione tra le variabili.

datasaurus_data = pd.read_csv("data/datasaurus.csv")
datasaurus_data.groupby("dataset").agg(
    {"x": ["count", "mean", "std"], "y": ["count", "mean", "std"]}
)
x y
count mean std count mean std
dataset
away 142 54.266100 16.769825 142 47.834721 26.939743
bullseye 142 54.268730 16.769239 142 47.830823 26.935727
circle 142 54.267320 16.760013 142 47.837717 26.930036
dino 142 54.263273 16.765142 142 47.832253 26.935403
dots 142 54.260303 16.767735 142 47.839829 26.930192
h_lines 142 54.261442 16.765898 142 47.830252 26.939876
high_lines 142 54.268805 16.766704 142 47.835450 26.939998
slant_down 142 54.267849 16.766759 142 47.835896 26.936105
slant_up 142 54.265882 16.768853 142 47.831496 26.938608
star 142 54.267341 16.768959 142 47.839545 26.930275
v_lines 142 54.269927 16.769959 142 47.836988 26.937684
wide_lines 142 54.266916 16.770000 142 47.831602 26.937902
x_shape 142 54.260150 16.769958 142 47.839717 26.930002
_ = sns.relplot(data=datasaurus_data, x="x", y="y", col="dataset", col_wrap=4)
_images/483167be6a1d79945b86b782c79a12bbe509bbfa10f7f96a8f8584499c9754d5.svg

13.8. Commenti e considerazioni finali#

La fase iniziale dell’analisi dei dati comporta l’utilizzo della statistica descrittiva per riassumere le informazioni raccolte. Durante questa fase, ci si pone domande come: qual è la distribuzione delle variabili di interesse? Esistono relazioni tra le coppie di variabili nel campione? Sono presenti valori anomali, ovvero osservazioni che si discostano notevolmente dagli altri dati, sia in forma univariata che bivariata? È fondamentale acquisire una comprensione chiara di questi aspetti prima di procedere con qualsiasi procedura statistica inferenziale. Per ottenere queste informazioni, l’utilizzo di rappresentazioni grafiche dei dati risulta essere molto utile.

13.9. Watermark#

%load_ext watermark
%watermark -n -u -v -iv -w
Last updated: Sat Jun 17 2023

Python implementation: CPython
Python version       : 3.11.3
IPython version      : 8.12.0

pandas    : 1.5.3
matplotlib: 3.7.1
scipy     : 1.10.1
seaborn   : 0.12.2
arviz     : 0.15.1
numpy     : 1.24.3

Watermark: 2.3.1