Αριθμομηχανή Σημαντικότητας Δοκιμής A/B
Ελέγξτε αν το αποτέλεσμα της δοκιμής A/B σας είναι στατιστικά σημαντικό. Εισάγετε επισκέπτες και μετατροπές για να λάβετε τη p-τιμή, z-σκορ, διάστημα εμπιστοσύνης και σχετικό ανάβασμα.
Αριθμομηχανή Σημαντικότητας Δοκιμής A/B
Εισάγετε επισκέπτες και μετατροπές για κάθε παραλλαγή για να ελέγξετε αν η διαφορά είναι πραγματική ή απλώς θόρυβος.
Αποτελέσματα
Στατιστικά Σημαντικό
Η διαφορά είναι απίθανο να οφείλεται στην τύχη στο επίπεδο σιγουριάς που επιλέξατε.
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.
Τεκμηρίωση
Δοκιμή A/B σε ένα λεπτό
Αλλάξατε ένα κουμπί, μια επικεφαλίδα ή ένα σχήμα ολοκλήρωσης. Η έκδοση A είναι η παλιά, η έκδοση B είναι η νέα. Το B φαίνεται καλύτερο — μετέτρεψε το 15% των επισκεπτών έναντι 10% για το A. Αλλά θα μπορούσε αυτό το κενό να είναι απλώς τύχη, όπως το να ρίξεις ένα νόμισμα δέκα φορές που μπορεί να δώσει επτά κεφάλια;
Αυτή η αριθμομηχανή απαντά ακριβώς σε αυτό. Εισάγετε πόσα άτομα είδαν κάθε έκδοση και πόσα έκαναν μετατροπή, και σας λέει την πιθανότητα ότι η διαφορά που μετρήσατε είναι πραγματική παρά τυχαίος θόρυβος. Αν αυτή η πιθανότητα είναι αρκετά υψηλή, έχετε έναν νικητή. Αν όχι, συνεχίζετε τη δοκιμή.
Ο ένας αριθμός που πρέπει να παρακολουθείτε είναι η p-τιμή: η πιθανότητα να δείτε ένα κενό τουλάχιστον τόσο μεγάλο αν οι δύο εκδόσεις ήταν στην πραγματικότητα πανομοιότυπες. Μια μικρή p-τιμή (π.χ., κάτω από 0,05) σημαίνει «αυτό θα συνέβαινε σπάνια τυχαία, οπότε η διαφορά είναι πιθανώς πραγματική».
Πώς να το χρησιμοποιήσετε
- Επισκέπτες — πόσα μοναδικά άτομα λήφθησαν κάθε έκδοση.
- Μετατροπές — πόσα από αυτά έκαναν το πράγμα που σας ενδιαφέρει (αγόρασαν, εγγραφή, κάνουν κλικ).
- Επίπεδο σιγουριάς — πόσο σίγουροι θέλετε να είστε πριν κηρύξετε ένα νικητή. 95% είναι το πρότυπο του κλάδου.
- Υπόθεση — δύο όψεων ρωτά «Είναι το B διαφορετικό από το A;» (ασφαλέστερο, το προεπιλεγμένο). ένα όψης ρωτά μόνο «Είναι το B καλύτερο από το A;» (πιο ευαίσθητο, αλλά πρέπει να αποφασίσετε την κατεύθυνση πριν εκτελέσετε τη δοκιμή).
Το αποτέλεσμα ενημερώνεται ζωντανά και οι είσοδοι αποθηκεύονται στη διεύθυνση URL της σελίδας, ώστε να μπορείτε να σημειώσετε ή να κάνετε κοινή χρήση ενός αποτελέσματος. Το Επαναφορά διαγράφει τη φόρμα. Το Φόρτωση δεδομένων δείγματος συμπληρώνει ένα εργαλειακό παράδειγμα.
Ένα εργαλειακό παράδειγμα
| Επισκέπτες | Μετατροπές | Ποσοστό | |
|---|---|---|---|
| A (έλεγχος) | 1.000 | 100 | 10,0% |
| B (παραλλαγή) | 1.000 | 150 | 15,0% |
Αυτό είναι ένα ανάβασμα 5 ποσοστιαίων μονάδων και ένα ανάβασμα +50% σχετικό. Η αριθμομηχανή επιστρέφει μια p-τιμή περίπου 0,0007 — κάτω από 0,05 — οπότε με 95% σιγουριά το αποτέλεσμα είναι στατιστικά σημαντικό. Σχετικά, αν οι δύο εκδόσεις ήταν πραγματικά πανομοιότυπες, θα δείτε ένα κενό τόσο μεγάλο λιγότερο από μία φορά σε χίλια δοκιμές.
Τα μαθηματικά (δοκιμή z δύο αναλογιών)
Κάτω από την κουκούλα αυτή είναι η τυπική δοκιμή z δύο αναλογιών, την ίδια δοκιμή που διδάσκεται στην εισαγωγική στατιστική και χρησιμοποιείται από τα κύρια εργαλεία A/B.
-
Ποσοστό μετατροπής κάθε ομάδας:
όπου είναι μετατροπές και είναι επισκέπτες.
-
Συγκεντρωμένο ποσοστό, υποθέτοντας (για την μηδενική υπόθεση) και οι δύο ομάδες μοιράζονται ένα πραγματικό ποσοστό:
-
Τυπικό σφάλμα της διαφοράς:
-
Η z-σκορ — πόσα τυπικά σφάλματα χωρίζουν τα δύο ποσοστά:
-
Η p-τιμή προέρχεται από την τυπική κανονική κατανομή . Δύο όψεων: . Ένα όψης: .
-
Σημαντικό όταν , όπου (οπότε 0,05 στο 95%).
Η αριθμομηχανή αναφέρει επίσης ένα διάστημα εμπιστοσύνης για τη διαφορά, υπολογισμένη με το μη συγκεντρωμένο τυπικό σφάλμα : το εύλογο εύρος για το πραγματικό κενό. Αν αυτό το διάστημα αποκλείει 0, το αποτέλεσμα είναι σημαντικό.
Με 95% σιγουριά, ένα z πέρα από ±1,96 (τα σκιασμένα ουρές, 5% της περιοχής) θεωρείται σημαντικό.
Ανάγνωση του αποτελέσματος ειλικρινά
- Η στατιστική σημαντικότητα δεν είναι επιχειρηματική σημαντικότητα. Ένα ανάβασμα 0,1% μπορεί να είναι στατιστικά πραγματικό αλλά όχι αξίζει να παραδοθεί.
- Μην κοιτάζετε και μην σταματήσετε νωρίς. Η έλεγχος της p-τιμής κάθε ημέρα και η διακοπή την στιγμή που πέσει κάτω από 0,05 αυξάνει το ποσοστό ψευδώς θετικών. Αποφασίστε το μέγεθος του δείγματος πριν και αφήστε τη δοκιμή να τελειωθεί.
- Παρακολουθήστε τον κανόνα του μεγέθους δείγματος. Η κανονική προσέγγιση είναι αξιόπιστη όταν κάθε ομάδα έχει τουλάχιστον ~10 μετατροπές και ~10 μη-μετατροπές. Με μικρούς αριθμούς, θεωρήστε το αποτέλεσμα ως κατευθυντήριο μόνο.
- Σιγουριά ≠ πιθανότητα B είναι καλύτερο. Ένα επίπεδο σιγουριάς 95% σημαίνει η διαδικασία είναι λάθος το πολύ 5% των φορών μακροπρόθεσμα — είναι μια δήλωση συχνοτήτων, όχι «95% πιθανότητα το B κερδίζει».
- Μία δοκιμή, ένα μετρικό. Δοκιμή πολλών μετρικών ή παραλλαγών ταυτόχρονα πολλαπλασιάζει την ευκαιρία ενός λάθους. διορθώστε το (π.χ. Bonferroni) ή προ-εγγραφή του ενός μετρικού που αποφασίζει τη δοκιμή.
Υπολογίστε το μόνοι σας
Κάθε απόσπασμα υπολογίζει τη δύο όψη p-τιμή για το εργαλειακό παράδειγμα παραπάνω.
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 = control visitors, conversions ; A2,B2 = variation visitors, conversions
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
3ΣΑΠ
Ποιο μέγεθος δείγματος χρειάζομαι; Αρκετό ώστε ένα νοητό ανάβασμα θα ήταν ανιχνεύσιμο. Ως πάτωμα, στοχεύστε για τουλάχιστον μερικές εκατοντάδες μετατροπές ανά παραλλαγή. χρησιμοποιήστε μια αποκλειστική αριθμομηχανή μεγέθους δείγματος με το ποσοστό βάσης και το μικρότερο ανάβασμα που αξίζει να ανιχνευθεί.
Δύο όψεων ή ένα όψης; Χρησιμοποιήστε δύο όψεων εκτός αν έχετε έναν σταθερό, προ-αποφασισμένο λόγο για να ενδιαφέρεστε μόνο για βελτίωση. Το ένα όψης διπλασιάζει την ευαισθησία σας αλλά απαγορεύει την αντίδραση στο B είναι χειρότερο.
Γιατί η αριθμομηχανή δείχνει ένα διάστημα εμπιστοσύνης; Δείχνει το εύλογο εύρος του πραγματικής διαφοράς, όχι μόνο ένα ναι/όχι απόφαση. Ένα ευρύ διάστημα που περνά 0 σημαίνει «δεν υπάρχουν αρκετά δεδομένα ακόμα».
Είναι αυτό Bayesian; Όχι — είναι μια δοκιμή z συχνοτήτων, η πιο ευρέως διδαγμένη και χρησιμοποιούμενη μέθοδος. Τα εργαλεία Bayesian A/B αναφέρουν «πιθανότητα B νικά A» αντί για μια p-τιμή. και οι δύο είναι έγκυρη, απαντούν σε λίγο διαφορετικές ερωτήσεις.