Day 10
海外运营 × Codex 训练营

A/B 测试
自动数据分析

从 GA4 / Mixpanel / Amplitude 拉数据 → 让 Codex 算 p-value 和置信区间 → 自动生成"是否推全量"决策报告。不用学统计学。

讲师 Terrence 时长 90 分钟 产物 一份完整 A/B 决策报告 + 滚动发布计划
Day 10 · 开场

今天结束,你能做到

本节关键判断:A/B 测试 90% 的失败不是测错,是"结果出来了不会看"。今天就解决这一步。
Day 10 · 痛点

为什么 A/B 测试是海外运营最大的"假动作"?

87%
A/B 测试在没达到统计显著的情况下就停了,结论不可靠
14d
普通团队从"看到数据"到"敢做决策"平均要 14 天等数据团队排期
2.3×
看"总转化率"和看"segment 分布"会得出完全相反结论的概率(辛普森悖论)

意味着:你跑了 N 个 A/B 测试,大概率只有 13% 的结论靠谱——但你不知道是哪 13%。

Day 10 · 案例

今天的案例 · Landing Page 改版 A/B 测试

A 版 · 控制组

原版 landing page

  • 访问:12,500
  • 注册转化:387
  • 转化率:3.10%
B 版 · 实验组

改版后 landing page(新文案 + Hero 视频)

  • 访问:12,600
  • 注册转化:445
  • 转化率:3.53%
测试时长
14 天
流量分配
50 / 50
观察到的提升
+13.9%

关键问题:13.9% 提升听起来不错——但够统计显著吗?敢推全量吗?

Day 10 · 概念

4 个核心指标 · 60 秒讲完

1
p-value(显著性概率) · 越小越可信p < 0.05 = 这个差距是"巧合"的概率 < 5% → 可以下结论
2
置信区间(CI · Confidence Interval) · 真实提升的可能范围95% CI = [+2.1%, +25.7%] → 真实提升大概率在这个区间里
3
提升幅度(Lift / Uplift) · B 比 A 高多少3.53% / 3.10% - 1 = +13.9%。但看光这一个数会骗自己
4
统计功效(Power) · 测试是否"看得到"显著差异Power = 80%+ 表示样本量够。小于此值说明可能漏掉真实差异
口诀:p-value 看"是不是真的",置信区间看"有多大",Lift 看"涨多少",Power 看"够不够数"。4 个都达标,才能推全量
Day 10 · 工具栈

今天用的工具栈

1
Codex CLI · 主战场,让它写 Python 脚本算统计新工作目录 ~/ab-analysis/
2
数据来源 · 三选一 · GA4 / Mixpanel / AmplitudeCodex 都能拉,3 个 API 用法不同,今天讲通用方法
3
Python · scipy / statsmodels / pandasscipy.stats 一行算 p-value,statsmodels 算置信区间
4
可视化(可选) · matplotlib / plotlyCodex 默认会画图,PNG 嵌入 Markdown 报告
5
报告输出 · Markdown / HTML / PDFMarkdown 给老板看就够,要正式可让 Codex 转 PDF
不要做的事:不要去网上找 A/B 测试计算器手动填——慢、易错、不可复用。让 Codex 一次写好脚本,下次测试只换数据
Day 10 · Prompt

今天的核心 Prompt(一字不差喂给 Codex)

我跑了一个 A/B 测试(landing page 改版),数据: - A 版(控制组):访问 12,500,转化 387 - B 版(新版):访问 12,600,转化 445 - 测试时长 14 天 请帮我: 1) 用 Codex 算 p-value / 置信区间 / 提升幅度 / 显著性是否达标(95%) 2) 按 segment 切:移动端 vs 桌面 / 新用户 vs 老用户 / 各国家 → 是否有 segment 反向? 3) 检查样本偏差(流量分配是否真 50/50) 4) 写一页 Markdown 决策报告: - 结论:推全量 / 不推 / 继续测 - 关键数据 - segment 洞察 - 风险提示(比如 novelty effect 新奇效应) 5) 如果决定推全量,给一个滚动发布计划 (10% → 50% → 100%) 要求:所有数据用 pandas DataFrame 处理; 统计计算用 scipy.stats; 报告输出到 ./reports/ab_test_landing_2026-05-26.md; 带 matplotlib 生成的对比柱状图嵌入报告。
Day 10 · 演示

Codex 跑完 · 终端输出

