A/B Testing: come condurre esperimenti statisticamente validi (e gli errori da evitare)

Abbiamo avuto modo di esaminare, nel corso dei precedenti articoli, come funziona il test delle ipotesi e come il t-test per due campioni ci permetta di confrontare due gruppi in modo rigoroso. Abbiamo anche costruito intervalli di confidenza, imparato a quantificare l’incertezza delle nostre stime, e visto con il Teorema del Limite Centrale perché tutto questo funziona anche quando i dati non sono normali.

Ma c’è una domanda che, nella realtà operativa di chi fa SEO e marketing, si presenta con una frequenza quasi quotidiana: quale variante funziona meglio? Quale title tag porta più click? Quale landing page converte di più? Quale meta description attira l’attenzione? Non è una domanda accademica: è la domanda che separa le decisioni basate sui dati dalle opinioni travestite da strategie.

La buona notizia è che per rispondere abbiamo già tutti gli strumenti. L’A/B testing non è altro che l’applicazione diretta dei concetti di inferenza statistica che abbiamo costruito passo dopo passo: test delle ipotesi, confronto tra gruppi, significatività. In questo articolo mettiamo tutto insieme.

Cos’è un A/B test

Un A/B test è, nella sua essenza, un esperimento controllato: prendiamo due varianti di qualcosa (una pagina, un titolo, una call-to-action), assegniamo casualmente gli utenti a una delle due varianti, e misuriamo quale produce risultati migliori.

La variante A è il controllo (la versione attuale, quella che stiamo già usando). La variante B è il trattamento (la nuova versione che vogliamo testare). La logica è la stessa di un esperimento scientifico: cambiamo una sola variabile alla volta, manteniamo tutto il resto costante, e osserviamo se il cambiamento produce un effetto misurabile.

Tre elementi rendono un A/B test affidabile. La randomizzazione: gli utenti vengono assegnati a A o B in modo casuale. Questo è fondamentale, perché se mostrassimo A di mattina e B di pomeriggio, ogni differenza osservata potrebbe dipendere dall’orario, non dalla variante. Il gruppo di controllo: senza A come riferimento, non sapremmo se i risultati di B sono buoni o cattivi. E infine una metrica di successo definita in anticipo: CTR, tasso di conversione, tempo sulla pagina. La metrica va scelta prima di raccogliere i dati, non dopo (torneremo su questo punto tra poco).

Ma perché serve la statistica? Perché i dati sono rumorosi. Se la variante A ha un CTR del 5.0% e la variante B del 5.3%, quella differenza è reale o è solo fluttuazione casuale? L’occhio nudo non può distinguere: ci serve un test formale. Ed è esattamente il test per due campioni che abbiamo già visto — applicato a proporzioni anziché a medie.

Formulare correttamente un A/B test

Prima di raccogliere dati, dobbiamo impostare il test in modo rigoroso. Vediamo come.

Scegliere la metrica. La metrica deve essere chiara, misurabile e direttamente collegata all’obiettivo. Per un title tag, la metrica naturale è il CTR (Click-Through Rate). Per una landing page, il tasso di conversione. Per un articolo del blog, magari il tempo medio sulla pagina. Va sempre tenuto bene a mente: una metrica vaga (“la pagina piace di più”) non è una metrica.

Definire le ipotesi. Come in ogni test statistico, partiamo da un’ipotesi nulla e un’ipotesi alternativa:

  • \(H_0\): le due varianti hanno lo stesso effetto (nessuna differenza tra A e B)
  • \(H_1\): le due varianti hanno un effetto diverso (esiste una differenza)

Il test statistico. Quando confrontiamo due proporzioni (come due CTR o due tassi di conversione), il test appropriato è lo z-test per due proporzioni. La logica è la stessa del t-test per due campioni, ma adattata a dati binari (click/non-click, conversione/non-conversione).

