📈 第2章 实验
📄 一句话概括

随机分组不是「保证均衡」,是「不偏向任何一方」。这两句话差别很大。 两千次随机模拟告诉你:八家店这么小的样本,将近一半的分组会歪到 50 个点以上。 所以分完必须回头查一眼均衡性——这一步省不得。

📝 本章和前面几章的关系

上一篇定下了控制组。这一篇解决「谁来当控制组」这个分配问题。 随机化是全书唯一一个能把「你想不到的因素」也平均掉的办法,第 6 章的贝叶斯、 第 11 章的分割都绕不开它。

一、观察数据的分组有多歪

观察期里,降价组社区店占 75%,未降组占 25%——差 50 个百分点。 这个差是系统性的:社区店生意差,所以更想降价。它不会自己消失。 随机分组要解决的,就是让这个差变成「平均为零、方向不定」。

二、随机化在做什么

把八家店的名字洗牌,前四家进实验组、后四家进控制组。 每一家店进哪一组,与它的店址、业绩、店长全无关——这就是随机。 结果是:两组在「平均意义上」一样,个别一次可能不一样。

三、两千次模拟的结果

跑两千次,两组社区店占比之差的平均值是 −0.0037,基本为零。 但差到 50 个点以上的有 955 次,占 47.8%——将近一半。 原因很简单:只有八家店、四家社区店,随便分一半很容易分到 3 比 1。

四、所以要做均衡性检查

分完组,先看两组在已知变量上像不像:店址、规模、客流、店长资历。 不像就重分。重分的成本只是一次洗牌,比做完实验发现分组歪了便宜太多。 这一步在实验报告里通常只有一行字:「两组基线无显著差异」,但它背后是一次检查。

五、随机化管不到的地方

随机化能平均掉「你记录下来的变量」,也能平均掉「你没记录但随机分布的变量」。 它平均不掉的是「和分组强相关的隐藏变量」——但随机分组本身就切断了这个相关。 这就是为什么随机对照试验被当成因果推断的标准:它把「分组」这件事从人手里拿走了。

六、动手 Demo:随机分组:把混杂因素平均掉

两千次洗牌,统计两组社区店占比之差。 看两个数:平均值几乎为零(无偏),但差到 50 点以上的占了将近一半(小样本)。

import random
site = ['community', 'community', 'community', 'downtown',
        'downtown', 'downtown', 'downtown', 'community']
rnd = random.Random(60)

diffs = []
for _ in range(2000):
    idx = list(range(8))
    rnd.shuffle(idx)
    g1, g2 = idx[:4], idx[4:]
    p1 = len([i for i in g1 if site[i] == 'community']) / 4.0
    p2 = len([i for i in g2 if site[i] == 'community']) / 4.0
    diffs.append(p1 - p2)

mean = sum(diffs) / len(diffs)
zero = len([d for d in diffs if abs(d) < 1e-9])
big = len([d for d in diffs if abs(d) >= 0.5 - 1e-9])
print('平均差 %.4f' % mean)
print('完全均衡 %d 次 (%.1f%%)' % (zero, zero * 100.0 / len(diffs)))
print('差 50 点以上 %d 次 (%.1f%%)' % (big, big * 100.0 / len(diffs)))

实跑输出:

--------------------------------------------------------------------
随机分组:把混杂因素平均掉
--------------------------------------------------------------------

  ① 观察数据的分组有多歪
  --------------------------------------------------------------------
  观察期里,降价组社区店占 75%,未降组社区店占 25%。
  两组在店址上差了 50 个百分点,这个差把降价的效果盖得干干净净。

  ② 随机分组会差多少
  --------------------------------------------------------------------
  两千次随机分组,两组社区店占比之差的平均值 -0.0037
  其中 1045 次两组完全均衡(52.2%);差到 50 个点以上的 955 次(47.8%)
  后一个数看着吓人,其实很正常:只有八家店,随机分一半很容易分到 3 比 1。
  样本越小,随机化越靠不住——这就是均衡性检查不能省的原因。
  最极端的一次差 1.00,也就是 100 个百分点

| 分组方式 | 社区店占比差 | 后果 |
|---|---|---|
| 观察数据 | 75% − 25% = 50 个点 | 系统性失衡,结论被盖住 |
| 随机分组 | 平均 0,约一半完全均衡 | 长期无偏,小样本仍可能歪 |


  ③ 随机化不是保证,是概率
  --------------------------------------------------------------------
  随机分组也可能一次就分歪——上面那 47.8% 就是这么来的。
  区别在于:随机分组的「歪」是随机的,重复很多次会互相抵消;
  观察数据的「歪」是系统性的,重复多少次都是同一个方向。
  ! 随机化换来的不是「一定均衡」,是「不偏向任何一方」。

  ④ 分完还要检查
  --------------------------------------------------------------------
  分完组要回头看一眼:两组的店址、规模、客流是不是差不多。
  不差不多就重新分——反正分组的成本只是一次洗牌。
  这一步叫「均衡性检查」,是实验报告里必备的一行。

平均值 −0.0037,几乎是零;但 47.8% 的分组歪了 50 个点以上。 这两个数一起看才完整:无偏说的是长期,47.8% 说的是这一次。所以分完还要查。

30 秒实验

  1. 把店数从 8 改成 80(社区 40 家),重跑,差 50 点以上的比例变成多少?
  2. 把随机种子从 60 换成别的,平均值会变吗?结论会变吗?
  3. 想一想:如果不用随机,改用「按店址配对后各取一半」,会不会更好?

常见误区

  1. 以为随机就一定均衡:小样本下随机也会歪,所以要做均衡性检查。
  2. 用「轮流分配」代替随机:轮流会把周期性因素(比如按开业顺序)带进分组。
  3. 按方便分组:谁近谁进实验组,等于把店址又请回来了。
  4. 分完不看基线:报告里没有均衡性一行,读者没法判断这次分组歪没歪。
自测三问(点开对答案) 1. 随机分组保证均衡吗? —— 不保证。它保证的是「不偏向任何一方」,长期平均为零,单次仍可能歪。 2. 为什么八家店时将近一半的分组会差 50 个点以上? —— 因为只有四家社区店,从八家里随机抽四家,抽到 3:1 甚至 4:0 的概率很高。 3. 均衡性检查查什么? —— 查两组在已知变量(店址、规模、客流等)上的分布像不像,不像就重分。

分组随机了,实验做完了,两个均值差 8 个点。最后一个问题:这 8 个点会不会只是运气?

相关笔记