$ python src/analyze.py --data data/ab_test.csv --report [1/5] Loading data... ✓ A: 12500 visits, B: 12600 visits [2/5] Sample size check... ✓ Power = 84.2% (recommended 80%+) [3/5] Statistical tests... A conversion: 3.10% (387 / 12500) B conversion: 3.53% (445 / 12600) Lift: +13.93% p-value: 0.0312 ← < 0.05 ✓ SIGNIFICANT 95% CI: [+1.2%, +27.5%] [4/5] Segment analysis... mobile: A 2.8%, B 3.6% (+28.6%, p=0.018) ← strong winner desktop: A 3.5%, B 3.4% (-2.9%, p=0.71) ← no effect new: A 2.1%, B 3.1% (+47.6%, p=0.003) ← biggest win return: A 4.8%, B 4.1% (-14.6%, p=0.09) ← potential regression [5/5] Generating report... ✓ reports/ab_test_landing_2026-05-26.md ✓ reports/charts/conversion.png DECISION: 推全量,但建议保留 return-user 对照组观察 2 周 ROLLOUT PLAN: 10% (3d) → 50% (4d) → 100%
Day 10 · 拆解

3 行代码 = 整个 A/B 测试统计核心

from scipy import stats from statsmodels.stats.proportion import proportions_ztest, confint_proportions_2indep # 1. 卡方检验 / Z 检验 算 p-value counts = [387, 445] # A B 的转化数 nobs = [12500, 12600] # A B 的访问数 z, p_value = proportions_ztest(counts, nobs) # → p_value = 0.0312 # 2. 算 95% 置信区间(提升幅度的区间) ci_low, ci_high = confint_proportions_2indep( count1=445, nobs1=12600, count2=387, nobs2=12500, method='wald', compare='ratio') # → CI = [+1.2%, +27.5%] # 3. 算 Power(事前 / 事后) from statsmodels.stats.power import zt_ind_solve_power power = zt_ind_solve_power( effect_size=0.0286, nobs1=12500, alpha=0.05, ratio=1.008) # → power = 0.842 → 样本量够

这 3 段是统计学课本上的"考点",但你不用记——Codex 写一次后永久存在你脚本里

Day 10 · 切片

辛普森悖论 · 总数赢、分段输的诡异现象

看总数

B 版赢 +13.9%

看起来很美好,赶紧推全量?

  • A: 387 / 12500 = 3.10%
  • B: 445 / 12600 = 3.53%
  • p = 0.031 显著 ✓
切 segment 看

老用户 -14.6%(反向)

新用户大涨,老用户跌——总数被新用户拉起来的

  • 新用户:+47.6% (拉了均值)
  • 老用户:-14.6% (p = 0.09 边缘)
  • 移动端:+28.6%,桌面端:无效
这种情况怎么办?不是"不推",而是"推但分人群"——新用户走 B 版,老用户继续 A 版,等 2 周再决定老用户怎么处理。
Day 10 · 健康度

SRM 检查 · 流量分配真的 50/50 吗?

Sample Ratio Mismatch(样本比例失衡)是很多 A/B 测试默默失败的根因——分流系统出 bug,一组多分了 5% 流量都看不出来。

# SRM 检查 · 卡方检验 from scipy.stats import chisquare observed = [12500, 12600] # 实际访问 expected = [12550, 12550] # 期望 50/50 chi2, p = chisquare(observed, expected) if p < 0.001: print(f"⚠ SRM ALERT · 流量分配可疑(p={p:.4f})") print("不要相信任何后续结论,先查分流系统") else: print(f"✓ SRM check passed · 流量分配正常(p={p:.4f})") # 我们的案例:p = 0.527 → 正常
判断阈值:SRM 检验 p < 0.001 就要警报——比测试本身的 p < 0.05 严格 50 倍。SRM 一失败,所有结论作废
Day 10 · 报告

Codex 生成的决策报告(节选)

# A/B 测试 · Landing Page 改版 · 决策报告 ## 结论:推全量 ✓(保留 return-user 对照) ## 关键数据 - A 版转化:3.10% (387/12,500) - B 版转化:3.53% (445/12,600) - 提升:+13.9% · p=0.031 (显著) · 95% CI [+1.2%, +27.5%] - Power 84.2% · SRM 检查通过 ✓ ## Segment 洞察 | Segment | A | B | Lift | p | 决策 | |---------|---|---|------|---|------| | 新用户 | 2.1% | 3.1% | +47.6% | 0.003 | ✓ 强烈推 | | 老用户 | 4.8% | 4.1% | -14.6% | 0.09 | ⚠ 保留 A | | 移动端 | 2.8% | 3.6% | +28.6% | 0.018 | ✓ 推 | | 桌面端 | 3.5% | 3.4% | -2.9% | 0.71 | ─ 不显著 | ## 风险提示 1. **新奇效应** (novelty effect):新版可能在前 14 天有"新鲜感加成", 建议 1 个月后回看老用户数据是否企稳 2. **老用户反向**:p=0.09 接近阈值,不能 100% 排除偶然, 建议老用户保留 A 版 4 周追踪 3. **季节性**:14 天测试横跨周末/工作日,未横跨月底/月初, 财务相关行为可能未覆盖 ## Rollout Plan - Day 1-3: 新用户 10% 上 B 版 - Day 4-7: 新用户 50% - Day 8: 新用户 100% - Day 9-30: 老用户保留 A 版,监控行为 - Day 30: 决定老用户是否切换
Day 10 · 发布