La statistica test si calcola così. Prima, calcoliamo la proporzione pooled (combinata), che è la nostra migliore stima della proporzione comune sotto l’ipotesi nulla:

\(
\hat{p} = \frac{x_1 + x_2}{n_1 + n_2} \\
\)

dove \(x_1\) e \(x_2\) sono i successi (click, conversioni) nei due gruppi, e \(n_1\) e \(n_2\) le dimensioni dei campioni.

Poi calcoliamo la statistica z:

\(
z = \frac{\hat{p}_1 – \hat{p}_2}{\sqrt{\hat{p}(1-\hat{p})\left(\frac{1}{n_1} + \frac{1}{n_2}\right)}} \\
\)

Al numeratore c’è la differenza osservata tra le due proporzioni; al denominatore, l’errore standard sotto l’ipotesi nulla. Il rapporto ci dice quante “unità di errore standard” separano le due proporzioni: più è alto, più la differenza è difficile da attribuire al caso.

Esempio: CTR di due title tag

Facciamo un esempio concreto. Abbiamo testato due varianti di title tag per una pagina importante del sito:

  • Title A (controllo): 1500 impressioni, 75 click → CTR = 5.0%
  • Title B (trattamento): 1500 impressioni, 105 click → CTR = 7.0%

Il title B sembra migliore, ma la differenza è statisticamente significativa? Calcoliamo passo dopo passo.

Passo 1: la proporzione pooled:

\(
\hat{p} = \frac{75 + 105}{1500 + 1500} = \frac{180}{3000} = 0.06 \\
\)

Passo 2: l’errore standard:

\(
SE = \sqrt{0.06 \times 0.94 \times \left(\frac{1}{1500} + \frac{1}{1500}\right)} = \sqrt{0.0564 \times 0.00133} \approx 0.00867 \\
\)

Passo 3: la statistica z:

\(
z = \frac{0.07 – 0.05}{0.00867} \approx 2.31 \\
\)

Passo 4: il p-value. Per un test a due code, \(p \approx 0.021\).

Dunque: il p-value è inferiore a 0.05. Possiamo rifiutare l’ipotesi nulla e concludere che la differenza tra i due title tag è statisticamente significativa. Il title B ha un CTR significativamente più alto.

Calcoliamo lo stesso test in R:

# Dati
n1 <- 1500; x1 <- 75    # Title A
n2 <- 1500; x2 <- 105   # Title B
p1 <- x1 / n1  # 0.05
p2 <- x2 / n2  # 0.07

# Proporzione pooled e z-test
p_pool <- (x1 + x2) / (n1 + n2)
se <- sqrt(p_pool * (1 - p_pool) * (1/n1 + 1/n2))
z <- (p2 - p1) / se
p_value <- 2 * (1 - pnorm(abs(z)))

cat("z =", round(z, 3), "\n")
cat("p-value =", round(p_value, 4), "\n")

Risultato: z = 2.309, p-value = 0.0209.

Esempio pratico: conversion rate di due landing page

Passiamo a un esempio più articolato. Un e-commerce sta testando due varianti della propria landing page:

  • Pagina A (design attuale): 1000 visitatori, 35 conversioni → tasso di conversione = 3.5%
  • Pagina B (nuovo design): 1000 visitatori, 58 conversioni → tasso di conversione = 5.8%

La differenza appare sostanziosa (2.3 punti percentuali), ma con questi numeri è sufficiente per escludere il caso?

Verifichiamo in R con prop.test(), che esegue il test per due proporzioni:

risultato <- prop.test(
  x = c(35, 58),
  n = c(1000, 1000)
)

print(risultato)

La funzione restituisce il p-value del test e, cosa molto utile, l’intervallo di confidenza della differenza tra le due proporzioni. In questo caso il p-value è circa 0.019 — inferiore a 0.05, quindi la differenza è statisticamente significativa.

