
Test d'ipotesi: logica, non rituale
La logica dei test d'ipotesi oltre la meccanica del p-value.
Cosa imparerai
- Formulare ipotesi nulla e alternativa e calcolare la statistica test prima di guardare i dati
- Distinguere errore di Tipo I e Tipo II e scegliere il livello α in base al costo relativo
- Scegliere tra test t e test sui ranghi quando normalità e varianze non tengono
Collegamenti
Test d’ipotesi: logica, non rituale
Questa lezione viaggia sul binario ml-tabellare, dove ogni test parte da una tabella di confronto. Il test d’ipotesi non è un timbro di verità. È una procedura per decidere quanto sarebbe sorprendente osservare certi dati se l’ipotesi nulla fosse ragionevole. Pensa a un A/B test che arriva in riunione con un valore p sotto soglia: qualcuno dice che si è vinto, qualcun altro chiede quante metriche sono state guardate e se il test è stato fermato prima del previsto.
Che cosa misura davvero un test
Un test d’ipotesi misura quanto i dati osservati sarebbero sorprendenti se l’ipotesi nulla fosse vera, senza mai certificarne la verità.
Come si conduce un test onesto
- Scrivi l’ipotesi nulla
H₀(nessun effetto) e l’alternativaH₁prima di guardare i dati. - Dichiara metrica primaria, livello
αe dimensione campionaria da power analysis. - Calcola la statistica test dai dati, per esempio la statistica
tdella differenza tra medie. - Ricava il valore
p, cioèP(statistica almeno così estrema | H₀ vera). - Rifiuta
H₀solo sep < α, e riporta sempre dimensione dell’effetto e intervallo di confidenza. - Se i dati violano la normalità, usa un test non parametrico sui ranghi come Mann-Whitney o Wilcoxon al posto del test
t.
La struttura logica del test
- Ipotesi nulla (H₀): lo stato di default, l’assenza di effetto. “La variante
BNON è diversa daA.” - Ipotesi alternativa (H₁): ciò che sospetti. “
Bè migliore diA.” - Statistica test: una funzione dei dati che misura la discrepanza tra ciò che osservi e
H₀, per esempio la statisticat. - p-value:
P(statistica test almeno così estrema | H₀ vera). NON èP(H₀ vera | dati). - Livello di significatività α: soglia predefinita. Se
p < α, rifiutiH₀.
La logica è popperiana: cerchi di falsificare H₀. Se i dati sono troppo improbabili sotto H₀, concludi che H₀ è probabilmente falsa e accetti provvisoriamente H₁.
Errori di Tipo I e Tipo II
| H₀ vera | H₀ falsa | |
|---|---|---|
| Non rifiuto H₀ | OK (1-α) | Errore Tipo II (β) |
| Rifiuto H₀ | Errore Tipo I (α) | OK (1-β, potenza) |
L’errore di Tipo I significa gridare al lupo quando non c’è, cioè un falso positivo. L’errore di Tipo II significa non vedere il lupo quando c’è, cioè un falso negativo. In molti contesti di business l’errore di Tipo I è tollerabile, perché testare una modifica innocua costa poco, mentre in medicina è catastrofico. La scelta di α riflette il costo relativo dei due errori, non è un dogma.
I peccati capitali del p-value
- p-hacking: provi molte segmentazioni e tieni quella con
p < 0.05. - HARKing (Hypothesizing After Results are Known): formuli l’ipotesi DOPO aver visto i dati.
- Peeking: guardi il test ogni giorno e lo fermi quando
p < 0.05. - Confondere significatività con dimensione dell’effetto: un valore
ppiccolo non significa effetto grande. - Confondere p-value con probabilità dell’ipotesi:
p=0.03NON significa probabilità del 3% cheH₀sia vera.
Per un test onesto la checklist è questa:
- Ipotesi formulata PRIMA di vedere i dati
- Una primary metric dichiarata a priori
- Sample size calcolata a priori con power analysis
- Correzione per test multipli (
Bonferroni,FDR) - Dimensione dell’effetto e intervallo di confidenza sempre riportati
Test parametrici contro non parametrici
Il test t e l’ANOVA assumono normalità e varianze confrontabili. Quando le assunzioni tengono sono i test più potenti. Mann-Whitney, Wilcoxon e Kruskal-Wallis lavorano invece sui ranghi invece che sui valori grezzi, quindi reggono code pesanti, outlier e scale ordinali. Con campioni grandi il teorema del limite centrale copre le medie anche senza normalità perfetta. Con campioni piccoli e distribuzioni storte, i ranghi sono la scelta prudente.
Verdetto: usa il test t quando normalità e varianze tengono e i test sui ranghi quando i dati sono ordinali o a code pesanti, e dichiara la scelta prima di vedere i dati.
Riferimenti:
- Wasserstein, R.L. & Lazar, N.A. (2016). “The ASA Statement on p-Values.” The American Statistician, 70(2).
- Neyman, J. & Pearson, E.S. (1933). “On the Problem of the Most Efficient Tests of Statistical Hypotheses.” Phil. Trans. R. Soc. Lond. A.
Esempio SQL: costruire una vista di controllo
La vista seguente crea una base analitica con metrica, segmento e finestra temporale, così puoi confrontare periodi e gruppi senza riscrivere la logica ogni volta.
WITH base_events AS (
SELECT
user_id,
account_id,
event_type,
event_time,
DATE_TRUNC('week', event_time) AS week,
source,
device_type
FROM events
WHERE event_time >= CURRENT_DATE - INTERVAL '180 days'
AND user_id IS NOT NULL
),
weekly_user_metrics AS (
SELECT
week,
user_id,
COALESCE(source, 'unknown') AS source,
COALESCE(device_type, 'unknown') AS device_type,
COUNT(*) AS total_events,
COUNT(DISTINCT DATE(event_time)) AS active_days,
COUNT(DISTINCT event_type) AS event_diversity,
MAX(CASE WHEN event_type IN ('purchase', 'subscribe', 'activation') THEN 1 ELSE 0 END) AS reached_key_outcome
FROM base_events
GROUP BY week, user_id, source, device_type
)
SELECT
week,
source,
device_type,
COUNT(DISTINCT user_id) AS users,
ROUND(AVG(active_days), 2) AS avg_active_days,
ROUND(AVG(event_diversity), 2) AS avg_event_diversity,
ROUND(AVG(reached_key_outcome) * 100, 2) AS key_outcome_rate
FROM weekly_user_metrics
GROUP BY week, source, device_type
ORDER BY week, source, device_type;
Esempio Python: controllare stabilità e anomalie
Il controllo seguente segnala variazioni anomale settimana su settimana senza reagire a ogni oscillazione casuale.
# df contiene: week, segment, users, key_outcome_rate
# key_outcome_rate espresso in percentuale, es. 12.4
df = df.sort_values(['segment', 'week']).copy()
df['previous_rate'] = df.groupby('segment')['key_outcome_rate'].shift(1)
df['wow_change_pp'] = df['key_outcome_rate'] - df['previous_rate']
df['rolling_mean'] = df.groupby('segment')['key_outcome_rate'].transform(
lambda s: s.rolling(4, min_periods=2).mean()
)
df['rolling_std'] = df.groupby('segment')['key_outcome_rate'].transform(
lambda s: s.rolling(4, min_periods=2).std()
)
df['z_score'] = (df['key_outcome_rate'] - df['rolling_mean']) / df['rolling_std']
anomalies = df[df['z_score'].abs() >= 2].sort_values('z_score')
print(anomalies[['week', 'segment', 'key_outcome_rate', 'wow_change_pp', 'z_score']])
La presa di posizione dell’ASA sul p-value
Nel 2016 l’American Statistical Association pubblicò una presa di posizione ufficiale sui p-value, la prima nella sua storia quasi bicentenaria. Il documento fissò sei principi, tra cui: il p-value non misura la probabilità che l’ipotesi nulla sia vera, non misura la dimensione dell’effetto e da solo non basta a sostenere una conclusione scientifica. La dichiarazione nacque proprio dall’abuso dei rituali meccanici come p-hacking e peeking, e resta il riferimento che ogni analyst dovrebbe citare prima di presentare un test in riunione.
Domande per chiudere la lezione
- Cosa distingue il valore p dalla probabilità che l’ipotesi nulla sia vera?
- Quando un test sui ranghi è preferibile al test t per confrontare due gruppi?
- Quale errore commetti se fermi un A/B test appena il valore p scende sotto soglia?
- Perché la dimensione dell’effetto va riportata anche quando il test è significativo?
Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.
Percorso collegato
Lezioni da leggere insieme
Questi collegamenti portano la lezione dentro il resto del corso: basi da riprendere, passaggi successivi e connessioni tematiche tra moduli.