เครื่องคิดเลขความสำคัญทางสถิติของการทดสอบ A/B
ตรวจสอบว่าผลลัพธ์การทดสอบ A/B ของคุณมีนัยสำคัญทางสถิติหรือไม่ ป้อนผู้มาเยี่ยมชมและการแปลงเพื่อรับ p-value, z-score, ช่วงความเชื่อมั่น และการยกระดับสัมพัทธ์
เครื่องคิดเลขความสำคัญทางสถิติของการทดสอบ 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-value: โอกาสในการเห็นช่องว่างอย่างน้อยขนาดนี้ หากเวอร์ชันทั้งสองเหมือนกันจริง ๆ p-value ที่เล็ก (เช่น ต่ำกว่า 0.05) หมายความว่า "สิ่งนี้จะไม่เกิดขึ้นโดยบังเอิญ ดังนั้นความแตกต่างอาจเป็นของจริง"
วิธีการใช้
- ผู้มาเยี่ยมชม — จำนวนคนที่แสดงเวอร์ชันแต่ละรุ่นจำนวนเท่าใด
- การแปลง — จำนวนที่พวกเขากระทำสิ่งที่คุณสนใจ (ซื้อ ลงทะเบียน คลิก)
- ระดับความเชื่อมั่น — คุณต้องการแน่ใจแค่ไหนก่อนที่จะเรียกผู้ชนะ 95% เป็นมาตรฐานของอุตสาหกรรม
- สมมติฐาน — สองด้าน ถาม "B แตกต่างจาก A หรือไม่" (ปลอดภัยกว่า ค่าเริ่มต้น); ด้านเดียว ถาม เพียง "B ดีกว่า A หรือไม่" (ละเอียดอ่อนมากขึ้น แต่คุณต้องตัดสินใจทิศทางก่อนเรียกใช้การทดสอบ)
ผลลัพธ์อัปเดตแบบสดและอินพุตจะถูกจัดเก็บไว้ใน URL หน้า ดังนั้นคุณสามารถบุ๊คมาร์ก หรือแชร์ผลลัพธ์ได้ รีเซ็ต ล้างแบบฟอร์ม; โหลดข้อมูลตัวอย่าง เติมตัวอย่างที่ได้รับการแก้ไข
ตัวอย่างที่ได้รับการแก้ไข
| ผู้มาเยี่ยมชม | การแปลง | อัตรา | |
|---|---|---|---|
| A (ควบคุม) | 1,000 | 100 | 10.0% |
| B (รูปแบบแปรผัน) | 1,000 | 150 | 15.0% |
นี่คือการยกระดับแบบสัมบูรณ์ 5 จุดเปอร์เซ็นต์ และยกระดับสัมพัทธ์ +50% เครื่องคิดเลขคืนค่า p-value ประมาณ 0.0007 — ต่ำกว่า 0.05 — ดังนั้นที่ระดับความเชื่อมั่น 95% ผลลัพธ์จึง มีนัยสำคัญทางสถิติ โดยคร่าว ๆ หากเวอร์ชันทั้งสองเหมือนกันจริง ๆ คุณจะเห็นช่องว่างขนาดนี้น้อยกว่าหนึ่งครั้งในการทดสอบหนึ่งพันครั้ง
คณิตศาสตร์ (การทดสอบ z สัดส่วนสอง)
ใต้ฝากี่นี้เป็นการทดสอบ z สัดส่วนสองมาตรฐาน two-proportion z-test ซึ่งเป็นการทดสอบเดียวกับที่สอนในสถิติเบื้องต้นและใช้โดยเครื่องมือ A/B หลัก
-
อัตราการแปลงของแต่ละกลุ่ม:
โดยที่ คือการแปลงและ คือผู้มาเยี่ยมชม
-
อัตรา รวมกลุ่ม โดยถือว่า (สำหรับสมมติฐานว่าง) ทั้งสองกลุ่มใช้อัตราจริงเดียว:
-
ข้อผิดพลาดมาตรฐานของความแตกต่าง:
-
z-score — จำนวนของข้อผิดพลาดมาตรฐานที่อัตราทั้งสองแตกต่างกัน:
-
p-value มาจากการแจกแจงแบบปกติมาตรฐาน สองด้าน: ด้านเดียว:
-
มีนัยสำคัญ เมื่อ โดยที่ (ดังนั้น 0.05 ที่ 95%)
เครื่องคิดเลขยังรายงาน ช่วงความเชื่อมั่น สำหรับความแตกต่าง คำนวณด้วยข้อผิดพลาดมาตรฐาน unpooled : ช่วงที่เป็นไปได้สำหรับช่องว่างจริง หากช่วงนั้นไม่รวม 0 ผลลัพธ์จึงมีนัยสำคัญ
ที่ระดับความเชื่อมั่น 95% z ที่เกิน ±1.96 (หางที่แรเงา 5% ของพื้นที่) จะถูกนับว่ามีนัยสำคัญ
อ่านผลลัพธ์อย่างสุจริต
- ความสำคัญทางสถิติไม่ใช่ความสำคัญทางธุรกิจ การยกระดับ 0.1% อาจเป็นของจริงในทางสถิติแต่ไม่คุ้มกับการส่ง
- อย่าแอบมองและหยุดเร็ว การตรวจสอบ p-value ทุกวันและหยุดในขณะที่ตกต่ำกว่า 0.05 จะทำให้อัตราผลบวกเท็จของคุณเพิ่มขึ้น ตัดสินใจขนาดตัวอย่างล่วงหน้าและปล่อยให้การทดสอบเสร็จสิ้น
- ดูกฎ หัวแม่มือของขนาดตัวอย่าง การประมาณแบบปกติน่าเชื่อถือเมื่อแต่ละกลุ่มมีการแปลงอย่างน้อย ~10 และ ~10 ไม่มีการแปลง ด้วยตัวเลขเล็กน้อย ให้ถือว่าผลลัพธ์เป็นเพียงการนำทาง
- ความเชื่อมั่น ≠ ความน่าจะเป็น B ดีกว่า ระดับความเชื่อมั่น 95% หมายความว่า ขั้นตอน ผิดอย่างมากที่สุด 5% ของเวลาในระยะยาว — มันเป็นคำกล่าวแบบบ่อยครั้ง ไม่ใช่ "95% โอกาส B ชนะ"
- การทดสอบหนึ่ง เมตริกหนึ่ง การทดสอบเมตริกหรือรูปแบบจำนวนมากพร้อมกันจะเพิ่มโอกาสของเสียงเดียว; แก้ไข (เช่น Bonferroni) หรือลงทะเบียนเมตริกเดียวที่ตัดสินใจการทดสอบ
คำนวณด้วยตัวเอง
แต่ละเฉพาะคำนวณ p-value สองด้านสำหรับตัวอย่างที่ได้รับการแก้ไขข้างต้น
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 หรือไม่ ไม่ — มันเป็น frequentist z-test วิธีที่สอนและใช้กันอย่างแพร่หลาย เครื่องมือ A/B แบบ Bayesian รายงาน "ความน่าจะเป็น B เอาชนะ A" แทนที่จะเป็น p-value; ทั้งสองไม่มีปัญหา พวกเขาตอบคำถามที่แตกต่างกันเล็กน้อย