Ma è l’intervallo di confidenza della differenza che ci dà l’informazione più preziosa: non solo se B è meglio di A, ma di quanto, con quale margine di incertezza. Se l’IC della differenza va da circa 0.4 a 4.2 punti percentuali, sappiamo che B è quasi certamente migliore, e il miglioramento si colloca in quell’intervallo. È un’informazione molto più ricca di un semplice “sì, è significativo”.

n.b.: prop.test() applica una correzione di continuità (correzione di Yates) che rende il test leggermente più conservativo. Per campioni grandi la differenza è trascurabile; per campioni piccoli, è una cautela benvenuta.

Gli errori più comuni

L’A/B testing è uno strumento potente, ma insidioso. La facilità con cui si può impostare un test nasconde insidie metodologiche serie. Vediamo le più frequenti.

Fermare il test troppo presto

È la tentazione più forte: dopo pochi giorni, B sembra nettamente migliore di A. Perché aspettare ancora? Perché quei risultati preliminari sono rumore, non segnale.

Il problema ha un nome tecnico: peeking (come dicono gli anglosassoni, “sbirciare”). Ogni volta che guardiamo i dati intermedi e decidiamo se fermarci, aumentiamo la probabilità di un falso positivo. È come lanciare una moneta: se ci fermiamo ogni volta che esce testa tre volte di fila, concluderemo che la moneta è truccata. Ma non lo è — semplicemente, non le abbiamo dato abbastanza lanci.

Come evitarlo: definire prima la dimensione campionaria necessaria e attendere di raggiungere quel numero prima di trarre conclusioni. Ne parleremo in modo approfondito quando affronteremo la power analysis.

Testare troppe varianti senza correzione

Un altro errore frequente: testare tre, quattro, cinque varianti contemporaneamente (A/B/C/D…) e poi confrontarle tutte a coppie. Il problema è quello delle comparazioni multiple: più confronti facciamo, più è probabile trovare almeno un risultato significativo per puro caso.

Con 5 varianti e 10 confronti a coppie, la probabilità di trovare almeno un falso positivo sale dal 5% a quasi il 40%. Non è un dettaglio: è un errore che invalida l’intero test.

Come evitarlo: se servono confronti multipli, applicare una correzione di Bonferroni (dividere la soglia \(\alpha\) per il numero di confronti) o, meglio ancora, limitarsi a testare una variante alla volta.

Ignorare la potenza del test

Il rischio di falso positivo (errore di tipo I, \(\alpha\)) lo conosciamo bene. Ma c’è un rischio speculare che viene spesso ignorato: il falso negativo (errore di tipo II, \(\beta\)). Succede quando B è davvero meglio di A, ma il nostro test non riesce a rilevarlo.

La causa più comune? Un campione troppo piccolo. Se abbiamo solo 100 visitatori per variante, il test non ha abbastanza “potenza” per rilevare differenze piccole ma reali. Concluderemo “nessuna differenza significativa” non perché la differenza non esiste, ma perché non avevamo abbastanza dati per vederla.

Come evitarlo: calcolare la dimensione campionaria necessaria prima di avviare il test, in base all’effetto minimo che vogliamo rilevare. È il tema della power analysis, che affronteremo a breve.

Confondere significatività statistica con significatività pratica

Un p-value basso non significa automaticamente che il risultato sia importante. Con campioni molto grandi, anche differenze microscopiche diventano statisticamente significative. Se testiamo due varianti su 500.000 visitatori, una differenza di CTR dello 0.01% (dal 5.00% al 5.01%) potrebbe risultare significativa. Ma è una differenza operativamente irrilevante.

Attenzione: il p-value risponde alla domanda “la differenza è reale?”, non alla domanda “la differenza è grande abbastanza da interessarci?”. Per quest’ultima serve una misura diversa — l’effect size — che tratteremo in un articolo dedicato.

Approccio frequentista vs bayesiano

