Go to main content
Hypothesis testing - official lesson image on GinnyTech, created by AD

Hypothesis testing: logic, not ritual

The logic of hypothesis testing beyond the mechanics of the p-value.

AD
Created byAndrii Dyshkantiuk
Lesson 155 / 236Level: AdvancedDuration: 22 minPrerequisites: 1

What you will learn

  • 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

Hypothesis Testing: Logic, Not Ritual

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

  1. Scrivi l’ipotesi nulla H₀ (nessun effetto) e l’alternativa H₁ prima di guardare i dati.
  2. Dichiara metrica primaria, livello α e dimensione campionaria da power analysis.
  3. Calcola la statistica test dai dati, per esempio la statistica t della differenza tra medie.
  4. Ricava il valore p, cioè P(statistica almeno così estrema | H₀ vera).
  5. Rifiuta H₀ solo se p < α, e riporta sempre dimensione dell’effetto e intervallo di confidenza.
  6. Se i dati violano la normalità, usa un test non parametrico sui ranghi come Mann-Whitney o Wilcoxon al posto del test t.

Logical structure of the test

  1. Null hypothesis (H₀): lo stato di default, l’assenza di effetto. “La variante B NON è diversa da A.”
  2. Alternative hypothesis (H₁): ciò che sospetti. “B è migliore di A.”
  3. Test statistic: una funzione dei dati che misura la discrepanza tra ciò che osservi e H₀, per esempio la statistica t.
  4. p-value: P(statistica test almeno così estrema | H₀ vera). NON è P(H₀ vera | dati).
  5. Significance level α: soglia predefinita. Se p < α, rifiuti H₀.

La logica è popperiana: cerchi di falsificare H₀. Se i dati sono troppo improbabili sotto H₀, concludi che H₀ è probabilmente falsa e accetti provvisoriamente H₁.

Type I and Type II errors

True H₀False H₀
Do not reject H₀OK (1-α)Type II Error (β)
Reject H₀Type I Error (α)OK (1-β, power)

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.

The cardinal sins of the p-value

  1. p-hacking: provi molte segmentazioni e tieni quella con p < 0.05.
  2. HARKing (Hypothesizing After Results are Known): you formulate the hypothesis AFTER seeing the data.
  3. Peeking: guardi il test ogni giorno e lo fermi quando p < 0.05.
  4. Confusing significance with effect size: un valore p piccolo non significa effetto grande.
  5. Confusing p-value with hypothesis probability: p=0.03 NON significa probabilità del 3% che H₀ sia vera.

Per un test onesto la checklist è questa:

  • Hypothesis formulated BEFORE seeing the data
  • A primary metric declared 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.

References:

  • 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.

SQL example: building a control view

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;

Python example: checking stability and anomalies

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

  1. Cosa distingue il valore p dalla probabilità che l’ipotesi nulla sia vera?
  2. Quando un test sui ranghi è preferibile al test t per confrontare due gruppi?
  3. Quale errore commetti se fermi un A/B test appena il valore p scende sotto soglia?
  4. Perché la dimensione dell’effetto va riportata anche quando il test è significativo?
Serve una mano concreta?

Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.

Book a call