Torna al blog
Test A/B nel Retail: Potenza Statistica, Durata e Trappole dei Risultati

Test A/B nel Retail: Potenza Statistica, Durata e Trappole dei Risultati

8 min di lettura1 visualizzazioni
di Marco Salmaso
Dividere il traffico in due e confrontare i risultati sembra semplice, ma la maggior parte dei test A/B in ambito retail produce conclusioni fragili. Vediamo cosa sono potenza statistica e MDE, perché il peeking rovina gli esperimenti e come impostare un test che dica davvero qualcosa.

Aprire un test A/B è facile: dividi il traffico, mostri due versioni di una pagina, aspetti qualche giorno e confronti i numeri. Il problema è che quasi tutti i test fatti così dicono qualcosa che non è vero. Non perché i dati siano sbagliati, ma perché la statistica che sta dietro al confronto viene quasi sempre ignorata.

In un contesto retail questo costa caro: si prendono decisioni su layout, prezzi, promozioni e assortimento basandosi su differenze che sono rumore. Questo articolo non spiega "come usare lo strumento X": spiega come impostare un esperimento che abbia una possibilità concreta di dare una risposta affidabile, e come riconoscere i casi in cui quella risposta non c'è.

Una sola metrica primaria, decisa prima

La prima decisione non è tecnica, è di disciplina: scegliere una metrica primaria e non cambiarla più. Nel retail può essere il tasso di conversione, il ricavo per sessione, il margine per ordine, gli articoli per scontrino. Una, non tre.

Perché tanta rigidità? Perché ogni metrica in più è un'occasione in più di trovare per caso una differenza che sembra significativa. Se misuri quindici metriche e scegli quella che si è mossa di più, la probabilità di trovare un "vincitore" è molto alta anche quando non c'è nessun effetto reale.

Accanto alla metrica primaria si definiscono le guardrail metric: indicatori che non devono peggiorare. Esempi tipici: tasso di reso, margine, tempo di caricamento della pagina, numero di contatti al servizio clienti. Servono a evitare che un miglioramento della conversione arrivi da pratiche che distruggono valore altrove (per esempio spedizioni gratis aggressive o sconti troppo profondi).

Infine, si fissa in anticipo la durata minima. Non "guardiamo e decidiamo".

Il p-value, spiegato senza giri di parole

L'ipotesi di partenza di un test A/B è la ipotesi nulla: non c'è nessuna differenza tra le due versioni, e qualsiasi scostamento osservato è frutto del caso. Il p-value risponde a questa domanda: se davvero non ci fosse alcun effetto, quanto sarebbe improbabile osservare una differenza grande almeno come quella che ho visto?

Due equivoci ricorrenti:

  • il p-value non è la probabilità che la variante B sia migliore di A;
  • il p-value non è la probabilità che il risultato sia "vero".

La soglia convenzionale di 0,05 significa accettare un 5% di falsi positivi. Di per sé è un compromesso ragionevole, ma il 5% non è una proprietà del singolo test: è una proprietà di lungo periodo. Se in un anno fai venti test e non correggi nulla, ti aspetti che circa uno risulti "significativo" solo per caso.

Potenza statistica e MDE: quanti dati servono davvero

La domanda che quasi nessuno si fa prima di partire è: questo test ha abbastanza dati per rispondere? La risposta dipende da tre cose: la conversione di base, l'effetto che vuoi rilevare e la potenza che ti serve.

L'effetto minimo rilevabile (MDE, minimum detectable effect) è la differenza più piccola che il test è in grado di distinguere dal rumore con una probabilità accettabile. La potenza è la probabilità di rilevare un effetto reale di quella dimensione: l'80% è lo standard, e significa che in un caso su cinque un effetto reale ti sfugge comunque.

La formula approssimata per il numero di osservazioni per gruppo, con conversione di base p e differenza assoluta delta, è questa:

n per gruppo ≈ 2 * (z_alpha + z_beta)^2 * p * (1 - p) / delta^2

dove:
  z_alpha ≈ 1,96   per alpha = 0,05 (due code)
  z_beta  ≈ 0,84   per potenza = 0,80
  p       = conversione di base
  delta   = differenza assoluta che vuoi rilevare

Questi valori sono un esempio, non un benchmark da applicare ciecamente al tuo negozio. Supponiamo una conversione di base del 3% e un traffico di 10.000 sessioni al giorno. Vediamo cosa cambia al variare dell'effetto che si vuole rilevare:

MDE relativoConversione Bn per gruppoSessioni totaliGiorni a 10k/giorno
5%3,15%~203.000~406.000~41
10%3,30%~51.000~102.000~10
20%3,60%~13.000~26.000~3

Il messaggio è brutale: gli effetti piccoli richiedono quantità di dati enormi. Un incremento del 5% relativo sulla conversione, in questo scenario, richiede più di un mese di traffico completo. Se il test viene chiuso dopo tre giorni, non stai misurando quell'effetto: stai misurando rumore.

In Python il calcolo è diretto:

from statsmodels.stats.power import NormalIndPower
from statsmodels.stats.proportion import proportion_effectsize

analisi = NormalIndPower()

p_base = 0.03
p_variante = 0.033  # +10% relativo