Tutto ciò che abbiamo visto finora segue l’approccio frequentista: calcoliamo una statistica test, la confrontiamo con una distribuzione di riferimento, otteniamo un p-value e prendiamo una decisione binaria (rifiutare o non rifiutare \(H_0\)).

Funziona, e funziona bene. Ma ha dei limiti che nella pratica quotidiana si avvertono. Il p-value non ci dice “di quanto è meglio B rispetto ad A”. Non ci dice “qual è la probabilità che B sia davvero superiore”. E se raccogliamo nuovi dati, non possiamo semplicemente aggiornare il risultato: dobbiamo ricalcolare tutto da capo.

Esiste un approccio alternativo che risponde direttamente alla domanda che in fondo ci interessa di più: qual è la probabilità che B sia meglio di A? È l’approccio bayesiano.

L’idea è questa. Invece di partire da un’ipotesi nulla e cercare di rifiutarla, partiamo da una distribuzione a priori (come dicono gli anglosassoni, prior) che rappresenta la nostra conoscenza iniziale sulla conversione di ciascuna variante. Poi, man mano che raccogliamo dati, aggiorniamo quella distribuzione. Il risultato è una distribuzione a posteriori (posterior) che incorpora sia le nostre conoscenze pregresse sia i dati osservati.

Per tassi di conversione, la distribuzione naturale è la Beta: è definita tra 0 e 1 (come una proporzione) e si aggiorna in modo molto elegante. Se partiamo da un prior \(\text{Beta}(\alpha, \beta)\) e osserviamo \(s\) successi su \(n\) tentativi, il posterior è:

\(
\text{Beta}(\alpha + s, \, \beta + n – s) \\
\)

Sembra difficile? È facilissimo. Usiamo i dati delle due landing page dell’esempio precedente. Partiamo da un prior non informativo \(\text{Beta}(1, 1)\) — che equivale a dire “non sappiamo nulla, qualsiasi valore tra 0 e 1 è ugualmente plausibile”:

  • Pagina A: 35 conversioni su 1000 → posterior \(\text{Beta}(36, \, 966)\)
  • Pagina B: 58 conversioni su 1000 → posterior \(\text{Beta}(59, \, 943)\)

Calcoliamo in R la probabilità che B sia migliore di A:

set.seed(42)
n_sim <- 100000

# Posterior delle due varianti
post_A <- rbeta(n_sim, shape1 = 36, shape2 = 966)
post_B <- rbeta(n_sim, shape1 = 59, shape2 = 943)

# Probabilita' che B > A
prob_B_meglio <- mean(post_B > post_A)
cat("P(B > A) =", round(prob_B_meglio, 4), "\n")

# Distribuzione della differenza
diff <- post_B - post_A
cat("Differenza mediana:", round(median(diff) * 100, 2), "punti %\n")
cat("IC 95% della differenza:",
    round(quantile(diff, 0.025) * 100, 2), "-",
    round(quantile(diff, 0.975) * 100, 2), "punti %\n")

Il risultato è notevole: la probabilità che B sia meglio di A è superiore al 99%. Ma il vero vantaggio dell’approccio bayesiano è che otteniamo direttamente la distribuzione della differenza: non solo sappiamo se B è meglio, ma di quanto, con un intervallo di credibilità che quantifica la nostra incertezza.

Questa è una differenza sostanziale rispetto all’approccio frequentista. Il p-value ci dice “la differenza è improbabile sotto \(H_0\)“; il risultato bayesiano ci dice “la probabilità che B sia migliore è del 99%, e il miglioramento si colloca tra circa 0.5 e 4.2 punti percentuali”. Per una decisione operativa, la seconda informazione è spesso più utile.

Una nota importante: l’approccio bayesiano completo merita un articolo dedicato. Qui abbiamo appena scalfito la superficie — il tema dei prior informativi, dei modelli gerarchici e della loro applicazione sistematica è un percorso a sé che affronteremo nella sezione dedicata alla statistica bayesiana.

Esempio pratico SEO: meta description A/B test

