A/B-testets signifikansräknare
Kontrollera om ditt A/B-testresultat är statistiskt signifikant. Ange besökare och konverteringar för att få p-värdet, z-poängen, konfidensintervallet och den relativa ökningen.
A/B-testets signifikansräknare
Ange besökare och konverteringar för varje variant för att kontrollera om skillnaden är verklig eller bara buller.
Resultat
Statistiskt signifikant
Skillnaden är osannolik att bero på slumpen på din valda konfidensnivå.
Chance this gap is just luck — lower is stronger.
How far apart the two rates are, in standard errors.
The likely range for the true difference.
Dokumentation
A/B-testning på en minut
Du ändrade en knapp, en rubrik eller ett kassaflöde. Version A är den gamla, version B är den nya. B ser bättre ut — den konverterade 15% av besökarna mot 10% för A. Men kunde det gapet bara vara tur, på samma sätt som att kasta ett mynt tio gånger kan ge sju kronor?
Denna miniräknare besvarar exakt det. Du anger hur många människor som såg varje version och hur många som konverterade, och den talar om för dig sannolikheten att skillnaden du mätt är verklig snarare än slumpmässig brus. Om denna sannolikhet är tillräckligt hög har du en vinnare. Om inte, fortsätter du att köra testet.
Det ena numret att hålla ögonen på är p-värdet: chansen att se ett gap minst lika stort om de två versionerna faktiskt var identiska. Ett litet p-värde (säg, under 0,05) betyder "detta skulle sällan hända av tur, så skillnaden är förmodligen verklig."
Hur man använder det
- Besökare — hur många unika människor fick se varje version.
- Konverteringar — hur många av dem gjorde det du bryr dig om (köpte, anmälde sig, klickade).
- Konfidensnivå — hur säker du vill vara innan du kallar på en vinnare. 95% är branschstandarden.
- Hypotes — tvåsidigt frågar "är B olika från A?" (säkrare, standard); ensidigt frågar bara "är B bättre än A?" (mer känsligt, men du måste bestämma riktningen innan du kör testet).
Resultatet uppdateras live och inmatningarna lagras i sidans URL, så du kan bokmärka eller dela ett resultat. Återställ rensar formuläret; Ladda exempeldata fyller i ett genomarbetat exempel.
Ett genomarbetat exempel
| Besökare | Konverteringar | Hastighet | |
|---|---|---|---|
| A (kontroll) | 1 000 | 100 | 10,0% |
| B (variation) | 1 000 | 150 | 15,0% |
Det är en absolut ökning på 5 procentenheter och en +50% relativ ökning. Miniräknaren returnerar ett p-värde på cirka 0,0007 — under 0,05 — så på 95% konfidensnivå är resultatet statistiskt signifikant. Ungefär, om de två versionerna var verkligen identiska, skulle du se ett gap denna stor mindre än en gång på tusen tester.
Matematiken (två-proportioner z-test)
Under huven är detta standard två-proportioner z-test, samma test som lärdes i introduktionsstatistik och som används av vanliga A/B-verktyg.
-
Konverteringsfrekvens för varje grupp:
där är konverteringar och är besökare.
-
Poolad frekvens, förutsatt (för nollhypotesen) att båda grupperna delar en sann frekvens:
-
Standardfel för skillnaden:
-
Z-poängen — hur många standardfel skiljer de två frekvenserna åt:
-
P-värdet kommer från normalfördelningen . Tvåsidigt: . Ensidigt: .
-
Signifikant när , där (så 0,05 på 95%).
Miniräknaren rapporterar också ett konfidensintervall för skillnaden, beräknat med det opoolerade standardfelet : det troliga intervallet för det verkliga gapet. Om det intervallet utesluter 0 är resultatet signifikant.
Vid 95% konfidensnivå räknas en z bortom ±1,96 (de skuggade svansarna, 5% av området) som signifikant.
Läsa resultatet ärligt
- Statistisk signifikans är inte affärsmässig signifikans. En 0,1% ökning kan vara statistiskt verklig men ändå inte värd att skeppa.
- Kika inte och stanna tidigt. Att kontrollera p-värdet varje dag och stanna när det sjunker under 0,05 blåser upp din falskt-positiv-frekvens. Bestäm provstorleken på förhand och låt testet slutföras.
- Se till exempel-storleksregeln. Normalapproximationen är tillförlitlig när varje grupp har minst ~10 konverteringar och ~10 icke-konverteringar. Med små siffror, behandla resultatet som endast riktningsgivet.
- Konfidensnivå ≠ sannolikhet för att B är bättre. En konfidensnivå på 95% betyder att proceduren är felaktig högst 5% av tiden i det långa loppet — det är ett frekventistuttalande, inte "95% chans att B vinner."
- Ett test, ett mätvärde. Att testa många mätvärden eller varianter samtidigt multiplicerar chansen för ett lyckoslut; korrigera för det (t.ex. Bonferroni) eller pre-registrera det enda mätvärde som bestämmer testet.
Beräkna det själv
Varje avsnitt beräknar två-sidiga p-värde för exemplet ovan.
1=2*(1-NORM.S.DIST(
2 (B2/A2 - B1/A1) /
3 SQRT(((B1+B2)/(A1+A2))*(1-(B1+B2)/(A1+A2))*(1/A1+1/A2)),
4 TRUE))
5' A1,B1 = kontroll besökare, konverteringar ; A2,B2 = variation besökare, konverteringar
61from math import sqrt, erf
2
3def ab_pvalue(n1, x1, n2, x2, two_sided=True):
4 p1, p2 = x1 / n1, x2 / n2
5 p = (x1 + x2) / (n1 + n2)
6 se = sqrt(p * (1 - p) * (1 / n1 + 1 / n2))
7 z = (p2 - p1) / se
8 phi = lambda v: 0.5 * (1 + erf(v / sqrt(2))) # standard normal CDF
9 return 2 * (1 - phi(abs(z))) if two_sided else 1 - phi(z)
10
11print(ab_pvalue(1000, 100, 1000, 150)) # ~0.00072
121// erf via Abramowitz & Stegun 7.1.26
2function erf(x) {
3 const s = x < 0 ? -1 : 1;
4 x = Math.abs(x);
5 const t = 1 / (1 + 0.3275911 * x);
6 const y = 1 - ((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t
7 - 0.284496736) * t + 0.254829592) * t * Math.exp(-x * x);
8 return s * y;
9}
10const phi = z => 0.5 * (1 + erf(z / Math.SQRT2));
11
12function abPValue(n1, x1, n2, x2, twoSided = true) {
13 const p1 = x1 / n1, p2 = x2 / n2, p = (x1 + x2) / (n1 + n2);
14 const se = Math.sqrt(p * (1 - p) * (1 / n1 + 1 / n2));
15 const z = (p2 - p1) / se;
16 return twoSided ? 2 * (1 - phi(Math.abs(z))) : 1 - phi(z);
17}
18console.log(abPValue(1000, 100, 1000, 150)); // ~0.00072
191public static double abPValue(int n1, int x1, int n2, int x2) {
2 double p1 = (double) x1 / n1, p2 = (double) x2 / n2;
3 double p = (double) (x1 + x2) / (n1 + n2);
4 double se = Math.sqrt(p * (1 - p) * (1.0 / n1 + 1.0 / n2));
5 double z = (p2 - p1) / se;
6 // Phi via the error function; erf approximated (A&S 7.1.26) separately.
7 double phi = 0.5 * (1 + erf(Math.abs(z) / Math.sqrt(2)));
8 return 2 * (1 - phi);
9}
101static double AbPValue(int n1, int x1, int n2, int x2) {
2 double p1 = (double)x1 / n1, p2 = (double)x2 / n2;
3 double p = (double)(x1 + x2) / (n1 + n2);
4 double se = Math.Sqrt(p * (1 - p) * (1.0 / n1 + 1.0 / n2));
5 double z = (p2 - p1) / se;
6 double phi = 0.5 * (1 + Erf(Math.Abs(z) / Math.Sqrt(2)));
7 return 2 * (1 - phi);
8}
91#include <cmath>
2
3double ab_pvalue(int n1, int x1, int n2, int x2) {
4 double p1 = (double)x1 / n1, p2 = (double)x2 / n2;
5 double p = (double)(x1 + x2) / (n1 + n2);
6 double se = std::sqrt(p * (1 - p) * (1.0 / n1 + 1.0 / n2));
7 double z = (p2 - p1) / se;
8 double phi = 0.5 * (1 + std::erf(std::fabs(z) / std::sqrt(2.0)));
9 return 2 * (1 - phi);
10}
111import "math"
2
3func abPValue(n1, x1, n2, x2 float64) float64 {
4 p1, p2 := x1/n1, x2/n2
5 p := (x1 + x2) / (n1 + n2)
6 se := math.Sqrt(p * (1 - p) * (1/n1 + 1/n2))
7 z := (p2 - p1) / se
8 phi := 0.5 * (1 + math.Erf(math.Abs(z)/math.Sqrt2))
9 return 2 * (1 - phi)
10}
111// erf from the `libm` crate; std has no erf.
2fn ab_pvalue(n1: f64, x1: f64, n2: f64, x2: f64) -> f64 {
3 let (p1, p2) = (x1 / n1, x2 / n2);
4 let p = (x1 + x2) / (n1 + n2);
5 let se = (p * (1.0 - p) * (1.0 / n1 + 1.0 / n2)).sqrt();
6 let z = (p2 - p1) / se;
7 let phi = 0.5 * (1.0 + libm::erf(z.abs() / 2f64.sqrt()));
8 2.0 * (1.0 - phi)
9}
101function ab_pvalue($n1, $x1, $n2, $x2) {
2 $p1 = $x1 / $n1; $p2 = $x2 / $n2;
3 $p = ($x1 + $x2) / ($n1 + $n2);
4 $se = sqrt($p * (1 - $p) * (1 / $n1 + 1 / $n2));
5 $z = ($p2 - $p1) / $se;
6 $phi = 0.5 * (1 + erf(abs($z) / sqrt(2)));
7 return 2 * (1 - $phi);
8}
91def ab_pvalue(n1, x1, n2, x2)
2 p1, p2 = x1.to_f / n1, x2.to_f / n2
3 p = (x1 + x2).to_f / (n1 + n2)
4 se = Math.sqrt(p * (1 - p) * (1.0 / n1 + 1.0 / n2))
5 z = (p2 - p1) / se
6 phi = 0.5 * (1 + Math.erf(z.abs / Math.sqrt(2)))
7 2 * (1 - phi)
8end
91# R has this built in: prop.test does the whole thing.
2prop.test(c(100, 150), c(1000, 1000), correct = FALSE)$p.value # ~0.00072
3FAQ
Vilken provstorlekt behöver jag? Tillräckligt att en meningsfull ökning skulle kunna upptäckas. Som en golvnivå, sikta på minst ett par hundra konverteringar per variant; använd en dedikerad provstorleksräknare med din baslinjehastighet och den minsta ökning värd att detektera.
Tvåsidigt eller ensidigt? Använd tvåsidigt om du inte har ett fast, förbundet skäl att bara bry dig om förbättring. Ensidigt fördubblar din känslighet men förbjuder reaktion på B som är värre.
Varför visar miniräknaren ett konfidensintervall? Det visar det troliga intervallet för den verkliga skillnaden, inte bara ett ja/nej-svar. Ett brett intervall som straddlar 0 betyder "inte tillräckligt med data ännu."
Är detta Bayesianskt? Nej — det är ett frekventist z-test, den mest allmänt undervisade och använd metoden. Bayesianske A/B-verktyg rapporterar "sannolikheten att B slår A" istället för ett p-värde; båda är giltiga, de besvarar lite olika frågor.