Калкулатор за значимост на 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, означава "още няма достатъчно данни."
Това Байезианско ли е? Не — това е честотиски z-тест, най-широко преподаваният и използван метод. Байезийските A/B инструменти отчитат "вероятност B побеждава A" вместо p-стойност; и двете са валидни, отговарят на малко различни въпроси.