effetto = proportion_effectsize(p_variante, p_base)
n = analisi.solve_power(
    effect_size=effetto,
    alpha=0.05,
    power=0.80,
    ratio=1,
    alternative="two-sided",
)
print(f"Osservazioni per gruppo: {round(n)}")

Il valore di n va poi tradotto nell'unità che stai randomizzando (utenti, sessioni, ordini) e confrontato con il traffico disponibile. Se il numero non ci sta nella finestra temporale che ti puoi permettere, la scelta non è "facciamo un test più corto": la scelta è ripensare l'esperimento, oppure accettare di misurare solo effetti grandi.

Peeking: guardare i risultati ogni giorno

Il modo più efficace per rendere inutile un test è controllarlo ogni mattina e fermarsi al primo p-value sotto 0,05. Si chiama peeking ed è un problema serio: ogni controllo intermedio è un'occasione di fermarsi su una fluttuazione casuale. Il tasso di falsi positivi non è più il 5% dichiarato, ma può salire molto, in alcuni scenari oltre il 20-30%.

Esistono soluzioni legittime, ma vanno decise prima:

  • durata fissa, calcolata dalla potenza, senza controlli intermedi;
  • test sequenziali con spending function (alpha spending), che distribuiscono il rischio di errore lungo i controlli programmati;
  • approcci bayesiani, che permettono aggiornamenti continui ma rispondono a una domanda diversa e richiedono una probabilità a priori dichiarata.

Un controllo giornaliero "solo per vedere come va" non è una di queste soluzioni.

Segmenti, sottogruppi e molteplicità

Dopo aver visto i risultati quasi tutti fanno la stessa cosa: aprono le segmentazioni. Nuovi utenti contro returning, mobile contro desktop, una regione contro un'altra. È comprensibile, ma statisticamente pericoloso.

Con dieci segmenti indipendenti, la probabilità di almeno un falso positivo è circa:

1 - 0,95^10 ≈ 0,40

Quattro volte su dieci troverai almeno un segmento "significativo" anche senza alcun effetto. Le contromisure:

  • pre-registrare i segmenti che interessano prima di vedere i dati;
  • correggere per test multipli, per esempio con Bonferroni o Benjamini-Hochberg;
  • trattare ogni analisi esplorativa come generatrice di ipotesi, da verificare in un test successivo.

Sessione o utente? L'unità di analisi

Un dettaglio tecnico che genera molti errori: l'unità di randomizzazione e l'unità di analisi devono coincidere. Se assegni gli utenti a caso ad A o B, ma analizzi per sessione, le osservazioni non sono indipendenti: lo stesso utente compare più volte e la varianza risulta sottostimata. Il risultato è un test che sembra più preciso di quanto sia.

Regola pratica: randomizza per utente (o per dispositivo identificato stabilmente) e analizza per utente. Se proprio devi randomizzare per sessione, ricorda che stai misurando un effetto diverso e che l'inferenza è più fragile.

Quando il test A/B non si può fare

Non tutto si presta a un esperimento classico:

  • interferenza tra unità: se il trattamento cambia il comportamento di altri utenti (prezzi dinamici, marketing, disponibilità di scorte), il gruppo di controllo non è più un controllo. In questi casi si usano switchback test (alternanza a blocchi temporali) o geo test su aree separate;
  • effetto novità: un cambiamento visibile attira attenzione nelle prime settimane e i risultati non si generalizzano. Serve una finestra più lunga o un disegno che misuri anche l'effetto a distanza;
  • volumi insufficienti: con poco traffico, molti esperimenti non sono semplicemente fattibili. Meglio saperlo prima.

Un flusso di lavoro in sei passi

  1. Scrivi l'ipotesi e scegli una metrica primaria, più le guardrail metric.
  2. Calcola la potenza e l'MDE. Se il test non è fattibile con il traffico disponibile, cambia esperimento invece di allungare i tempi a caso.
  3. Fissa la durata e non fare peeking.
  4. Verifica il bilanciamento della randomizzazione (sample ratio mismatch): uno split molto diverso da 50/50 indica un bug nell'assegnazione, non un risultato.
  5. Analizza con intervalli di confidenza, non solo con il p-value: la dimensione dell'effetto conta quanto la sua significatività.
  6. Decidi, e archivia l'esperimento con metrica, durata e risultato. Serve per non ripetere gli stessi test e per correggere le analisi multiple nel tempo.

Conclusione: i punti chiave

  • Un test A/B valido si progetta prima: metrica primaria, potenza, MDE e durata decisi in anticipo.
  • Il p-value risponde a una domanda precisa e non è la probabilità che la variante sia migliore.
  • Gli effetti piccoli richiedono volumi enormi: spesso è più realistico misurare effetti grandi o non misurare affatto.
  • Il peeking gonfia i falsi positivi. Se vuoi controlli intermedi, usa test sequenziali decisi a monte.
  • Segmentare a posteriori senza correzioni per test multipli produce vincitori che non esistono.
  • Randomizzazione e analisi devono usare la stessa unità (utente, non sessione).
  • Quando c'è interferenza tra unità, l'A/B classico non basta: servono switchback o geo test.

La differenza tra un esperimento che informa una decisione e uno che la giustifica a posteriori è quasi sempre nella preparazione, non nell'analisi.


Foto di copertina di SumUp su Unsplash.