Kalkulator Kepentingan Ujian A/B
Periksa sama ada hasil ujian A/B anda signifikan secara statistik. Masukkan pelawat dan penukaran untuk mendapatkan nilai-p, skor-z, selang keyakinan, dan lif relatif.
Kalkulator Kepentingan Ujian A/B
Masukkan pelawat dan penukaran untuk setiap varian untuk memeriksa sama ada perbezaan adalah nyata atau hanya hingar.
Hasil
Signifikan Secara Statistik
Perbezaan itu tidak mungkin disebabkan oleh kebetulan pada tahap keyakinan pilihan anda.
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.
Dokumentasi
Ujian A/B dalam satu minit
Anda mengubah butang, tajuk, atau aliran pembayaran. Versi A adalah yang lama, versi B adalah yang baru. B kelihatan lebih baik โ ia menukar 15% pelawat berbanding 10% untuk A. Tetapi bolehkah jurang itu hanya keberuntungan, cara yang sama dengan membalik syiling sepuluh kali boleh memberikan tujuh kepala?
Kalkulator ini menjawab tepat itu. Anda memasukkan berapa ramai orang yang melihat setiap versi dan berapa yang ditukar, dan ia memberitahu anda kebarangkalian bahawa perbezaan yang anda ukur adalah nyata daripada hingar rawak. Jika kebarangkalian itu cukup tinggi, anda mempunyai pemenang. Jika tidak, anda terus menjalankan ujian.
Nombor yang perlu diperhatikan adalah nilai-p: peluang melihat jurang sekurang-kurangnya sebesar ini jika kedua-dua versi sebenarnya sama. Nilai-p yang kecil (misalnya, di bawah 0.05) bermaksud "ini jarang berlaku kebetulan, jadi perbezaan mungkin nyata."
Cara menggunakannya
- Pelawat โ berapa ramai orang unik yang ditunjukkan setiap versi.
- Penukaran โ berapa ramai daripada mereka melakukan perkara yang anda ambil berat (membeli, mendaftar, mengklik).
- Tahap keyakinan โ seberapa yakin anda ingin menjadi sebelum memanggil pemenang. 95% adalah standard industri.
- Hipotesis โ dua hala bertanya "adakah B berbeza daripada A?" (lebih selamat, lalai); satu hala hanya bertanya "adakah B lebih baik daripada A?" (lebih sensitif, tetapi anda mesti memutuskan arah sebelum menjalankan ujian).
Hasil dikemas kini secara langsung dan input disimpan dalam URL halaman, jadi anda boleh menanda isyarat atau berkongsi hasil. Tetapkan semula mengosongkan borang; Muat data sampel mengisi contoh yang dilakukan.
Contoh yang dilakukan
| Pelawat | Penukaran | Kadar | |
|---|---|---|---|
| A (kawalan) | 1,000 | 100 | 10.0% |
| B (variasi) | 1,000 | 150 | 15.0% |
Itu adalah lif mutlak 5 mata peratusan dan lif relatif +50%. Kalkulator mengembalikan nilai-p kira-kira 0.0007 โ di bawah 0.05 โ jadi pada keyakinan 95% hasilnya signifikan secara statistik. Secara kasar, jika kedua-dua versi benar-benar sama, anda akan melihat jurang sebesar ini kurang daripada sekali dalam seribu ujian.
Matematik (ujian z dua perkadaran)
Di bawah penutup ini adalah ujian z dua perkadaran standard, ujian yang sama diajarkan dalam statistik pengenalan dan digunakan oleh alat A/B arus perdana.
-
Kadar penukaran setiap kumpulan:
di mana adalah penukaran dan adalah pelawat.
-
Kadar terkumpul, dengan menganggap (untuk hipotesis nol) kedua-dua kumpulan berkongsi satu kadar sebenar:
-
Ralat standard perbezaan:
-
Skor-z โ berapa banyak ralat standard selain dua kadar:
-
Nilai-p datang daripada taburan normal standard . Dua hala: . Satu hala: .
-
Signifikan apabila , di mana (jadi 0.05 pada 95%).
Kalkulator juga melaporkan selang keyakinan untuk perbezaan, dikira dengan ralat standard yang tidak terkumpul : julat yang masuk akal untuk jurang sebenar. Jika selang itu mengecualikan 0, hasilnya signifikan.
Pada keyakinan 95%, z di luar ยฑ1.96 (ekor berlorek, 5% daripada kawasan) dikira sebagai signifikan.
Membaca hasilnya dengan jujur
- Kepentingan statistik bukan kepentingan perniagaan. Lif 0.1% boleh menjadi nyata secara statistik namun tidak bernilai dihantar.
- Jangan mengintip dan berhenti awal. Memeriksa nilai-p setiap hari dan menghentikan saat ia turun di bawah 0.05 meningkatkan kadar positif palsu anda. Tentukan saiz sampel di hadapan dan biarkan ujian selesai.
- Perhatikan peraturan jempol saiz sampel. Anggaran normal adalah dipercayai apabila setiap kumpulan mempunyai sekurang-kurangnya ~10 penukaran dan ~10 bukan penukaran. Dengan nombor-nombor kecil, anggap hasilnya hanya berarah.
- Keyakinan โ kebarangkalian B lebih baik. Tahap keyakinan 95% bermaksud prosedur salah paling 5% daripada masa dalam jangka panjang โ ia adalah pernyataan frequentist, bukan "peluang 95% B menang."
- Satu ujian, satu metrik. Menguji banyak metrik atau varian serentak mengalikan peluang kebetulan; betulkan untuk itu (cth Bonferroni) atau daftar awal metrik tunggal yang menentukan ujian.
Kira sendiri
Setiap cebisan mengira nilai-p dua hala untuk contoh yang dilakukan di atas.
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
3Soalan Lazim
Apakah saiz sampel yang saya perlukan? Cukup sehinggakan lif bermakna boleh dikesan. Sebagai lantai, sasarkan sekurang-kurangnya beberapa ratus penukaran per varian; gunakan kalkulator saiz sampel berdedikasi dengan kadar asas anda dan lif terkecil bernilai mengesan.
Dua hala atau satu hala? Gunakan dua hala melainkan anda mempunyai sebab yang kukuh dan pra-komitmen untuk hanya peduli tentang peningkatan. Satu hala menggandakan sensitiviti anda tetapi melarang bertindak balas kepada B menjadi lebih teruk.
Mengapa kalkulator menunjukkan selang keyakinan? Ia menunjukkan julat yang boleh diterima bagi perbezaan sebenar, bukan hanya keputusan ya/tidak. Selang lebar yang meletak 0 bermaksud "belum cukup data lagi."
Adakah ini Bayesian? Tidak โ ia adalah ujian z frequentist, kaedah yang paling banyak diajarkan dan digunakan. Alat A/B Bayesian melaporkan "kebarangkalian B mengalahkan A" bukan nilai-p; kedua-duanya sah, mereka menjawab soalan yang sedikit berbeza.