10% → 50% → 100% · 为什么要滚动?

1
10% 阶段 · Day 1-3 · 真实流量 sanity check(理智检查),监控错误率 / 性能 / 客诉
观察
2
50% 阶段 · Day 4-7 · 扩大覆盖,看复杂场景(支付 / 退款 / 客服)有没有边缘 bug
扩量
3
100% 阶段 · Day 8+ · 全量推送,保留 1% 全程 A 版作为长期对照(holdout)
全量
为什么不直接 100%?
  • A/B 测试样本量有限,不能覆盖所有长尾场景
  • 突发 bug 影响 100% 用户 vs 影响 10% 用户,损失差 10 倍
  • 需要时间观察老用户的延迟反应(重新登录、订阅续费)
为什么保留 1% holdout?
  • 季度后对比长期效果(不是 14 天那种短期波动)
  • 检测 novelty effect(新奇效应消退)
  • 检测"赢家诅咒"——短期赢的版本长期可能输
Day 10 · 避坑

A/B 测试 · 5 个最常见的"自我欺骗"

误区 1 · Peeking(偷看)

测试中途看到 B 赢了就停——p-value 是基于固定样本量的,提前停 = 假阳性

→ 预设样本量,到了再看。

误区 2 · 单一 KPI 决策

只看注册转化,没看后续留存/付费/客单价——B 版可能"骗注册不留存"。

→ 配套 north star 指标。

误区 3 · 没控制变量

同时改 UI + 文案 + 视频,赢了不知道是哪个因素。

→ 一次只测一个变量(MVT 例外)。

误区 4 · 测试周期太短

3 天测出"显著",但只覆盖了 1 个工作日类型——周末 / 月底 / 发薪日都没盖。

→ 至少 1 个完整周期(7 / 14 / 30 天)。

误区 5 · 把"不显著"当"无效"

p = 0.08 不是"B 没用",是"样本量不够下不了结论"。要么继续测,要么用更敏感的指标(次留 / 7 日留存)—— 而不是直接放弃。

Day 10 · 进阶

MVT · 多变量测试 30 秒入门

A/B 测试

2 版对比

  • A vs B
  • 测 1 个变量
  • 样本量需求小
  • 适合单点改动(按钮颜色 / 标题)
MVT · 多变量测试

2^N 版对比

  • 标题 (A/B) × 按钮 (A/B) × 视频 (有/无) = 8 版
  • 测多变量交互效应
  • 样本量需求 ×N 倍
  • 适合整体改版(landing 重做)
MVT 何时用:当你不确定哪个元素重要时用——比如改 landing 同时改了 5 处。不要用 MVT 替代 A/B,样本量需求是 A/B 的 4-8 倍,小团队跑不动。
告诉 Codex: "用 statsmodels 跑 2x2 MVT 分析: 标题(A/B)× 按钮颜色(红/绿)= 4 个组合, 数据见 data/mvt.csv,输出每个组合的 lift + 交互效应"
Day 10 · 实操
现在轮到你

学员练习
用你的真实 A/B 数据跑完整分析

用你最近一次 A/B 测试的数据(或讲师准备的脱敏样本)
喂给 Codex 跑完整分析 → 拿到 Markdown 决策报告 → 当场看 segment 反向有没有

脱敏样本已发群 真实数据更好 60 分钟时长 完成 = 拿到决策报告
Day 10 · 实操

练习步骤 · 跟着做

  1. 准备数据 CSV · 必备字段:user_id, variant (A/B), visit_date, converted (0/1), device, user_type, country
  2. 新建工作目录 · mkdir ~/ab-analysis && cd ~/ab-analysis
  3. 启动 Codex CLI · codex 把 SLIDE 7 的完整 prompt 喂进去
  4. Codex 会问你数据路径 · 把 CSV 放 data/ 下,告诉它路径
  5. 跑脚本 · python src/analyze.py --data data/ab_test.csv --report
  6. 看终端输出 · 4 行关键数字:p-value / CI / SRM / segment
  7. 打开 Markdown 报告 · reports/ab_test_*.md 看完整决策
  8. 关键检验 · segment 里有没有反向 → 这才是 AI 给运营的核心价值
Day 10 · 调试

常见问题 · 5 类

