/ab-test-analysis
Design and analyze A/B tests, calculate statistical significance, and determine sample sizes for conversion optimization and experiment validation
$ npx -y skills add aj-geddes/useful-ai-prompts --skill ab-test-analysis --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/ab-test-analysis
Context preview
The summary Claude sees to decide when to auto-load this skill.
Design and analyze A/B tests, calculate statistical significance, and determine sample sizes for conversion optimization and experiment validation
SKILL.md
ab-test-analysis.SKILL.mdname: A/B Test Analysis
description: Design and analyze A/B tests, calculate statistical significance, and determine sample sizes for conversion optimization and experiment validation
A/B Test Analysis
Overview
A/B testing is a statistical method to compare two variants and determine which performs better, enabling data-driven optimization decisions.
When to Use
- Comparing two versions of a product feature, webpage, or marketing campaign
- Optimizing conversion rates, click-through rates, or user engagement metrics
- Making data-driven decisions with statistical confidence about changes
- Determining sample size requirements for experiment validity
- Analyzing treatment effects and measuring lift from interventions
- Evaluating whether observed differences are statistically significant
Core Components
- **Control Group**: Original version (A)
- **Treatment Group**: New variant (B)
- **Metric**: Outcome being measured
- **Sample Size**: Observations needed for power
- **Significance Level**: Type I error threshold (α = 0.05)
- **Power**: 1 - Type II error (typically 0.80)
Analysis Steps
1. Define success metric 2. Calculate sample size 3. Run experiment 4. Check assumptions 5. Perform statistical test 6. Calculate effect size 7. Interpret results
Implementation with Python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from scipy.stats import binom_test, ttest_ind, chi2_contingency
import seaborn as sns
# Sample A/B test data
np.random.seed(42)
# Scenario: Testing new checkout flow
control_conversions = np.random.binomial(1, 0.10, 10000)
treatment_conversions = np.random.binomial(1, 0.12, 10000)
control_revenue = np.random.exponential(50, 10000)
treatment_revenue = np.random.exponential(55, 10000)
# Create dataframes
df_control = pd.DataFrame({
'group': 'Control',
'converted': control_conversions,
'revenue': control_revenue,
})
df_treatment = pd.DataFrame({
'group': 'Treatment',
'converted': treatment_conversions,
'revenue': treatment_revenue,
})
df = pd.concat([df_control, df_treatment], ignore_index=True)
print("A/B Test Data Summary:")
print(df.groupby('group')[['converted', 'revenue']].agg({
'converted': ['sum', 'count', 'mean'],
'revenue': ['sum', 'mean', 'std'],
}))
# 1. Conversion Rate Test (Chi-square)
contingency_table = pd.crosstab(df['group'], df['converted'])
print("\nContingency Table:")
print(contingency_table)
chi2, p_value, dof, expected = chi2_contingency(contingency_table)
print(f"\nChi-square Test:")
print(f"Chi2 statistic: {chi2:.4f}")
print(f"P-value: {p_value:.4f}")
print(f"Significant: {'Yes' if p_value < 0.05 else 'No'}")
# 2. Conversion Rate Calculation
control_cr = df[df['group'] == 'Control']['converted'].mean()
treatment_cr = df[df['group'] == 'Treatment']['converted'].mean()
lift = (treatment_cr - control_cr) / control_cr * 100
print(f"\nConversion Rates:")
print(f"Control: {control_cr:.4f} ({control_cr*100:.2f}%)")
print(f"Treatment: {treatment_cr:.4f} ({treatment_cr*100:.2f}%)")
print(f"Lift: {lift:.2f}%")
# 3. Revenue Per User Test (T-test)
control_revenue = df[df['group'] == 'Control']['revenue']
treatment_revenue = df[df['group'] == 'Treatment']['revenue']
t_stat, p_value_revenue = ttest_ind(control_revenue, treatment_revenue)
print(f"\nRevenue Per User T-test:")
print(f"Control Mean: ${control_revenue.mean():.2f}")
print(f"Treatment Mean: ${treatment_revenue.mean():.2f}")
print(f"T-statistic: {t_stat:.4f}")
print(f"P-value: {p_value_revenue:.4f}")
print(f"Significant: {'Yes' if p_value_revenue < 0.05 else 'No'}")
# 4. Effect Size (Cohen's d)
def cohens_d(group1, group2):
n1, n2 = len(group1), len(group2)
var1, var2 = np.var(group1, ddof=1), np.var(group2, ddof=1)
pooled_std = np.sqrt(((n1-1)*var1 + (n2-1)*var2) / (n1+n2-2))
return (np.mean(group1) - np.mean(group2)) / pooled_std
effect_size = cohens_d(control_revenue, treatment_revenue)
print(f"\nEffect Size (Cohen's d): {effect_size:.4f}")
print("Interpretation: " + {
True: "Small effect (|d| < 0.2)",
False: {
True: "Medium effect (0.2 <= |d| < 0.8)",
False: "Large effect (|d| >= 0.8)"
}[abs(effect_size) < 0.8]
}[abs(effect_size) < 0.2])
# 5. Confidence Intervals
def confidence_interval(data, confidence=0.95):
n = len(data)
mean = np.mean(data)
se = stats.sem(data)
margin = se * stats.t.ppf((1 + confidence) / 2, n - 1)
return mean - margin, mean + margin
ci_control = confidence_interval(control_revenue)
ci_treatment = confidence_interval(treatment_revenue)
print(f"\n95% Confidence Intervals:")
print(f"Control: (${ci_control[0]:.2f}, ${ci_control[1]:.2f})")
print(f"Treatment: (${ci_treatment[0]:.2f}, ${ci_treatment[1]:.2f})")
# 6. Sample Size Calculation
def calculate_sample_size(baseline_cr, target_cr, significance=0.05, power=0.80):
from scipy.stats import norm
effect_size = 2 * (np.arcsin(np.sqrt(target_cr)) - np.arcsin(np.sqrt(baseline_cr)))
z_alpha = norm.ppf(1 - significance/2)
z_beta = norm.ppf(power)
n = ((z_alpha + z_beta) / effect_size) ** 2
return int(np.ceil(n))
sample_size_needed = calculate_sample_size(control_cr, treatment_cr)
print(f"\nSample Size Analysis:")
print(f"Baseline CR: {control_cr:.4f}")
print(f"Target CR: {treatment_cr:.4f}")
print(f"Required per group: {sample_size_needed:,}")
print(f"Actual per group: {len(df[df['group'] == 'Control']):,}")
# 7. Sequential Testing / Running Analysis
fig, axes = plt.subplots(2, 2, figsize=(14, 8))
# Cumulative conversion rates
control_cumsum = df[df['group'] == 'Control']['converted'].cumsum()
treatment_cumsum = df[df['group'] == 'Treatment']['converted'].cumsum()
control_n = np.arange(1, len(control_cumsum) + 1)
treatment_n = np.arange(1, len(treatment_cumsum) + 1)
axes[0, 0].plot(control_n, control_cumsum / control_n, label='Control', alpha=0.7)
axes[0, 0].plot(treatment_n, treatment_cumsum / treatment_n, lRead more
name: A/B Test Analysis description: Design and analyze A/B tests, calculate statistical significance, and determine sample sizes for conversion optimization and experiment validation
A/B Test Analysis
Overview
A/B testing is a statistical method to compare two variants and determine which performs better, enabling data-driven optimization decisions.
When to Use
- Comparing two versions of a product feature, webpage, or marketing campaign
- Optimizing conversion rates, click-through rates, or user engagement metrics
- Making data-driven decisions with statistical confidence about changes
- Determining sample size requirements for experiment validity
- Analyzing treatment effects and measuring lift from interventions
- Evaluating whether observed differences are statistically significant
Core Components
- **Control Group**: Original version (A)
- **Treatment Group**: New variant (B)
- **Metric**: Outcome being measured
- **Sample Size**: Observations needed for power
- **Significance Level**: Type I error threshold (α = 0.05)
- **Power**: 1 - Type II error (typically 0.80)
Analysis Steps
1. Define success metric 2. Calculate sample size 3. Run experiment 4. Check assumptions 5. Perform statistical test 6. Calculate effect size 7. Interpret results
Implementation with Python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from scipy.stats import binom_test, ttest_ind, chi2_contingency
import seaborn as sns
# Sample A/B test data
np.random.seed(42)
# Scenario: Testing new checkout flow
control_conversions = np.random.binomial(1, 0.10, 10000)
treatment_conversions = np.random.binomial(1, 0.12, 10000)
control_revenue = np.random.exponential(50, 10000)
treatment_revenue = np.random.exponential(55, 10000)
# Create dataframes
df_control = pd.DataFrame({
'group': 'Control',
'converted': control_conversions,
'revenue': control_revenue,
})
df_treatment = pd.DataFrame({
'group': 'Treatment',
'converted': treatment_conversions,
'revenue': treatment_revenue,
})
df = pd.concat([df_control, df_treatment], ignore_index=True)
print("A/B Test Data Summary:")
print(df.groupby('group')[['converted', 'revenue']].agg({
'converted': ['sum', 'count', 'mean'],
'revenue': ['sum', 'mean', 'std'],
}))
# 1. Conversion Rate Test (Chi-square)
contingency_table = pd.crosstab(df['group'], df['converted'])
print("\nContingency Table:")
print(contingency_table)
chi2, p_value, dof, expected = chi2_contingency(contingency_table)
print(f"\nChi-square Test:")
print(f"Chi2 statistic: {chi2:.4f}")
print(f"P-value: {p_value:.4f}")
print(f"Significant: {'Yes' if p_value < 0.05 else 'No'}")
# 2. Conversion Rate Calculation
control_cr = df[df['group'] == 'Control']['converted'].mean()
treatment_cr = df[df['group'] == 'Treatment']['converted'].mean()
lift = (treatment_cr - control_cr) / control_cr * 100
print(f"\nConversion Rates:")
print(f"Control: {control_cr:.4f} ({control_cr*100:.2f}%)")
print(f"Treatment: {treatment_cr:.4f} ({treatment_cr*100:.2f}%)")
print(f"Lift: {lift:.2f}%")
# 3. Revenue Per User Test (T-test)
control_revenue = df[df['group'] == 'Control']['revenue']
treatment_revenue = df[df['group'] == 'Treatment']['revenue']
t_stat, p_value_revenue = ttest_ind(control_revenue, treatment_revenue)
print(f"\nRevenue Per User T-test:")
print(f"Control Mean: ${control_revenue.mean():.2f}")
print(f"Treatment Mean: ${treatment_revenue.mean():.2f}")
print(f"T-statistic: {t_stat:.4f}")
print(f"P-value: {p_value_revenue:.4f}")
print(f"Significant: {'Yes' if p_value_revenue < 0.05 else 'No'}")
# 4. Effect Size (Cohen's d)
def cohens_d(group1, group2):
n1, n2 = len(group1), len(group2)
var1, var2 = np.var(group1, ddof=1), np.var(group2, ddof=1)
pooled_std = np.sqrt(((n1-1)*var1 + (n2-1)*var2) / (n1+n2-2))
return (np.mean(group1) - np.mean(group2)) / pooled_std
effect_size = cohens_d(control_revenue, treatment_revenue)
print(f"\nEffect Size (Cohen's d): {effect_size:.4f}")
print("Interpretation: " + {
True: "Small effect (|d| < 0.2)",
False: {
True: "Medium effect (0.2 <= |d| < 0.8)",
False: "Large effect (|d| >= 0.8)"
}[abs(effect_size) < 0.8]
}[abs(effect_size) < 0.2])
# 5. Confidence Intervals
def confidence_interval(data, confidence=0.95):
n = len(data)
mean = np.mean(data)
se = stats.sem(data)
margin = se * stats.t.ppf((1 + confidence) / 2, n - 1)
return mean - margin, mean + margin
ci_control = confidence_interval(control_revenue)
ci_treatment = confidence_interval(treatment_revenue)
print(f"\n95% Confidence Intervals:")
print(f"Control: (${ci_control[0]:.2f}, ${ci_control[1]:.2f})")
print(f"Treatment: (${ci_treatment[0]:.2f}, ${ci_treatment[1]:.2f})")
# 6. Sample Size Calculation
def calculate_sample_size(baseline_cr, target_cr, significance=0.05, power=0.80):
from scipy.stats import norm
effect_size = 2 * (np.arcsin(np.sqrt(target_cr)) - np.arcsin(np.sqrt(baseline_cr)))
z_alpha = norm.ppf(1 - significance/2)
z_beta = norm.ppf(power)
n = ((z_alpha + z_beta) / effect_size) ** 2
return int(np.ceil(n))
sample_size_needed = calculate_sample_size(control_cr, treatment_cr)
print(f"\nSample Size Analysis:")
print(f"Baseline CR: {control_cr:.4f}")
print(f"Target CR: {treatment_cr:.4f}")
print(f"Required per group: {sample_size_needed:,}")
print(f"Actual per group: {len(df[df['group'] == 'Control']):,}")
# 7. Sequential Testing / Running Analysis
fig, axes = plt.subplots(2, 2, figsize=(14, 8))
# Cumulative conversion rates
control_cumsum = df[df['group'] == 'Control']['converted'].cumsum()
treatment_cumsum = df[df['group'] == 'Treatment']['converted'].cumsum()
control_n = np.arange(1, len(control_cumsum) + 1)
treatment_n = np.arange(1, len(treatment_cumsum) + 1)
axes[0, 0].plot(control_n, control_cumsum / control_n, label='Control', alpha=0.7)
axes[0, 0].plot(treatment_n, treatment_cumsum / treatment_n, l488 production-ready AI prompts, all following a standardized template with validated quality gates. Transform ChatGPT, Claude, and other AI assistants into expert consultants.
Repo: aj-geddes/useful-ai-prompts
Other skills on useful-ai-prompts.
- /access-control-rbac
Implement Role-Based Access Control (RBAC), permissions management, and authorization policies. Use when building secure access control systems with fine-grained permissions.
Open skill - /accessibility-compliance
Implement WCAG 2.1/2.2 accessibility standards, screen reader compatibility, keyboard navigation, and a11y testing. Use when building inclusive web applications, ensuring regulatory compliance, or improving user experience for people with disabilities.
Open skill - /accessibility-testing
Test web applications for WCAG compliance and ensure usability for users with disabilities. Use for accessibility test, a11y, axe, ARIA, keyboard navigation, screen reader compatibility, and WCAG validation.
Open skill - /agile-sprint-planning
Plan and execute effective sprints using Agile methodologies. Define sprint goals, estimate user stories, manage sprint backlog, and facilitate daily standups to maximize team productivity and deliver value incrementally.
Open skill - /alert-management
Implement comprehensive alert management with PagerDuty, escalation policies, and incident coordination. Use when setting up alerting systems, managing on-call schedules, or coordinating incident response.
Open skill - /android-kotlin-development
Develop native Android apps with Kotlin. Covers MVVM with Jetpack, Compose for modern UI, Retrofit for API calls, Room for local storage, and navigation architecture.
Open skill

