# 数据分析 · 第 05 篇|统计推断与 AB 实验 > 系列:project / 数据分析(共 12 篇)|AI生成|2026-10-27|codebuddy **这一篇讲什么** 第 04 篇反复强调「相关不等于因果」,却只给了否定的边界,没给肯定的方法。这一篇补上正面解法:用随机分流人为制造两组可比的样本,再用统计推断判断差异是真实的还是抽样的偶然。内容按「先懂推断,再做实验」推进:先讲样本与总体、抽样误差、置信区间,解释为什么 10% 的样本结果不能直接当总体;再讲假设检验、p 值、两类错误与统计功效;然后算样本量、设计实验、识别样本比例失衡与多重比较;用一个新客券的完整案例走完「显著 → 效应量 → 经济性 → 上线决策」;最后列七个常见坑,以及无法做实验时的准实验替代方案。读完应该能自己设计一个能得出结论的实验,也能看穿一个结论站不住的实验。 ## 一、从样本到总体:10% 不等于 10% 北辰优选想评估新版注册页,抽样 1,000 名新用户,其中 100 人完成首单,转化率 10%。这个 10% 能不能直接当成「新版注册页的转化率」写进汇报? 不能。它只是一个**估计值**,换一批 1,000 人,可能是 9.2%,也可能是 10.9%。这种由抽样带来的波动叫抽样误差。对比例指标,标准误的公式是: SE = √( p(1-p) / n ) 代入 p = 0.10、n = 1,000,SE = √(0.09/1000) ≈ 0.95 个百分点。95% 置信区间约为 p ± 1.96×SE,即 [8.1%, 11.9%]。意思是:如果把这套抽样重复很多次,大约 95% 的区间会覆盖真实转化率。注意措辞——**不是「真实值有 95% 的概率落在 8.1% 到 11.9% 之间」**,真实值是固定的,随机的是区间。 样本量对精度的影响是平方根关系:样本翻四倍,误差才减半。 | 样本量 n | 观测转化率 | 标准误 | 95% 置信区间 | 区间宽度 | | --- | --- | --- | --- | --- | | 500 | 10.0% | 1.34pp | [7.4%, 12.6%] | 5.3pp | | 1,000 | 10.0% | 0.95pp | [8.1%, 11.9%] | 3.8pp | | 5,000 | 10.0% | 0.42pp | [9.17%, 10.83%] | 1.7pp | | 20,000 | 10.0% | 0.21pp | [9.58%, 10.42%] | 0.8pp | 这张表解释了两个常见困惑。第一,为什么小样本的「暴涨 50%」多半是噪音——n=500 时区间宽达 5.3 个百分点,8% 和 10% 在统计上根本分不开。第二,为什么大样本的「显著提升」可能毫无意义——n=200,000 时,10.0% 对 10.1% 也能显著,但业务上没人会在意 0.1 个百分点。**显著性回答「是不是真的」,效应量回答「值不值得」**,两个问题不能混。 ## 二、假设检验:p 值到底在回答什么 要判断两组差异是否真实,标准做法是假设检验。设 A 组(旧版)转化率 p_A,B 组(新版)p_B: - 原假设 H₀:p_B - p_A = 0,即新版没区别。 - 备择假设 H₁:p_B - p_A ≠ 0,即新版有区别(双侧)。 然后计算:**假如 H₀ 为真,观察到当前这么大或更大的差异,概率是多少**。这个概率就是 p 值。p = 0.03 的含义是「如果新版真的没用,出现这种差距的可能性只有 3%」,而不是「新版没用的概率是 3%」,也不是「结论有 3% 的概率是错的」。这两种误读在业务汇报里出现频率极高。 显著性水平 α 是我们事前定的容忍度,通常取 0.05。它对应两类错误: | | 真实情况:无差异 | 真实情况:有差异 | | --- | --- | --- | | 判定为有差异 | 第一类错误(假阳性),概率 α | 正确,概率 = 统计功效 1-β | | 判定为无差异 | 正确 | 第二类错误(假阴性),概率 β | α 和 β 是一对跷跷板:把 α 从 0.05 收紧到 0.01,假阳性少了,但同样的样本量下假阴性会变多。所以不能只盯着「别误报」,还要看功效——**当真有效时,实验有多大把握能检测出来**。行业惯例是功效不低于 80%,也就是 β ≤ 0.20。 功效取决于三件事:效应量越大越容易检测、样本量越大越容易检测、指标波动越小越容易检测。这解释了为什么「提升 0.1 个百分点」的实验往往做不出结论——不是方法错,是效应太小,需要的数据量不现实。 ## 三、样本量:想检测 0.8 个百分点,需要多少人 样本量必须在实验开始前算,不能做完再补。一个够用的近似公式(双侧 α=0.05、功效 80%): n = 16 × p(1-p) / δ² 其中 p 是基线转化率,δ 是要检测的绝对提升,n 是**每组**所需人数。这个 16 来自 2×(1.96+0.84)² ≈ 15.7,是常用的经验系数。 北辰优选基线 10%,想检测 0.8 个百分点的绝对提升: n = 16 × 0.10 × 0.90 / 0.008² = 1.44 / 0.000064 = 22,500 每组约 2.25 万人,两组 4.5 万人。几个规律值得记住: | 基线转化率 p | 要检测的绝对提升 δ | 每组所需样本 | 说明 | | --- | --- | --- | --- | | 10% | 2.0pp | 3,600 | 大改动,容易测 | | 10% | 1.0pp | 14,400 | 中等改动 | | 10% | 0.8pp | 22,500 | 本案例的量级 | | 10% | 0.5pp | 57,600 | 小优化,成本很高 | | 5% | 0.5pp | 30,400 | 低基线更难测 | | 20% | 2.0pp | 6,400 | 高基线相对好测 | 两个容易被忽略的点。第一,δ 要用**绝对提升**,不是相对提升;「提升 8%」听上去是 8 个百分点,实际是 0.8 个百分点,样本量差 100 倍。第二,算完样本量还要算时长:北辰优选每天新增访问 8,000 人,按 50/50 分流,每天每组 4,000 人,22,500 人需要约 5.6 天。但实验至少要跑满 7 天,因为工作日和周末的行为不同,跑 5 天会把周末的结构性差异算进结果里。 ## 四、AB 实验设计:随机、单位、指标、时长 一个能得出结论的实验,要在开始前把六件事定死。 | 设计要素 | 北辰优选新客券案例 | 常见错误 | | --- | --- | --- | | 实验单位 | 用户(user_id) | 用会话或订单做单位,同一人被反复分到不同组 | | 分流方式 | 按 user_id 哈希取模,A/B 各 50% | 按注册时间先后分组,混入时间趋势 | | 核心指标 | 新客 7 日支付转化率 | 同时把 8 个指标都当核心指标 | | 护栏指标 | 客单价、退款率、客服投诉率、毛利率 | 只看转化率,忽略成本与体验 | | 实验时长 | 14 天(覆盖两个完整周) | 看到显著就停,或只跑 3 天 | | 分析口径 | 意向治疗(ITT),按分流时点分组 | 剔除「没领券」的用户,破坏随机性 | **实验单位**的选择决定了随机化的粒度。用用户做单位最稳,因为同一个人不会同时看到两个版本。用会话做单位会引入污染:同一个用户可能在 A 组看到旧版、在 B 组看到新版,两组差异被稀释。用门店、城市做单位时,单位数往往只有几十个,随机化的平衡性变差,需要按规模分层后再分流。 比「完全随机」更稳的做法是**分层随机化**:先按新老客、城市等级、历史购买力把用户分成若干层,再在每一层内部按 50/50 分流。这样即使总体样本有偏,两组的结构也会基本一致,能显著降低方差。北辰优选的券实验就按「新客/老客 × 一线/非一线」分了四层,每层独立分流,事后核对各层占比差异都在 0.3 个百分点以内,说明随机化是干净的。 **核心指标只能有一个**(最多加一个辅助指标)。指标一多,就会不自觉地挑那个显著的去汇报,这就是多重比较问题。看 5 个指标,每个都用 α=0.05,至少出现一个假阳性的概率是 1-0.95⁵ ≈ 22.6%——也就是说,**一个完全无效的改动,有五分之一以上的概率会被你「发现有效」**。处理办法有三种:事前只认一个核心指标;对多指标做 Bonferroni 校正(α 除以指标数);或者用 FDR 控制。最简单也最有效的是第一种。 **分流是否真的随机**要用 SRM(Sample Ratio Mismatch)检验。假设计划 50/50、共 40,000 人,实际 A 组 19,600、B 组 20,400。卡方统计量是 (400²/20,000)×2 = 16,自由度 1,p 远小于 0.001。这说明分流有问题——常见原因是指标上报丢失、跳转链路某一侧失败、爬虫或机器人被分到某一组。SRM 一旦出现,**先查数据管道,不要解释业务结果**,因为此时两组的可比性已经破了。 ```sql -- 示意:实验分流比例校验(假设有一张分流记录表) SELECT group_name, COUNT(*) AS users, COUNT(*) * 1.0 / SUM(COUNT(*)) OVER () AS share FROM exp_assignment WHERE exp_id = 'E2026_09_COUPON' GROUP BY group_name; -- 同时校验:两组的新老结构、城市分布是否可比 SELECT group_name, AVG(CASE WHEN u.signup_date >= DATE '2026-08-01' THEN 1.0 ELSE 0.0 END) AS new_user_share, AVG(CASE WHEN city = '上海' THEN 1.0 ELSE 0.0 END) AS shanghai_share FROM exp_assignment a JOIN users u ON u.user_id = a.user_id WHERE a.exp_id = 'E2026_09_COUPON' GROUP BY group_name; ``` 第二段查询的思路值得记住:**随机化只保证期望上可比,不保证实际样本每一维都平衡**。所以要抽查几个关键维度(新老客占比、城市分布、历史客单价),如果差异超过抽样误差能解释的范围,就要在分析时做协变量调整,或者直接重跑。 ## 五、北辰优选案例:10.0% 对 10.8%,上不上线 实验跑完:A 组(无券)20,000 人,2,000 人支付,转化率 10.0%;B 组(满 99 减 10)20,000 人,2,160 人支付,转化率 10.8%。差 0.8 个百分点,相对提升 8%。 先做统计判断。合并比例 p̄ = 4,160/40,000 = 10.4%,合并标准误约 0.305 个百分点,z ≈ 2.62,双侧 p ≈ 0.009。用未合并标准误算差值区间:SE ≈ 0.308 个百分点,95% 置信区间为 0.8 ± 1.96×0.308,即 [0.20pp, 1.40pp]。区间不含 0,结论是「正向且显著」。 ```python import math from scipy import stats n1 = n2 = 20_000 x1, x2 = 2_000, 2_160 p1, p2 = x1 / n1, x2 / n2 #1) 两比例 z 检验(合并标准误) p_pool = (x1 + x2) / (n1 + n2) se_pool = math.sqrt(p_pool * (1 - p_pool) * (1 / n1 + 1 / n2)) z = (p2 - p1) / se_pool p_value = 2 * (1 - stats.norm.cdf(abs(z))) #2) 差值置信区间(未合并标准误,更常用于报告) se_diff = math.sqrt(p1 * (1 - p1) / n1 + p2 * (1 - p2) / n2) lo, hi = (p2 - p1) - 1.96 * se_diff, (p2 - p1) + 1.96 * se_diff #3) 事后功效:这个样本量能有多大概率测出 0.8pp power = stats.norm.cdf((p2 - p1) / se_diff - 1.96) print(f"z={z:.2f}, p={p_value:.4f}") print(f"diff={p2-p1:.4f}, 95% CI=[{lo:.4f}, {hi:.4f}]") print(f"power={power:.2%}") ``` 跑出来的三个数:z ≈ 2.62、p ≈ 0.009、区间 [0.20pp, 1.40pp]、功效约 74%。这里有个必须诚实说明的点:**功效略低于 80% 的惯例线**。第三节算过,这个效应量需要每组 22,500 人,实际只有 20,000 人。换句话说,这次显著有一点「刚好撞线」的成分——如果真实效应就是 0.8pp,重复做同样的实验,大约四次里有一次测不出来。所以结论应该写成「倾向于正向,效应量估计偏不稳」,而不是「确定提升 0.8pp」。 然后是更关键的一步:统计显著,是否等于应该上线?算经济账。 | 项目 | 数值 | 说明 | | --- | --- | --- | | 每组人数 | 20,000 | 实验样本 | | B 组增量转化人数 | 160 | 0.8pp × 20,000 | | 增量 GMV | 19,200 元 | 160 单 × 客单价 120 元 | | 增量毛利 | 6,720 元 | 毛利率 35%,每单毛利 42 元 | | 券核销成本 | 21,600 元 | 2,160 单核销 × 面额 10 元 | | 净收益 | -14,880 元 | 增量毛利减券成本 | | 每个增量用户成本 | 135 元 | 21,600 ÷ 160 | 结论反转:**统计上显著,经济上亏损**。原因是券的成本按「全部核销」支付(2,160 单),而增量只有 160 单——九成以上的用券用户本来就会买。每个增量新客花掉 135 元,而他能带来 42 元毛利,怎么算都不划算。 这就是为什么实验报告不能只写 p 值。正确的决策链是四步:**显著吗 → 效应多大 → 划算吗 → 有风险吗**。这个案例在第三步就该停:不上线全员发券。可行的替代方案是缩小发放范围(只对加购未支付用户发),把 2,160 单的核销成本压到几百单,或者把面额降到 5 元再测一轮。如果考虑长期价值,假设新客 90 天复购率 25%、二次订单毛利 60 元,增量用户带来的长期毛利约 160×0.25×60 = 2,400 元,仍然填不上 2 万的坑——**结论对假设是稳健的**,这一点也要写进报告。 ## 六、七个常见的坑 | 坑 | 表现 | 后果 | 处理 | | --- | --- | --- | --- | | Peeking | 每天看结果,显著就停 | 假阳性率从 5% 升到 20% 左右(示意) | 事前定样本量与结束时间,中途只看护栏 | | 分流不随机 | 按时间、按 ID 段分组 | 组间不可比,结论无效 | 哈希分流 + SRM 检验 | | 新奇效应 | 老用户对新版好奇,短期指标虚高 | 上线后效果回落 | 跑满 2—4 周,看趋势是否衰减 | | 季节性 | 实验期正好跨大促或节假日 | 结果不可外推 | 避开特殊周期,或两组同期对比 | | 网络效应 | 用户之间会互相影响(拼团、社交) | 对照组被污染,效应被低估 | 按社群/城市整群分流 | | 指标污染 | 对照组用户看到了实验组的活动 | 差异被稀释 | 检查曝光日志,做互斥设计 | | 只报显著不报效应量 | 「显著提升」但没有绝对值 | 小到无意义的提升被放大 | 必报绝对效应 + 置信区间 | **Peeking** 值得单独说。它的诱惑在于「数据看着看着就显著了」,但每次查看都是一次检验,重复检验会累积假阳性。正确的做法是事前承诺样本量和结束日期,中途只看护栏指标(退款率、投诉率、崩溃率)决定是否紧急停止,不看核心指标的方向。如果业务上必须连续监控,就用序贯检验方法,它专门为「允许中途看」设计,代价是需要更大的效应量才能显著。 **新奇效应**在产品改版里特别常见。上线第一周,老用户因为界面变了会多点几下,指标虚高;第二周习惯之后回落。判断方法是看分组差异随时间的变化曲线:如果差异在第二周明显收窄,就要警惕。反过来,如果差异持续扩大,说明可能是真的改善,也可能是长期用户逐步发现新功能。 ## 七、不能做实验的时候:准实验方法 有些事没法随机:改价格、改会员体系、上线下广告、政策变化。这时只能退而求其次,用观察数据构造可比性。四种方法够用。 | 方法 | 基本思路 | 关键假设 | 常见失败 | | --- | --- | --- | --- | | 双重差分(DID) | 比较「受影响的组」与「未受影响的组」在前后两期的变化之差 | 平行趋势:无干预时两组趋势一致 | 两组本来就在分化,趋势不平行 | | 倾向得分匹配(PSM) | 为每个处理组用户找特征相近的对照用户 | 可观测特征足以解释选择 | 有未观测的混淆变量 | | 断点回归(RDD) | 利用某个阈值两侧的突变(如满 199 免运费) | 阈值附近的人除处理外无系统差异 | 有人在阈值附近操纵行为 | | 合成控制 | 用多个未受影响地区的加权组合,模拟处理地区 | 加权组合能复现处理地区的前期走势 | 找不到合适的组合 | DID 最容易上手,也最容易被误用。北辰优选在某个城市先上线了次日达,想评估它对复购的影响。做法是取该城市与三个可比城市,比较上线前后两个月的复购率变化,再把对照城市的变化减掉——减掉的正是「季节性、大盘趋势」这些共同冲击。它的命门是平行趋势:如果该城市本来复购率就在上升,减出来的效果就被高估。检验办法是画干预前 8 周的两条曲线,看是否平行;也可以做「安慰剂检验」,假装干预提前四周发生,如果也能测出「效果」,说明模型有问题。 匹配方法要特别注意「共同支撑」问题:如果处理组全是高价值用户,找不到特征相近的对照,硬匹配出来的结果只是在小样本上编故事。实操中要检查匹配前后的标准化差异,通常要求各协变量差异降到 10% 以内,否则说明匹配没成功,结论不可信。 这些方法给的证据强度都弱于随机实验,写报告时要明确标注「准实验,依赖平行趋势假设」,而不是和 AB 实验混为一谈。证据强度大致可以排序:随机实验 > 断点回归 ≈ 合成控制 > DID > 匹配 > 简单前后对比。 ## 八、把统计语言翻译成业务语言 统计结论不能直接扔给业务方。「p=0.009,差值 0.8pp,95% CI [0.2pp, 1.4pp],功效 74%」这句话,运营听不懂,老板也不想听。翻译成三层: 第一层,**结论**:「新客券能把支付转化率从 10.0% 提到 10.8%,这个提升大概率是真的,不是波动。」 第二层,**不确定性**:「真实提升大概在 0.2 到 1.4 个百分点之间,最可能是 0.8。这次样本略少,重复做有约四分之一的概率测不出来。」 第三层,**决策**:「但券的成本按全部核销算,每个增量新客要花 135 元,只带来 42 元毛利,所以不建议全员发。建议只对加购未支付的用户发,再测两周。」 这三层对应三种听众:结论给决策者,不确定性给会质疑的人,决策给执行的人。**跳过第二层是最危险的**——只报「提升 0.8pp」而不说区间,等于把估计值伪装成确定值,一旦复现不了,整个分析团队的可信度都会受损。 最后一条纪律:实验的结论只对**实验覆盖的人群和时段**成立。北辰优选的券实验只覆盖新客、只跑了 14 天,结论不能外推到老客,也不能假设半年后还成立。写清楚边界,比写漂亮结论更重要。 ## 本篇要点回顾 1. 样本估计值天然带误差:1,000 人测出 10%,95% 区间是 [8.1%, 11.9%],说成「转化率 10%」就已经过度自信了。 2. p 值是「H₀ 为真时观察到当前差异的概率」,不是「H₀ 为真的概率」;α=0.05 意味着每 20 次无效改动会有 1 次被误判为有效。 3. 样本量要用绝对提升算:基线 10%、检测 0.8pp 需要每组约 22,500 人,而相对提升「8%」和绝对提升 0.8pp 相差 100 倍。 4. 显著不等于上线:新客券把转化率从 10.0% 提到 10.8%(p≈0.009),但每个增量用户成本 135 元、毛利仅 42 元,净亏 1.49 万元。 5. 一次实验只回答一个有限问题,结论要标注人群、时段和证据强度;随机实验强于 DID,DID 强于简单前后对比。 ## 延伸阅读 - **第 04 篇|诊断性分析与归因**:那篇讲清楚了为什么观察数据里的「相关」不能当因果,本篇的随机分流正是对那个问题的正面回答,两篇连起来读才完整。 - **第 06 篇|预测分析与建模入门**:实验解决「这个改动有没有用」,预测解决「这个人会不会流失」,前者靠随机化,后者靠特征与模型,两者共享「训练/验证」的思路但目的不同。 - **第 03 篇|描述性分析与指标体系**:实验的核心指标必须先有稳定口径,转化率的分母是 UV 还是 PV、7 日还是 30 日,都在那篇定义。 - **第 07 篇|分析方法全景与选择**:本篇的假设检验与实验设计属于「验证」类方法,那篇给出四类方法的整体地图和选择路径。 - **第 11 篇|分析报告与沟通**:怎么把 p 值和置信区间讲成业务能决策的三层话术,那篇有更完整的模板与案例。