1
p-value = nan · 一组样本量为 0→ 检查 variant 列是否包含 A 和 B,是否大小写一致
2
SRM ALERT 警报 · 流量分配失衡→ 不是脚本 bug,是真实问题。查分流系统/Google Optimize/Vercel Edge Config
3
Segment 出现"unknown"占比 30%+ · 字段缺失→ 让 Codex 跳过 unknown 或单独 segment 处理
4
"Power 不够" 警告 · 样本量不足以下结论→ 不是 bug,是数据不够。要么继续测,要么放弃结论
5
报告里图片不显示 · matplotlib backend 问题→ 让 Codex 加 matplotlib.use('Agg') 切非 GUI backend
调试技巧:报错 + 数据头 5 行原样粘 Codex——这是它能修复的最小信息。
Day 10 · 进阶

进阶 · 直接从 GA4 拉数据

在原脚本基础上加: 1) 用 google-analytics-data Python SDK 拉 GA4 数据 2) 服务账号凭证存 service-account.json 3) 查询参数: - property_id: 自己的 GA4 property - 维度: experiment_id, variant, device_category, user_type, country - 指标: sessions, conversions - 时间: 过去 14 天 4) 拉完直接喂给现有 analyze() 函数 5) cron 每天凌晨 4 点跑一次,更新报告
注意:GA4 有数据延迟(24-48 小时),所以"今天看昨天的数据"才是合理姿势——不要早上 10 点跑期望立刻看到上午的数据。

Mixpanel / Amplitude 同理 —— 都有 Python SDK,Codex 都能调。

Day 10 · 工具对比

GA4 / Mixpanel / Amplitude · 怎么选

GA4

免费 · 通用

  • 免费(10M event/月内)
  • 覆盖率:90%+ 出海网站都有
  • API 稳定但有 24-48h 延迟
  • 事件模型适合 web,移动端弱

→ 90% 团队首选

Mixpanel

$25/mo 起 · 产品分析强

  • funnel / cohort 分析专业
  • 实时数据(< 1 min 延迟)
  • A/B 测试官方有 Experiments 模块
  • 移动端 SDK 优秀

→ SaaS / 移动 APP 推荐

Amplitude

免费 10M event · 数据科学向

  • 自助式 SQL 查询
  • 北美 SaaS 行业标准
  • A/B + Feature Flag 一体
  • 付费版贵($995/mo 起)

→ 数据驱动文化深的团队

选型原则:现有什么用什么。不要为 A/B 测试换工具——Codex 脚本是工具无关的,pandas DataFrame 进去 p-value 出来。
Day 10 · 自动化

让报告每周自动到老板邮箱

1
cron 每周一早 6 点跑 · GitHub Actions schedule '0 6 * * 1'避开工作时间,跑完后老板上班就看到
2
报告输出 PDF · pandoc 把 Markdown 转 PDF老板更喜欢 PDF(手机能开 + 不用 markdown 渲染器)
3
邮件发送 · 用 SendGrid / Resend / Postmark API每周一上午 9 点自动发,附件 PDF + 邮件正文一句话结论
4
Slack 通知 · 关键 Lift > 10% 时 #experiments 频道 @产品事件驱动,重要变化不靠老板自己翻邮件
5
历史归档 · 报告存 Notion / Google Drive3 个月后回看历史决策是否成立,建立"决策日志"
价值:跑通这一套后,你团队的 A/B 测试响应速度从 14 天压到 24 小时——这就是 Codex 的杠杆。
Day 10 · 验收

今日成果 · 5 项验收清单

Codex 跑通了 A/B 测试分析脚本验收:终端能看到 p-value / CI / Power 三个数字
SRM 检查通过验收:终端 "SRM check passed",不是 ALERT
看到 segment 切片结果验收:至少 3 个 segment 维度(device / user_type / country)
Markdown 决策报告生成验收:reports/ 下有 .md 文件,含"结论 · 数据 · segment · 风险 · rollout"5 段
自己能读懂报告做决策验收:能向同桌讲 30 秒"该不该推全量,为什么"
最后 10 分钟:找同桌互讲——讲完代表你真的会用了。
Day 10 · 小结

今天 3 个 takeaway

  1. p-value < 0.05 + Power > 80% + SRM 通过——3 个都达标才能下结论,缺一不可
  2. 总数赢不等于全员赢——必须切 segment 看,辛普森悖论是 A/B 第一杀手
  3. 推全量不是终点——滚动 10% → 50% → 100% + 1% holdout,给自己留后悔的空间
课后作业(明天前完成):把你过去半年的 A/B 测试找一个出来,用今天的脚本重新分析——大概率你会发现当时的决策不对。把"原来的决策 + 现在的决策 + 差异原因"写 3 句话发训练营群。
Day 10 · 结束
明天 · Day 11

用户行为路径分析

从 GA4 / Mixpanel 拉用户事件流
让 Codex 自动揪出流失关键节点 + 生成漏斗优化建议

现在 · Q&A 时间
课后微信群答疑 · 联系讲师 Terrence · 13299138336
讲师备注 · 按 N 切换显示 / 隐藏
翻页 · Space 下一页 · F 全屏 · N 备注 · Home 首页