Test t di Student e di Welch

Test t di Student e Welch con Python

Con il termine test t (o t-test) si fa riferimento a un insieme di test statistici che riguardano la media di una popolazione normale. Tali test variano tra loro in primo luogo per il numero di campioni coinvolti, che possono essere uno o due. Nel caso di due campioni, abbiamo un ulteriore suddivisione in base al fatto se essi sono tra loro dipendenti o indipendenti. Infine per due campioni indipendenti applicheremo tecniche diverse se la varianza delle due popolazioni confrontate è uguale o diversa.

In questo articolo vedremo come implementare con Python tutte e quattro queste tipologie di test, tenendo comunque presente che, come prima cosa, occorrerà verificare in ogni caso la normalità delle popolazioni statistiche che stiamo analizzando, ad esempio con i metodi descritti in questo articolo https://www.yimp.it/distribuzione-normale/

Test T sulla media di una distribuzione normale

Partiamo dal caso più semplice in cui abbiamo un solo campione proveniente da una distribuzione normale e vogliamo effettuare un test statistico sulla sua media. Procediamo importando dei dati d’esempio dal mio repository di Github con il metodo read_csv di pandas e calcoliamo la media aritmetica dell’unica colonna Temperatura presente nel file.

import pandas as pd
dati = "https://raw.githubusercontent.com/iantomasinicola/Esercizi/main/Dati_test_normalita.csv"
d1 = pd.read_csv(dati)
d1["Temperatura"].mean()

Dai dati del nostro campione otteniamo il valore 19.15 per la media aritmetica. Vogliamo ora eseguire un test t per valutare se possiamo generalizzare all’intera popolazione da cui è estratto il campione l’affermazione che la media della temperatura è maggiore di 18. Imposteremo allora il test t con queste ipotesi:

  • H0: la media della popolazione è minore o uguale a 18;
  • H1: la media della popolazione è maggiore a 18.

Per eseguire il test con Python possiamo utilizzare il metodo ttest_1samp della libreria Scipy

from scipy import stats
stats.ttest_1samp(a = d1["Temperatura"].values,
                             popmean = 18,
                             alternative = "greater")

Facciamo attenzione a valorizzare l’argomento popmean con il valore oggetto del test (18) e il parametro alternative con “greater”, pari al segno presente nell’ipotesi H1 (che non a caso è chiamata in generale ipotesi alternativa).

Il codice ci restituirà in output:

  • il valore della statistica test
  • il p-value
  • i gradi di libertà

Per valutare l’esito del test, il valore che ci interessa maggiormente è il p-value: in questo caso otteniamo circa 0.017, un valore sufficientemente piccolo per rifiutare l’ipotesi H0 nella maggior parte delle applicazioni e accettare, dunque, che la media della popolazione sia maggiore di 18.

Test T sul confronto tra medie di due popolazioni normali e dipendenti

Supponiamo di aver registrato la temperatura di cento città italiane scelte casualmente, in due orari differenti della stessa giornata: le ore 15 e le ore 18. Importiamo i dati dal nostro Github:

import pandas as pd 
dati = "https://raw.githubusercontent.com/iantomasinicola/Esercizi/main/test_due_campioni_dipendenti.csv"
d2 = pd.read_csv(dati) 
d2.head(5)
dataframe con due colonne dipendenti per eseguire test t sul confronto tra due popolazioni normali dipendenti

Calcoliamo ora la media aritmetica delle due colonne

d2["Temperatura_ore_15"].mean(), d2["Temperatura_ore_18"].mean()

e otteniamo così due valori abbastanza distanti: 19.15 e 17.51. Dopo aver verificato che entrambe le colonne provengono da una popolazione normale, ad esempio tramite il test di Shapiro-Wilk, vogliamo provare a generalizzare il risultato sulle media dell’intera popolazione (in questo caso tutte le città italiane). Il t-test avrà allora questa forma:

  • H0: la media della popolazione è rimasta uguale
  • H1: la media della popolazione è cambiata

In questo caso è importante osservare che i due campioni non possono essere considerati indipendenti, in quanto la temperatura delle ore 15 in una città influenzerà sicuramente quella delle ore 18 nella medesima città. Per eseguire il test useremo il metodo di Scipy stats.ttest_rel, passandogli in input semplicemente le due colonne:

from scipy import stats
stats.ttest_rel (d2["Temperatura_ore_15"].values, 
                        d2["Temperatura_ore_18"].values)

Come al solito otterremo in output la statistica test, il p-value e i gradi di liberta: anche in questo caso il p-value è abbastanza piccolo da rifiutare l’ipotesi H0.

corso di analisi dei dati
Se vuoi diventare un esperto (qualunque sia il tuo livello di partenza) ti invito a visitare l’anteprima gratuita della piattaforma –> La Scuola dei Dati <–

Test T di Student e di Welch sul confronto tra medie di due popolazioni normali e indipendenti

Consideriamo ora due campioni di temperature indipendenti, registrate ad esempio in due città differenti e in orari casuali. In generale non c’è dunque nessun legame tra gli elementi dei due campioni.

import pandas as pd
dati = "https://raw.githubusercontent.com/iantomasinicola/Esercizi/main/test_due_campioni_indipendenti.csv"
d3 = pd.read_csv(dati) 
d3.head(2), d3.tail(2)
dataset con dati di due campioni indipendenti per t test di student e di welch

Usiamo il metodo query di Pandas per dividere i dati in due Dataframe distinti, in base al luogo di rilevazione.

d3_1 = d3.query( 'Luogo == "Citta1"')
d3_2 = d3.query( 'Luogo == "Citta2"')
d3_1["Temperatura"].mean(), d3_2["Temperatura"].mean()

Come al solito verifichiamo che i due campioni provengano entrambi da una distribuzione normale ma, prima di procedere con il test statistico, calcoliamo questa volta anche la stima della varianza delle due popolazioni.

d3_1[“Temperatura”].var(), d3_2[“Temperatura”].var()

Otteniamo due valori molti distanti tra loro (28.62 e 0.96). Inoltre, se effettuiamo un Test di Levene otterremo un p-value praticamente pari a zero, per cui confermiamo il rifiuto dell’ipotesi nulla del Test di Levene per cui le varianze delle due popolazioni sono uguali.

from scipy import stats
stats.levene(d3_1["Temperatura"].values, 
                    d3_2["Temperatura"].values)

A questo punto possiamo applicare il metodo stats.ttest_ind per effettuare un test sull’uguaglianza di medie per due campioni normali e indipendenti, facendo però molta attenzione a valorizzare l’argomento equal_var con False (il valore di default sarebbe stato True) coerentemente con quanto abbiamo appena studiato sulle varianze.

from scipy import stats
stats.ttest_ind(d3_1["Temperatura"].values,
                        d3_2["Temperatura"].values, 
                        equal_var = False) 

Il test eseguito in questo modo è noto come t-test di Welch, se invece avessimo posto equal_var=True avremo effettuato un t-test di Student.

Il t-test di Welch esegue internamente dei calcoli più complicati, tuttavia sarà quello che utilizzeremo la maggior parte delle volte: sono pochi i casi in cui possiamo essere certi che la varianza delle due popolazioni sia uguale. Inoltre, anche nei casi di varianza uguale, il t-test di Welch resta comunque affidabile, a differenza del t-test di Student che perde significatività se applicato in casi con varianza differente.

Continua a imparare

Torna in alto
Torna su