Vediamo un ultimo scenario, molto comune nella pratica quotidiana. Abbiamo due varianti di meta description per una pagina chiave del sito. Alternando le due versioni (due settimane ciascuna, per minimizzare effetti stagionali) e consultando i dati di Search Console, otteniamo:

  • Meta A: 3200 impressioni, 128 click → CTR = 4.0%
  • Meta B: 3100 impressioni, 155 click → CTR = 5.0%

Verifichiamo in R:

prop.test(c(128, 155), c(3200, 3100))

il p-value è circa 0.064 — superiore alla soglia di 0.05, quindi non possiamo rifiutare l’ipotesi nulla. Anche l’intervallo di confidenza della differenza include lo zero, confermando la non significatività. Un risultato al limite, che ci dice: con questi dati non abbiamo abbastanza evidenza per concludere che la meta B sia davvero migliore.Quale approccio usare? Per un test semplice come questo, l’approccio frequentista con prop.test() è più che sufficiente: abbiamo campioni grandi, la domanda è chiara. L’approccio bayesiano diventa più prezioso quando i campioni sono piccoli, quando vogliamo aggiornare il risultato man mano che arrivano nuovi dati, o quando abbiamo conoscenze pregresse da incorporare (ad esempio, sappiamo che per quel tipo di pagina il CTR è tipicamente tra il 3% e il 7%).

Ma la decisione operativa non deve basarsi solo sul p-value. Dobbiamo chiederci: la differenza (un punto percentuale di CTR in più) è abbastanza grande da giustificare il cambiamento? Con 3000 e più impressioni al mese, un punto percentuale in più significa circa 30 click aggiuntivi. È significativo per il nostro business? Questa è una domanda che la statistica non può risolvere da sola — è una valutazione che spetta a noi.

Prova tu

Un e-commerce sta testando due varianti di call-to-action su una pagina prodotto:

  • Variante A (“Aggiungi al carrello”): 450 visite, 23 conversioni
  • Variante B (“Compralo ora”): 430 visite, 31 conversioni
  1. Calcola il tasso di conversione di ciascuna variante
  2. Esegui il test con prop.test(c(23, 31), c(450, 430)) e interpreta il p-value
  3. L’intervallo di confidenza della differenza include lo zero?
  4. Al livello di significatività del 5%, la differenza è statisticamente significativa?

Suggerimento: se il p-value è superiore a 0.05, non possiamo concludere che una variante sia meglio dell’altra — ma questo non significa che siano uguali. Potrebbe semplicemente significare che non abbiamo abbastanza dati. È esattamente il problema della potenza del test di cui abbiamo parlato.

L’A/B testing ci offre un framework rigoroso per prendere decisioni basate sui dati, non sulle intuizioni. Ma come abbiamo visto, un test ben condotto ci dice se c’è una differenza significativa — non ci dice quanto sia grande quell’effetto, né quanti dati ci servano per rilevarlo con sicurezza. Sono le domande dell’effect size e della power analysis, i prossimi strumenti nel nostro percorso.


Per approfondire

Se vuoi approfondire la metodologia degli esperimenti online, Trustworthy Online Controlled Experiments di Ron Kohavi, Diane Tang e Ya Xu è il riferimento mondiale sull’A/B testing. Gli autori hanno guidato le piattaforme di sperimentazione di Microsoft, Amazon e LinkedIn — e il libro copre tutto, dal design del test alle insidie che abbiamo visto in questo articolo, fino agli aspetti organizzativi che fanno la differenza tra un test ben condotto e un esercizio sterile.

Per chi vuole esplorare l’approccio bayesiano all’A/B testing (che abbiamo appena introdotto), Bayesian Statistics the Fun Way di Will Kurt è un’introduzione accessibile e sorprendentemente divertente. Spiega prior, posterior e aggiornamento bayesiano con esempi che non richiedono una laurea in matematica — e usa R per la parte computazionale.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *