中心极限定理:为什么随机世界总会产生钟形曲线
钟形曲线无处不在
量一千个人的身高,画成分布图,你会看到一条中间高、两边低的对称曲线,形状像一口倒扣的钟。这就是正态分布,日常叫它钟形曲线。
换成考试成绩、降雨量、新生儿体重,结果都一样:只要你收集的数据足够多,形状总是一口钟。
这是为什么?世间万事万物如此不同,凭什么都服从同一个形状?
答案是一个叫 *中心极限定理*(Central Limit Theorem,简称 CLT)的数学结论。它说的是:不管原始数据是什么分布,只要把足够多次独立观测的结果拿来取平均,平均值就会服从正态分布。这个结论看起来很不可思议,但它是整个现代统计学的基础。
赌徒的发现
这个发现要从赌博说起。
18 世纪初的伦敦,数学家 Abraham de Moivre 靠给赌徒当顾问谋生。他的才华得到过牛顿和哈雷的认可,但作为法国新教难民,他在英国拿不到正式的教职,只能用数学本事换饭吃。
de Moivre 研究了抛硬币的问题。抛 100 次硬币,正面朝上的次数大概是 50 次左右,但不会精确地等于 50。重复玩很多遍,每次的结果都不一样。然而,当你把所有结果画成频率图时,一个清晰的形状浮现出来:中间最高(50 次附近),两边对称下降。这就是正态分布。
de Moivre 算出了这条钟形曲线的精确形状,写进了 1738 年出版的《机会论》(The Doctrine of Chances)一书。但他没有意识到自己的发现有多大的通用性。几十年后,法国数学家 Laplace 在 1810 年把它推广为一个通用定理:不管随机过程本身是什么规律,只要取足够多次的均值,结果就服从正态分布。这就是后来的中心极限定理。
CLT 到底说了什么
中心极限定理可以用一句话概括:
取很多个互相独立的随机数的平均值,这个平均值服从正态分布。
关键条件是互相独立。每次抛硬币的结果不会影响下一次,每次掷骰子也不会受到上一次的影响。只有当观测之间互不干扰时,CLT 才成立。
这个定理最厉害的地方在于,它不关心原始数据是什么分布。抛硬币、掷骰子、测身高,原始规律完全不同,但取均值后都会变成同一种形状。
我们用代码来看看这个过程。
抛 100 枚硬币,数正面朝上有几枚。重复 10000 次,把结果画成频率分布:
import random from collections import Counter random.seed(42) # 抛 100 枚硬币,数正面朝上的数量,重复 10000 次 results = [] for _ in range(10000): heads = sum(1 for _ in range(100) if random.random() < 0.5) results.append(heads) # 按 5 个一组统计频次 buckets = Counter() for h in results: buckets[h // 5 * 5] += 1 # 画 ASCII 直方图 max_freq = max(buckets.values()) for bucket in range(30, 70, 5): freq = buckets.get(bucket, 0) bar_len = int(freq / max_freq * 50) print(f"{bucket:3d}-{bucket+4:3d}: {'█' * bar_len} ({freq})")
30- 34: (12) 35- 39: ██ (175) 40- 44: ████████████████ (1180) 45- 49: ██████████████████████████████████████████████ (3273) 50- 54: ██████████████████████████████████████████████████ (3523) 55- 59: █████████████████████ (1545) 60- 64: ███ (270) 65- 69: (22)
每次抛 100 枚硬币,正面朝上的次数总是聚集在 50 附近。离 50 越远,出现的频率越低。这就是钟形曲线。
均匀分布也能变钟形
你可能会想,硬币只有正反两面,正面 50%、反面 50%,这个分布太简单了,产生钟形曲线不奇怪。
那我们换一个完全不同的分布:掷骰子。
骰子有 6 个面,每个面朝上的概率相等(都是 1/6)。如果你掷 10000 次骰子,记录每个面的出现次数,频率图是完全平坦的,没有钟形。
import random from collections import Counter random.seed(42) # 单骰子:掷 10000 次 single = Counter(random.randint(1, 6) for _ in range(10000)) for face in range(1, 7): bar = '█' * (single[face] // 30) print(f" {face}: {bar} ({single[face]})")
1: █████████████████████████████████████████████████████ (1618) 2: ██████████████████████████████████████████████████████ (1629) 3: ██████████████████████████████████████████████████████ (1647) 4: ████████████████████████████████████████████████████████ (1687) 5: ███████████████████████████████████████████████████████ (1671) 6: ██████████████████████████████████████████████████████████ (1748)
六个面出现的频率几乎一样高,看不出任何钟形的影子。
现在改变做法:每次掷 10 个骰子,取它们的平均值。重复 10000 次,看平均值的分布:
import random from collections import Counter random.seed(42) # 十骰子取平均:重复 10000 次 avg_counts = Counter() for _ in range(10000): total = sum(random.randint(1, 6) for _ in range(10)) avg = round(total / 10, 1) bucket = round(avg * 2) / 2 # 四舍五入到最近的 0.5(如 3.3→3.5, 3.8→4.0) avg_counts[bucket] += 1 max_freq = max(avg_counts.values()) for bucket in sorted(avg_counts): freq = avg_counts[bucket] bar_len = int(freq / max_freq * 40) print(f" {bucket:.1f}: {'█' * bar_len} ({freq})")
1.5: (1) 2.0: (81) 2.5: ████████ (728) 3.0: ██████████████████████████ (2392) 3.5: ████████████████████████████████████████ (3556) 4.0: ██████████████████████████ (2382) 4.5: ████████ (766) 5.0: █ (90) 5.5: (4)
钟形出来了。原始分布是完全平坦的,但只要取 10 个数的均值,重复足够多次,均值就变成了钟形分布。
这就是中心极限定理的魔力。不管你从什么分布里抽样,只要样本够多、取均值,结果就趋近正态分布。骰子的原始分布没有任何钟形的痕迹,但取均值后钟形自动出现了。
为什么它自动出现
理解了 CLT 的机制,就能解释为什么自然界中到处都是钟形曲线了。
以身高为例。一个人的身高受很多因素影响:父亲的身高、母亲的身高、基因组合、孕期营养、童年营养、运动量、睡眠质量,等等。这些因素互相之间基本独立(你爸的身高不会影响你小时候吃什么),每个因素的贡献都很小。
当很多个微小的、互相独立的因素叠加在一起时,效果就相当于取均值。根据中心极限定理,这个均值服从正态分布。所以人的身高自动呈现钟形曲线,不需要任何外力来塑造它。
考试成绩也是类似的道理。一套设计合理的试卷,分数由大量互不相关的因素决定:这道题你会不会、那道题有没有粗心、这道题时间够不够。因素足够多、足够独立,总分就服从正态分布。
这就是为什么钟形曲线不需要被设计,它会自己长出来。只要一个量背后隐藏着很多个独立因素叠加的过程,这个量就几乎必然呈现正态分布。
判断真伪的力量
CLT 不只是解释了自然界为什么有这么多钟形曲线,它还给了科学家一个强大的工具:判断异常。
回到 de Moivre 时代的咖啡馆。有人递给你一枚硬币,跟你打赌。你抛 100 次,正面朝上不到 45 次就算他赢。你抛了,结果只有 20 次正面。这枚硬币公平吗?
多亏了中心极限定理,你知道正面次数服从正态分布,均值 50。100 次抛硬币(二项分布)的标准差可以用公式 √(n×p×(1−p)) 算出来,n=100、p=0.5,所以标准差 = √25 = 5。20 次正面距离均值有 (50−20)/5 = 6 个标准差之远。在正态分布中,偏离均值 6 个标准差以上的概率几乎为零(大约十亿分之一)。
你可以非常自信地说:这枚硬币被动过手脚。
正态分布有一个实用的性质,叫 68/95 法则:
- 大约 68% 的数据落在均值上下 1 个标准差范围内
- 大约 95% 的数据落在均值上下 2 个标准差范围内
我们用代码验证一下。抛 100 枚硬币(标准差是 5),看正面次数有多少落在 50±5 和 50±10 的区间内:
import random random.seed(42) # 抛 100 枚硬币,数正面,重复 10000 次 results = [] for _ in range(10000): heads = sum(1 for _ in range(100) if random.random() < 0.5) results.append(heads) # 统计各区间占比 within_5 = sum(1 for h in results if 45 <= h <= 55) within_10 = sum(1 for h in results if 40 <= h <= 60) total = len(results) print(f"正面 45-55 次(离均值偏差不超过 5): {within_5/total*100:.1f}%") print(f"正面 40-60 次(离均值偏差不超过 10): {within_10/total*100:.1f}%") print() print("正态分布理论值:±1σ 约 68%,±2σ 约 95%") print("(模拟值略高,因为整数区间比连续分布的±1σ稍宽)")
正面 45-55 次(离均值偏差不超过 5): 72.7% 正面 40-60 次(离均值偏差不超过 10): 96.3% 正态分布理论值:±1σ 约 68%,±2σ 约 95% (模拟值略高,因为整数区间比连续分布的±1σ稍宽)
模拟值(72.7% 和 96.3%)比理论值(68% 和 95%)略高。原因是硬币正面次数是整数。代码中 45 ≤ h ≤ 55 包含了 45 和 55 两个端点,共 11 个整数。在连续分布中,整数 45 实际占据 44.5 到 45.5 的范围,55 占据 54.5 到 55.5。所以 11 个整数实际覆盖的连续范围是 44.5 到 55.5,宽度是 11,比 1 个标准差的宽度(10)多了一点。但趋势完全一致。绝大多数结果集中在均值附近,偏离越远越罕见。
这个原理是统计推断的基石。科学家做实验、分析师做 A/B 测试、质检员抽检产品,判断结果是否正常的逻辑都建立在 CLT 之上。你知道均值和标准差,就能算出某个结果出现的概率,概率太低就说明有问题。
CLT 的局限性
CLT 虽然强大,但不是万能的。它有三个前提:
- 样本要互相独立。 如果你在一个缅因州的小镇上做全国民调,不管重复多少次,结果都不会变成正态分布,因为样本本身有系统性偏差。
- 样本量要够大。 CLT 说的是足够多次取均值的极限行为。实际中,样本量太小时(通常少于 30),正态近似的效果会很差。
- 极端事件比平均值更重要。 "百年一遇"的洪水最近频繁发生,这时候关注平均水位没有意义,你需要研究的是分布的尾部。极端事件的建模用的是另一套工具(极值理论),不是 CLT。
尽管有这些限制,CLT 仍然是经验科学的支柱。几乎每次科学家用测量数据推断世界规律时,CLT 都隐藏在方法背后。没有它,科学很难对任何事情给出有信心的结论。