51. Test t di Student per campioni indipendenti#

import arviz as az
import itertools
import numpy as np
import pandas as pd
import scipy.stats as stats
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import t
from scipy.stats import ttest_ind
import pingouin as pg
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[1], line 10
      8 from scipy.stats import t
      9 from scipy.stats import ttest_ind
---> 10 import pingouin as pg

ModuleNotFoundError: No module named 'pingouin'
%matplotlib inline

# 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(
    context="paper",
    palette="colorblind",
)

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

Il test t di Student per due campioni indipendenti è un metodo statistico che viene utilizzato per determinare se le medie di due campioni indipendenti sono statisticamente significativamente diverse. Questo test è applicabile quando i due campioni sono indipendenti, il che significa che non esiste alcuna correlazione tra le osservazioni in un campione e quelle nell’altro.

Il test t di Student per due campioni indipendenti utilizza la differenza tra le medie dei due campioni e stime delle varianze campionarie delle popolazioni da cui i campioni sono stati estratti. L’ipotesi nulla del test è che le medie dei due campioni siano uguali, mentre l’ipotesi alternativa a due code è che le medie dei due campioni siano diverse. La statistica del test è calcolata come la differenza tra le medie campionarie divisa per la deviazione standard campionaria media.

La statistica t viene confrontata con la distribuzione t di Student con \(n_1 + n_2 - 2\) gradi di libertà, dove \(n_1\) e \(n_2\) sono le dimensioni dei due campioni. Il valore-p viene quindi calcolato dalla distribuzione t per determinare la significatività del test.

Esistono due casi in cui viene utilizzata una stima differente della varianza. Se si presume che le due popolazioni abbiano la stessa varianza, allora si utilizza una stima pooled della varianza. Questo approccio è considerato efficiente quando l’omoschedasticità è verificata. Invece, se si presume che le due popolazioni abbiano varianze diverse, si utilizzano due stime separate delle varianze per i due campioni, chiamato test di Welch. Questo metodo è più robusto quando le varianze dei due gruppi sono significativamente diverse.

Le assunzioni principali del test t di Student per due campioni indipendenti sono l’indipendenza dei due campioni e la normalità della distribuzione delle popolazioni da cui sono stati estratti i campioni.

Qui sotto viene indicato come calcolare la stima della deviazione standard pooled che si usa per standardizzare la differenza tra le medie dei due campioni se l’assunzione di omoschedasticità è verificata:

\[ \begin{equation} s_p = \sqrt{\frac{(n_0 - 1)s^2_0 + (n_1 - 1)s^2_1}{n_0 + n_1 - 2}}, \end{equation} \]

Il valore della statistica test è

\[ \begin{equation} t = \frac{\bar{x}_0 - \bar{x}_1}{s_p \sqrt{1/n_0 + 1/n_1}}. \end{equation} \]

Esaminiamo un esempio concreto. Supponiamo di disporre di nove misure del peso per un gruppo di donne e di nove misure di peso per un gruppo di uomini. Ci chiediamo se, nella popolazione, la media del peso dei due gruppi sia diversa.

Creiamo due array con i dati e li inseriamo in un DataFrame.

women_weight = np.array([38.9, 61.2, 73.3, 21.8, 63.4, 64.6, 48.4, 48.8, 48.5])
men_weight   = np.array([67.8, 60, 63.4, 76, 89.4, 73.3, 67.3, 61.3, 62.4])

weight = np.concatenate((women_weight, men_weight))
print(weight)
[38.9 61.2 73.3 21.8 63.4 64.6 48.4 48.8 48.5 67.8 60.  63.4 76.  89.4
 73.3 67.3 61.3 62.4]

Creaiamo una variabile che specifica l’appartenenza al gruppo.

is_female = np.repeat([1, 0], 9)
is_female
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
df = pd.DataFrame({"is_female": is_female, "weight": weight})
df
is_female weight
0 1 38.9
1 1 61.2
2 1 73.3
3 1 21.8
4 1 63.4
5 1 64.6
6 1 48.4
7 1 48.8
8 1 48.5
9 0 67.8
10 0 60.0
11 0 63.4
12 0 76.0
13 0 89.4
14 0 73.3
15 0 67.3
16 0 61.3
17 0 62.4

Qui sotto è riportato un KDE plot per i dati di tutto il campione.

_ = sns.kdeplot(df["weight"])
_images/5bd9a2628b10cead904f0e5f123cd74da3e15d4a593b7775867247224b878d15.svg

Dal DataFrame estraiamo due array contenenti i valori dei pesi dei due gruppi.

weight_f = df.loc[df["is_female"] == 1, "weight"]
weight_m = df.loc[df["is_female"] == 0, "weight"]

Calcoliamo la deviazione standard pooled.

s_pool_num = np.sum(
    [
        (len(weight_f) - 1) * np.std(weight_f, ddof=1) ** 2,
        (len(weight_m) - 1) * np.std(weight_m, ddof=1) ** 2,
    ]
)
s_pool_denom = len(weight_f) + len(weight_m) - 2

s_pool = np.sqrt(np.divide(s_pool_num, s_pool_denom))
s_pool
12.86771368796942

Calcoliamo la statistica test.

t_num = np.mean(weight_f) - np.mean(weight_m)
t_denom = s_pool * np.sqrt(1 / len(weight_f) + 1 / len(weight_m))
T = np.divide(t_num, t_denom)
T
-2.7842353699254567

I gradi di libertà sono:

len(weight_f) + len(weight_m) - 2
16

Il valore-p è uguale a

st.t.cdf(T, df=16) * 2
0.013265602643801042

Rifacciamo ora i calcoli usando la funzione ttest del pacchatto pingouin. L’argomento paired = False specifica che i due campioni sono indipendenti; l’argomento correction=False specifica che non verrà usata la correzione di Welch per varianze separate.

res = pg.ttest(weight_m, weight_f, paired=False, correction=False)
print(res)
               T  dof alternative     p-val          CI95%   cohen-d   BF10  \
T-test  2.784235   16   two-sided  0.013266  [4.03, 29.75]  1.312501  4.251   

           power  
T-test  0.743519  

Il risultato conferma quanto trovato in precedenza attraverso i calcoli effettuati. Il valore-\(p\) indica che possiamo rifiutare l’ipotesi nulla di uguaglianza delle medie delle due popolazioni. Quindi, possiamo concludere con un livello di confidenza del 95% che la media del peso dei maschi nella popolazione è superiore alla media del peso delle femmine nella popolazione.