ניתוח מובהקות סטטיסטית למבחני A/B
הרצתם מבחן A/B וראיתם p < 0.05? עצרו. אם תפסיקו את המבחן בסימן הראשון למובהקות, ההסתברות לתוצאה חיובית שגויה עולה ל-26%. תרחיש טיפוסי: מעצב עיצב מחדש כפתור, המבחן הראה שיפור בהמרה תוך יומיים, אבל שבוע לאחר מכן האפקט נעלם. הצצה (Peeking) היא הטעות היקרה ביותר בניסויי פיצול. ניתחנו 50+ פרויקטים ואנו מבטיחים שעם הגישה שלנו תימנעו מטעות זו וממלכודות אחרות.
מדוע מובהקות סטטיסטית קריטית למבחני A/B?
מובהקות סטטיסטית היא האישור המתמטי לכך שההבדל בין הגרסאות אינו נובע ממקריות. בלעדיה, אתם מסתכנים ביישום שינוי שלמעשה פוגע במדדים. או לחלופין, דוחים שיפור רווחי בגלל רעש. אנו משתמשים בשתי גישות: פרקוונטיסטית (Frequentist) ובייסיאנית (Bayesian). כל אחת פותרת סוג משלה של בעיות.
כיצד גישות פרקוונטיסטיות ובייסיאניות עוזרות להימנע מטעויות?
P-value — ההסתברות לראות אפקט קיצוני כמו זה שהתקבל, תחת השערת האפס. סף של 0.05 הוא סטנדרטי, אך הוא אינו משקף את גודל האפקט. רמת ביטחון (בדרך כלל 95%) משמעותה שאנו מוכנים לטעות ב-5% מהמקרים. עוצמה סטטיסטית (80%) — היכולת לזהות אפקט אמיתי. MDE — האפקט המינימלי שהמבחן יזהה בהינתן גודל המדגם.
מבחן Z לפרופורציות
from scipy.stats import proportions_ztest, chi2_contingency
import numpy as np
def analyze_test(control_n, control_conv, variant_n, variant_conv, alpha=0.05):
cr_control = control_conv / control_n
cr_variant = variant_conv / variant_n
relative_lift = (cr_variant - cr_control) / cr_control * 100
# Z-тест (применим при n > 30)
counts = np.array([variant_conv, control_conv])
nobs = np.array([variant_n, control_n])
z_stat, p_value = proportions_ztest(counts, nobs, alternative='two-sided')
# Доверительный интервал для разницы
se = np.sqrt(
cr_control * (1 - cr_control) / control_n + cr_variant * (1 - cr_variant) / variant_n
)
diff = cr_variant - cr_control
z_crit = 1.96 # для 95% CI
ci_low = diff - z_crit * se
ci_high = diff + z_crit * se
print(f"Control: {cr_control:.3%} ({control_conv}/{control_n})")
print(f"Variant: {cr_variant:.3%} ({variant_conv}/{variant_n})")
print(f"Lift: {relative_lift:+.1f}%")
print(f"95% CI: [{ci_low:.3%}, {ci_high:.3%}]")
print(f"P-value: {p_value:.4f}")
print(f"Significant: {'YES ✓' if p_value < alpha else 'NO ✗'}")
return p_value < alpha
analyze_test(
control_n=3842,
control_conv=115,
variant_n=3891,
variant_conv=148
) מבחן חי-בריבוע (חלופה למבחן Z)
from scipy.stats import chi2_contingency
contingency = np.array([
[control_conv, control_n - control_conv], # Control: converts, not converts
[variant_conv, variant_n - variant_conv] # Variant: converts, not converts
])
chi2, p_value, dof, expected = chi2_contingency(contingency)
print(f"Chi2: {chi2:.4f}, p={p_value:.4f}")מבחן חי-בריבוע ומבחן Z נותנים תוצאות זהות עבור שתי קבוצות.
מהי הצצה (Peeking) וכיצד להימנע ממנה?
הצצה — עצירת מבחן ברגע שמופיע p < 0.05, מבלי להמתין לגודל המדגם המחושב. זה מנפח את שיעור שגיאת הסוג הראשון ל-26% ב-alpha=0.05. פתרון: חשבו מראש את גודל המדגם הנדרש ואל תפריעו למבחן עד שהוא מושג.
# Неправильно: проверять каждый день и останавливать при p < 0.05
# Правильно: рассчитать объём заранее, остановить только после его достижения
def required_sample_size(baseline_cr, mde, alpha=0.05, power=0.8):
from scipy import stats
import math
p1, p2 = baseline_cr, baseline_cr * (1 + mde)
p_avg = (p1 + p2) / 2
z_a = stats.norm.ppf(1 - alpha/2)
z_b = stats.norm.ppf(power)
n = ((z_a * math.sqrt(2 * p_avg * (1-p_avg)) + z_b * math.sqrt(p1*(1-p1) + p2*(1-p2))) / (p2-p1)) ** 2
return math.ceil(n)
n = required_sample_size(baseline_cr=0.03, mde=0.15)
print(f"Run test until {n} users per variant reached")להשוואות מרובות, השתמשו בתיקון Bonferroni:
# Bonferroni correction для множественных сравнений
n_comparisons = 4 # 4 варианта vs контроль
corrected_alpha = 0.05 / n_comparisons # = 0.0125
# Или FDR (Benjamini-Hochberg)
from statsmodels.stats.multitest import multipletests
p_values = [0.03, 0.07, 0.01, 0.04]
reject, corrected_p, _, _ = multipletests(p_values, alpha=0.05, method='fdr_bh') ניתוח A/B בייסיאני: גישה הסתברותית
חלופה לגישה הפרקוונטיסטית — הסתברות שגרסה טובה יותר:
import numpy as np
def bayesian_ab_test(control_conv, control_n, variant_conv, variant_n, samples=100000):
"""Posterior distribution через Beta distribution"""
# Prior: Beta(1,1) = равномерное распределение
control_posterior = np.random.beta(
control_conv + 1,
control_n - control_conv + 1,
samples
)
variant_posterior = np.random.beta(
variant_conv + 1,
variant_n - variant_conv + 1,
samples
)
prob_variant_better = (variant_posterior > control_posterior).mean()
expected_lift = (variant_posterior - control_posterior).mean() / control_posterior.mean() * 100
print(f"Probability variant is better: {prob_variant_better:.1%}")
print(f"Expected lift: {expected_lift:+.1f}%")
print(f"Credible interval: [{np.percentile(variant_posterior - control_posterior, 2.5):.3%}, "
f"{np.percentile(variant_posterior - control_posterior, 97.5):.3%}]")
bayesian_ab_test(115, 3842, 148, 3891)הגישה הבייסיאנית נותנת את ההסתברות שהגרסה טובה יותר, ומאיצה את קבלת ההחלטות ב-20% בהשוואה לפרקוונטיסטית בתרחישי מבחנים מרובים.
פרקוונטיסטי לעומת בייסיאני: מתי להשתמש במה?
| קריטריון | פרקוונטיסטי | בייסיאני |
|---|---|---|
| פירוש | p-value, רווח בר-סמך | הסתברות של השערה |
| גודל מדגם נדרש | קבוע מראש | גמיש, ניתן למעקב |
| שילוב נתונים קודמים | לא | כן (קודם) |
| מורכבות חישובית | נמוכה | גבוהה יותר (סימולציות) |
| פופולריות | קלאסי, תקן תעשייתי | מודרני, אינטואיטיבי |
| מצב | החלטה |
|---|---|
| p < 0.05, שיפור > 0 | השקת הגרסה |
| p > 0.05, תנועה נמוכה | המשך המבחן |
| p > 0.05, הושג גודל המדגם | אין אפקט מובהק, סגירת המבחן |
| p < 0.05, שיפור שלילי | שמירה על קבוצת הביקורת |
| פלח אחד מובהק, אחר לא | ניתוח אינטראקציה, פריסה מפולחת |
תהליך ומה כלול
- אנליטיקה — אנו מנתחים את תוכנית הבדיקות הנוכחית שלכם, המטרות והמדדים.
- עיצוב — בחירת השיטה האופטימלית (פרקוונטיסטית/בייסיאנית), חישוב גודל המדגם.
- יישום — שילוב סקריפטים או חיבור ספרייה (למשל,
from scipy.stats import proportions_ztest, chi2_contingency import numpy as np def analyze_test(control_n, control_conv, variant_n, variant_conv, alpha=0.05): cr_control = control_conv / control_n cr_variant = variant_conv / variant_n relative_lift = (cr_variant - cr_control) / cr_control * 100 # Z-тест (применим при n > 30) counts = np.array([variant_conv, control_conv]) nobs = np.array([variant_n, control_n]) z_stat, p_value = proportions_ztest(counts, nobs, alternative='two-sided') # Доверительный интервал для разницы se = np.sqrt( cr_control * (1 - cr_control) / control_n + cr_variant * (1 - cr_variant) / variant_n ) diff = cr_variant - cr_control z_crit = 1.96 # для 95% CI ci_low = diff - z_crit * se ci_high = diff + z_crit * se print(f"Control: {cr_control:.3%} ({control_conv}/{control_n})") print(f"Variant: {cr_variant:.3%} ({variant_conv}/{variant_n})") print(f"Lift: {relative_lift:+.1f}%") print(f"95% CI: [{ci_low:.3%}, {ci_high:.3%}]") print(f"P-value: {p_value:.4f}") print(f"Significant: {'YES ✓' if p_value < alpha else 'NO ✗'}") return p_value < alpha analyze_test( control_n=3842, control_conv=115, variant_n=3891, variant_conv=148 )+from scipy.stats import chi2_contingency contingency = np.array([ [control_conv, control_n - control_conv], # Control: converts, not converts [variant_conv, variant_n - variant_conv] # Variant: converts, not converts ]) chi2, p_value, dof, expected = chi2_contingency(contingency) print(f"Chi2: {chi2:.4f}, p={p_value:.4f}")). - בדיקות — סימולציה על נתונים היסטוריים, אימות נכונות.
- פריסה — הגדרת לוח מחוונים אוטומטי עם תוצאות, תיעוד.
התוצר כולל קוד מקור של הניתוח (Python/R/JS) עם הערות, חישוב גודל המדגם הנדרש לפרמטרים שלכם, אינטגרציה עם מערכת המעקב שלכם (Google Analytics, Mixpanel, לוגים מותאמים אישית), הדרכה לצוות שלכם על פירוש תוצאות, ותמיכה למשך שבועיים לאחר הפריסה. אנו מבטיחים נכונות חישובים ודיוק מסקנות — הניסיון שלנו מאושר על ידי עשרות פרויקטים מוצלחים.
מסגרת זמן ועלות
הקמת ניתוח מובהקות סטטיסטית עם חישוב אוטומטי של גודל מדגם ובחירת בייסיאני/פרקוונטיסטי אורכת 1–2 ימי עסקים. העלות מחושבת באופן אישי לפי מורכבות האינטגרציה — בדרך כלל בין $60 ל-$240. בממוצע, לקוחות מקצרים את זמן הניתוח ב-30% ונמנעים מהפסדים מהחלטות שגויות, שעלולים לעלות לחברה עד $1,200 בחודש. קבעו ייעוץ — צרו קשר עוד היום!
רשימת בדיקה של טעויות נפוצות
- לא חישבנו מראש את גודל המדגם.
- עצרנו את המבחן ב-p < 0.05 הראשון.
- שכחנו מהשוואות מרובות.
- השתמשנו ב-p-value כקריטריון יחיד מבלי להתחשב בגודל האפקט.
- לא פילחנו את הקהל (למשל, מכשירים שונים).
צרו קשר כדי להקים ניתוח סטטיסטי אמין למבחני A/B שלכם ולקבל החלטות בטוחות. הזמינו ייעוץ על חישוב מובהקות סטטיסטית עוד היום — נעזור לכם להימנע מטעויות ולחסוך בתקציב.







