读完这篇,你能做什么
能计算总体与样本方差,运行固定种子的蒙特卡洛估计,并实现常数额外空间的在线统计。
学习理由、准备要求与知识点
为什么学它
两次训练的平均损失或奖励相同,波动也可能很不同。一起看平均与波动,才更容易判断结果。
先读这些内容
知识点清单
- 随机变量与取值分布
- 离散期望
- 总体方差
- 样本方差与n-1
- 均值标准误
- 蒙特卡洛估计
- 独立样本假设
- Welford在线更新
运行前先确认Java 17;Python 3.14 CPU 教学实验,无外部数据、预训练权重、GPU 或多机训练。源代码基线与局限见源码模块。
01先弄懂它是什么
一次随机结果不一定能代表整体表现,所以我们常想知道平均会怎样。随机变量就是用一个数记录随机结果,例如 X 记录公平骰子的点数,取值为一到六。把各个数按出现概率加权平均,得到期望 E[X],这里是三点五。骰子不可能掷出三点五;期望描述的是整个分布的平均水平,不是对下一次结果的保证。
只看平均数还不够:两个策略平均奖励相同,一个可能每次都差不多,另一个可能忽高忽低。方差 Var(X)=E[(X-E[X])^2] 用偏离均值的平方来衡量这种波动,标准差是它的平方根,单位与原来的数一致。平方会去掉正负方向,也让极端值影响更大。对极端值出现得较频繁的重尾分布,还要先确认期望和方差是否存在。
样本统计量从有限观测估计总体性质。给定 n 个数,样本均值为 sum(x_i)/n;把这一批数据当完整总体时方差除以 n,估计未知总体方差时常用除以 n-1 的样本方差。在独立同分布且二阶矩存在等条件下,后一种对总体方差无偏,不能把这个结论直接推广到任意相关轨迹。
文中这几个词,先认一认
- 期望
- 把每个可能的数乘以它出现的概率,再加起来,得到分布的平均水平。
- 标准误
- 如果反复抽样并重复估计,估计结果会波动多大。它描述估计值的波动,不是原始数据本身的波动。
- 蒙特卡洛
- 用许多次随机抽样来近似计算平均结果或积分。例如反复模拟试验,再汇总结果。
02看看它怎么工作
平均值相加与波动相加,要分开看。只要相关期望存在,就有 E[X+Y]=E[X]+E[Y],不要求 X、Y 独立;但 Var(X+Y) 还包含两倍协方差,不能随手把两个方差直接相加。如果 n 个样本独立同分布,样本均值的方差是原方差除以 n,标准误是标准差除以 sqrt(n)。因此想让典型估计误差减半,通常需要把样本数增加到约四倍。
蒙特卡洛可以把积分转为期望。例如 U 在零到一之间均匀取样,E[U^2]=积分0到1的u^2=1/3。抽 n 次并平均平方值,就得到一个随机估计。每次运行可能不同,固定随机种子便于复现具体序列,却不会让估计自动无偏或代表所有种子。
用样本标准差除以 sqrt(n) 可以估计均值标准误,但依赖样本相关结构。相邻训练步骤的损失、同一任务的多次尝试或同一用户的数据往往相关,直接当作独立样本会低估不确定性。应按真正独立的单位抽样,必要时使用分组、时间块或其他适合依赖结构的方法。
直接用 mean(x^2)-mean(x)^2 计算方差,在数值上可能把两个很大的近似数相减,丢失真正很小的波动。例如数据都接近一万亿,但只相差几个单位,两个大平方很接近。Welford 更新维护样本数 n、当前均值 mean 和离差平方和 M2,避免显式形成两个巨大平方的差。
新值 x 到来时,令 delta=x-oldMean,newMean=oldMean+delta/newN,再令 newM2=oldM2+delta*(x-newMean)。第二个差使用更新后的均值,而不是再用旧 delta 平方;这个修正考虑了均值更新后,各数据相对均值的偏差也会变化。总体方差为 M2/n,样本方差为 M2/(n-1),空数据和单样本应按对应定义处理。
先跑通一个最小例子
Python stdlib 对照统计库,并用固定种子估计 E[U^2]。误差断言只检查这个受控实验,不能作为一般置信保证。
import math, random, statistics
data=[1.,2.,3.,4.]
assert statistics.mean(data)==2.5
assert statistics.pvariance(data)==1.25
assert math.isclose(statistics.variance(data),5/3)
assert statistics.pvariance([7.,7.,7.])==0.
rng=random.Random(2026)
draws=[rng.random()**2 for _ in range(20000)]
estimate=statistics.mean(draws)
se=statistics.stdev(draws)/math.sqrt(len(draws)) # 本实验抽样独立,均值标准误才使用此式。
assert abs(estimate-1/3)<0.02
assert se>0
same=random.Random(2026)
assert draws[:3]==[same.random()**2 for _ in range(3)] # 固定种子提供序列可重复性。
print("PASS 7; estimate =",round(estimate,6),"estimated_se =",round(se,6))
核对运行结果打印 PASS 7,估计应接近 1/3,标准误为正;这不是训练收益或总体显著性的证明。
正在加载流程图…
查看流程图源码(Mermaid)
flowchart LR
A["抽样单位与分布假设"] --> B["输入一个观测值"]
B --> C["更新计数和均值"]
C --> D["更新离差平方和"]
D --> E["输出方差与估计误差"]
E --> F["说明独立性和有限样本边界"]按顺序看,每一步做了什么
- 确定随机变量和独立抽样单位。
- 区分总体方差与样本估计。
- 用稳定更新维护均值和 M2。
- 按估计目标选择分母。
- 用多样本与误差说明解释蒙特卡洛结果。
03对照实现代码
CPython v3.14.0;Lib/statistics.py · statistics._ss
以下为原创精简教学实现,不是原样库源码;只演示本文说明的机制,省略真实实现的优化、调度和完整兼容边界。
from fractions import Fraction
def exact_spread(values):
data=[Fraction(x) for x in values] # 原创有理数模型,保留给定有限数的精确比值。
if not data:
raise ValueError("empty")
mean=sum(data)/len(data)
squared=sum((x-mean)**2 for x in data) # 精确算术中离差平方和不受浮点大数相消影响。
return mean,squared
CPython v3.14.0 的 _ss 在未给中心值时,将数据转换成精确比值并按分母累计,形成精确的和与平方和,然后计算离差平方和与均值。源码特别说明某个表达式对普通浮点数数值性质较差,但在 Fraction 精确算术下成立;不能脱离表示方式只复制公式。
这个实现不是 Welford 浮点在线算法。它利用 Python 数值类型和有理数运算获得更精确的统计结果,代价与数值表示大小有关。Java 教学算法选择固定宽度在线状态,是另一种工程方案;两者解决相似统计问题,不能冒称具有相同内部机制或成本。
源码允许传入中心值 c,并走不同的平方偏离累计路径;如果 c 不是所需均值,结果含义会改变。调用者不能为了省一次计算随意传入近似中心,再把返回值无条件当成正确样本方差。公开 statistics 接口的错误处理和类型转换还位于更外层。
原创模型直接使用 Fraction 计算中心化平方差,只保留精确算术如何避免浮点相消的核心思想,未复制分母分组优化、混合数值类型和非有限值处理。读者可以用这个小模型核对简单输入,再对照 Welford 的近似误差和常数状态成本。
代码先调用谁,再调用谁
- statistics 方差接口取得数据
_ss转换精确数值比值- 累计和与平方和或指定中心离差
- 返回均值和离差平方和
- 上层按总体或样本分母形成方差
04动手写一个例子
Welford 在线均值与方差
逐个接收有限 double,维护计数、均值与 M2;总体方差要求至少一个值,样本方差至少两个。输入或中间计算非法时不提交新状态。
- 输入 1
[1,2,3,4]- 输出 1
mean=2.5,population=1.25,sample=5/3
- 输入 2
[7,7,7]- 输出 2
variance=0
状态只保存三个数,不需要保留全部历史数据。每次输入先计算新的计数、均值和 M2 到局部变量,检查其有限性,再写回字段。这样失败的输入不会留下部分更新状态,便于继续诊断或按调用方策略中止。
Welford 的修正项使用旧均值计算 delta,再使用新均值计算第二个差,体现所有旧样本相对新中心移动的影响。若误用 delta*delta,计算得到的不是目标离差平方和;测试 [1,2,3,4] 可以直接暴露这一错误。
单样本的总体方差为零,但样本方差的 n-1 分母为零,不能假装两者都一样。高偏置、小波动数据检查数值稳定性,常量数据检查零方差,空输入和非有限输入检查接口边界。在线算法改善常见相消问题,但不保证任意极值下所有中间结果都可表示。
为什么这样写是对的每次成功更新后,n 是已接受值数量,mean 为其在线均值,M2 为围绕该均值的离差平方和近似。
更新只做固定次数的 double 和 long 运算;历史数据不存储,误差仍受输入尺度和顺序影响。
保存为 Main.java,运行 javac --release 17 -encoding UTF-8 Main.java,再运行 java Main。程序包含固定输入自测,断言失败时会抛出错误。
public class Main {
static final class Stats {
long n;double mean,m2;
void add(double x){
if(!Double.isFinite(x))throw new IllegalArgumentException("finite");
long next=Math.addExact(n,1);
double delta=x-mean,newMean=mean+delta/next;
double newM2=m2+delta*(x-newMean); // 第二个差必须使用新均值。
if(!Double.isFinite(newMean)||!Double.isFinite(newM2))throw new ArithmeticException("range");
n=next;mean=newMean;m2=newM2; // 检查通过后再提交完整状态。
}
double population(){if(n==0)throw new IllegalStateException("empty");return m2/n;}
double sample(){if(n<2)throw new IllegalStateException("need two");return m2/(n-1);}
}
static Stats of(double... x){Stats s=new Stats();for(double v:x)s.add(v);return s;}
static void near(double a,double b){if(!Double.isFinite(a)||Math.abs(a-b)>1e-9)throw new AssertionError(a+" != "+b);}
static void fails(Class<? extends Throwable> type,Runnable r){try{r.run();}catch(Throwable e){if(type.isInstance(e))return;throw new AssertionError(e);}throw new AssertionError();}
public static void main(String[] args){
Stats s=of(1,2,3,4);near(s.mean,2.5);near(s.population(),1.25);near(s.sample(),5.0/3);
near(of(7,7,7).sample(),0);
near(of(1e12+1,1e12+2,1e12+3,1e12+4).population(),1.25); // 大偏置、小波动。
fails(IllegalStateException.class,()->new Stats().population());
fails(IllegalStateException.class,()->of(1).sample());
fails(IllegalArgumentException.class,()->s.add(Double.NaN));if(s.n!=4)throw new AssertionError("partial update");
System.out.println("PASS 6");
}
}这些特殊情况也要试一试
- 空数据均值方差没有本题定义。
- 单样本不能计算样本方差。
- 失败输入不改变状态。
- 数值稳定改进不等于无限精度。
进阶选读 · 分块统计与相关样本
场景数据分布在多个文件或工作节点,或者观测具有时间相关性。
做法用包含均值差修正的合并公式组合块统计;相关样本另按组或时间块估计不确定性,不把块数与原始条数混淆。
复杂度独立块合并每块 O(1),统计含义仍取决于抽样结构。
好处与代价合并均值与方差便于扩展,但仅合并数值不能修复错误的独立性假设。
05项目里怎么用
实验报告至少同时说明样本单位、样本数、均值和波动指标。标准差描述观测分散,标准误描述均值估计的不确定性;把两者混用会让误差条意义不清。若同一任务重复运行多次,应区分任务间差异和同一任务内部随机性,避免以重复次数制造过大的有效样本量。
蒙特卡洛算得多准,取决于样本数、结果波动和抽样方法。对独立样本取均值,增加样本通常能减小估计方差;但特别罕见的事件,普通抽样可能试了很多次仍没见到。重要性采样等方法会改变抽样分布并配套调整权重,才可能提高效率;它们还要求覆盖需要估计的范围,不能随意只挑看起来更有利的样本。
数据处理过程中要保留非有限值策略。直接跳过 NaN 会改变统计对象,按零填充也可能系统性偏移均值;若采用过滤,应报告过滤数量与原因。小型 CPU 实验用于验证公式和实现,对真实训练轨迹需要另行检查相关性、漂移和异常点,不应将固定种子结果视为稳定收益。
容易踩的坑
- 把期望当成下一次必然出现的结果。
- 样本方差与总体方差分母混用。
- 把相关观测当成独立样本计算标准误。
- 直接用两个大平方相减而忽略数值相消。
几种做法,怎么选
表格有四列,窄屏可左右滑动查看代价和适用条件。
| 方案 | 优势 | 代价与限制 | 适用条件 |
|---|---|---|---|
| 保留全部数据两遍计算 | 便于复核和复杂统计 | 存储随数据量增长 | 离线小中型分析 |
| Welford 在线状态 | 单遍、常数额外空间 | 浮点误差与顺序有关 | 流式监控 |
| 精确有理数统计 | 给定可表示数值下精确 | 数值位数和运算成本可能增长 | 小数据参考核对 |
06检验是否读懂了
先自己想、自己写,再展开答案核对。场景题是假设的练习情境;遇到还没学过的内容,可以做完基础后再回来。
先用自己的话解释
01期望三点五是否意味着骰子能掷出三点五?
展开参考答案与推导
不是。期望是分布的加权平均,不必属于随机变量的可能取值集合。它描述长期平均层面的性质,而非单次保证。
02标准差和标准误有什么不同?
展开参考答案与推导
标准差描述原始观测波动,标准误描述估计量在重复抽样中的波动。独立样本均值的标准误约为标准差除以样本数平方根。
03均值标准误总能除以 sqrt(n) 吗?
展开参考答案与推导
不能。该形式依赖独立同分布等条件;相关观测包含协方差项,直接使用原始条数可能低估不确定性。
换个情况,还会处理吗
01均值一样但一个策略极不稳定如何报告?
展开参考答案与推导
同时展示离散程度、分位数和相关失败模式,明确样本数与独立单位。单个均值无法表达尾部风险或跨任务差异。
02样本翻倍为何误差没有减半?
展开参考答案与推导
独立均值的典型误差按样本数平方根缩小,翻倍约缩小到原来的零点七零七。实际一次误差还会随机波动,不要求严格遵循该比例。
03固定种子是否足够证明方法稳定?
展开参考答案与推导
不够。固定种子便于重现同一序列,稳定性需要多个种子或合理重复设计,并区分数据变化与算法随机性。
写代码试一试
01计算总体方差。
- 输入 / 条件
[1,2,3,4]- 输出 / 预期
1.25
提示 均值为2.5。
展开参考答案与推导
离差平方和为五,除以四得到一点二五;若使用样本方差,则分母为三,结果为五除以三。首先要明确这批数据是完整总体,还是用于估计更大总体的样本。
02选择 Welford 修正项。
- 输入 / 条件
旧均值 m,输入 x,新均值 m'- 输出 / 预期
(x-m)*(x-m')
提示 两个中心不同。
展开参考答案与推导
先由旧均值计算 delta,再乘 x 与新均值的差。直接加 delta 的平方没有考虑中心移动,不能维护正确的离差平方和。
03估算增加样本的效果。
- 输入 / 条件
希望均值标准误约减半- 输出 / 预期
约4倍独立样本
提示 平方根收敛。
展开参考答案与推导
标准误与 sqrt(n) 成反比,因此把 n 乘四才使分母乘二。若样本相关或方差变化,这个估算需要重新检查。
读完之后,独立完成
课后作业:自己做一遍
本篇共 10 道作业,先完成 8 道基础与综合任务,再按前置知识挑战进阶题。其中包含 1 道思维拓展,试着换个条件,看看原来的办法是否还管用。不附参考答案。
能计算总体与样本方差,运行固定种子的蒙特卡洛估计,并实现常数额外空间的在线统计。
本篇重点加练
标准误依赖抽样单位与独立性,增加观测行数不必然增加独立信息。
- 均值标准误
- 独立样本假设
重点内容会多练几次。先说清楚怎么做,再试试空数据、出错或条件改变时会发生什么。
先自己做,卡住时记下问题,再回来查。问答题写清“为什么、什么时候适用”;动手题留下输入、输出和运行步骤,方便下次重做。
基础必做
- 作业 01代码推演
离散回报取 -2、1、5,概率为 0.25、0.5、0.25。计算期望、总体方差及回报超过期望的概率,并区分随机变量与统计量。
- 提交内容
- 手算分布表
- 怎样算完成
- 概率使用一致
- 期望与样本观测不混淆
练到的知识点随机变量与取值分布 · 离散期望 · 总体方差
- 作业 02原理问答
对样本 [1,2,2,7] 分别定义总体描述方差、样本方差和均值标准误,注明各自何时可被用于推断。
- 提交内容
- 统计量表与假设说明
- 怎样算完成
- 分母与用途配套
- 独立性条件明确
练到的知识点样本方差与n-1 · 均值标准误 · 独立样本假设
- 作业 03原理问答
同一批十位参与者各贡献十次观测。为“新参与者的均值”与“这十人的后续均值”分别定义估计对象和可用样本单位。
- 提交内容
- 两份统计目标与依赖图
- 怎样算完成
- 目标总体明确
- 相关重复不被默认独立
练到的知识点均值标准误 · 独立样本假设
综合应用
- 作业 04编程实践
仅用 Python 标准库实现流式均值方差统计,按不同分块顺序处理同一份 1000 个数的固定种子数据,并与独立批量实现比较误差。
- 提交内容
- CPU 脚本与核对记录
- 怎样算完成
- 在线状态定义完整
- 误差容差有依据
练到的知识点样本方差与n-1 · Welford在线更新
- 作业 05排错实验
用蒙特卡洛估计区间 [0,1] 上 x² 的积分,比较 100、1000、10000 次采样,各重复 30 次;报告误差分布而非仅一次结果。
- 提交内容
- 实验脚本、结果表与图
- 怎样算完成
- 每轮随机源可追踪
- 成本与误差同时记录
练到的知识点均值标准误 · 蒙特卡洛估计 · 独立样本假设
- 作业 06面试场景
同一测试题重复运行 100 次与独立生成 100 道题,哪一种支持对新题表现的推断?为两种数据分别设计可报告的统计摘要。
- 提交内容
- 实验单位说明与报告样式
- 怎样算完成
- 相关性来源明确
- 推断范围不过度扩张
练到的知识点样本方差与n-1 · 均值标准误 · 独立样本假设
- 作业 07编程实践
用 Python 标准库生成 100 组实验,每组含 20 个独立随机值及其各复制四次的版本;比较两种数据上的均值和按行计算的标准误。
- 提交内容
- CPU 实验与汇总表
- 怎样算完成
- 复制过程保持身份
- 重复实验参数可重现
练到的知识点均值标准误 · 独立样本假设
- 作业 08面试场景
两种测量设备的单次噪声不同、单次成本也不同。自行给定独立噪声方差和预算,计算可采样次数并评审均值精度的比较依据。
- 提交内容
- 带假设的预算与精度表
- 怎样算完成
- 成本单位一致
- 精度推断条件明确
练到的知识点均值标准误
进阶挑战 · 掌握前置后选做
- 作业 09设计评审
评审“复用同一随机样本比较两个估计器”的实验设计;构造 CPU 小实验比较共享随机数与独立随机数的差值波动。
- 提交内容
- 实验与设计审阅意见
- 怎样算完成
- 比较预算相同
- 结论限定在所测分布
练到的知识点蒙特卡洛估计 · 独立样本假设
思维拓展
先写出你的猜想,再用例子或实验验证。答案可以不同,但要说清依据、适用情况,以及还有什么没弄懂。
- 作业 10思维拓展 · 跨域迁移
将标准误问题迁移到网站点击率:同一用户连续点击是否可以当独立样本?设计两种用户生成机制,在纸面或小模拟中展示推断范围如何改变。
- 提交内容
- 生成机制与比较计划
- 怎样算完成
- 用户和点击层级区分
- 机制差异能被观测或模拟
练到的知识点均值标准误 · 独立样本假设
完成后,再检验一次
给每题标记“独立完成 / 查阅后完成 / 尚未完成”。查过资料或没做出的题,记下卡在哪里。隔一天换一组输入再试,能解释结果和出错原因,再把这个知识点标为掌握。
继续阅读
先看能帮你完成当前练习的部分。例子跑通后,再读更深入的解释。
- 必读参考文档英文
CPython 3.14:statistics._ss 的离差平方和 (新标签页)↗
核对精确比值累计与离差平方和计算,明确它与 Java Welford 模型采用不同数值策略。
- 深入参考文档英文
Python 3.14 statistics (新标签页)↗
比较 mean、pvariance、variance 与 stdev 的定义和错误条件。
- 深入参考文档英文
MIT 18.05:概率统计 (新标签页)↗
阅读期望、方差、样本均值与大数定律。
- 深入参考文档英文
Brown Seeing Theory:概率分布 (新标签页)↗
观察分布位置和离散程度怎样影响随机样本。