方差的迭代计算公式


1️、方差基础公式

给定一组数据 x1,x2,...,xnx_1, x_2, \dots, x_nx1,x2,...,xn,其 均值 和 方差 定义如下:

均值:

xˉn=1n∑i=1nxi \bar{x}n = \frac{1}{n} \sum{i=1}^{n} x_i xˉn=n1i=1∑nxi

方差:

无偏样本方差 :
sn2=1n−1∑i=1n(xi−xˉn)2 s_n^2 = \frac{1}{n-1} \sum_{i=1}^{n} (x_i - \bar{x}_n)^2 sn2=n−11i=1∑n(xi−xˉn)2

总体方差 :
σn2=1n∑i=1n(xi−xˉn)2 \sigma_n^2 = \frac{1}{n} \sum_{i=1}^{n} (x_i - \bar{x}_n)^2 σn2=n1i=1∑n(xi−xˉn)2

注意:样本方差比总体方差除以 n−1n-1n−1,以消除偏差。


2️、为什么需要迭代公式?

直接计算方差需要存储所有数据 ,尤其对于大规模数据或流式数据(streaming data),这是不现实的。

迭代公式允许 每来一个新数据 xn+1x_{n+1}xn+1 时更新均值和方差,无需重新扫描整个数据集。


3️、均值迭代公式

已有 nnn 个样本均值 xˉ∗n\bar{x}*nxˉ∗n,加入新样本 x∗n+1x*{n+1}x∗n+1 后,新的均值 xˉn+1\bar{x}_{n+1}xˉn+1:

xˉn+1=xˉn+xn+1−xˉnn+1 \bar{x}_{n+1} = \bar{x}n + \frac{x{n+1} - \bar{x}_n}{n+1} xˉn+1=xˉn+n+1xn+1−xˉn

简单理解:新均值是旧均值加上新数据偏差的 1/(n+1)1/(n+1)1/(n+1)。


4️、方差迭代公式推导(Welford 算法)

  1. 定义当前样本数量 nnn 的 累计平方差 :
    M2,n=∑i=1n(xi−xˉn)2 M_{2,n} = \sum_{i=1}^{n} (x_i - \bar{x}_n)^2 M2,n=i=1∑n(xi−xˉn)2

  2. 当加入新样本 xn+1x_{n+1}xn+1:

    • 更新均值:
      xˉn+1=xˉn+xn+1−xˉnn+1 \bar{x}_{n+1} = \bar{x}n + \frac{x{n+1} - \bar{x}_n}{n+1} xˉn+1=xˉn+n+1xn+1−xˉn
    • 差值:
      δ=xn+1−xˉn \delta = x_{n+1} - \bar{x}n δ=xn+1−xˉn
      δ2=xn+1−xˉn+1 \delta_2 = x
      {n+1} - \bar{x}_{n+1} δ2=xn+1−xˉn+1
  3. 更新累计平方差:
    M2,n+1=M2,n+δ⋅δ2 M_{2,n+1} = M_{2,n} + \delta \cdot \delta_2 M2,n+1=M2,n+δ⋅δ2

  4. 迭代计算方差:

  • 样本方差:
    sn+12=M2,n+1n s_{n+1}^2 = \frac{M_{2,n+1}}{n} sn+12=nM2,n+1
    或无偏样本方差:
    sn+12=M2,n+1n s_{n+1}^2 = \frac{M_{2,n+1}}{n} sn+12=nM2,n+1

核心思想:每次只用上一轮累计平方差 + 新样本与均值的偏差,保证数值稳定,不容易溢出。


5️、数值稳定性说明

Welford 方法相比直接公式:
sn2=1n∑xi2−xˉn2 s_n^2 = \frac{1}{n} \sum x_i^2 - \bar{x}_n^2 sn2=n1∑xi2−xˉn2

优势:

  • 不需要存储所有 xix_ixi;
  • 避免 平方和减去平方均值 导致的数值精度丢失;
  • 可以实时处理大规模或流式数据。

6️、C++ 实战示例

cpp 复制代码
#include <vector>
#include <iostream>

class OnlineVariance {
private:
    int n = 0;
    double mean = 0.0;
    double M2 = 0.0;  // 累计平方差
public:
    void addSample(double x) {
        n++;
        double delta = x - mean;
        mean += delta / n;
        double delta2 = x - mean;
        M2 += delta * delta2;
    }

    double getMean() const { return mean; }
    double getVariance() const { return n > 1 ? M2 / (n-1) : 0.0; } // 样本方差
    double getPopulationVariance() const { return n > 0 ? M2 / n : 0.0; } // 总体方差
};

int main() {
    std::vector<double> data = {2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0};
    OnlineVariance ov;

    for (auto x : data) {
        ov.addSample(x);
        std::cout << "n=" << ov.n << ", mean=" << ov.getMean()
                  << ", variance=" << ov.getVariance() << std::endl;
    }

    return 0;
}

输出示例(部分):

复制代码
n=1, mean=2, variance=0
n=2, mean=3, variance=2
n=3, mean=3.33333, variance=2.33333
...

每增加一个数据点,均值和方差都会被实时更新。


7️、总结公式

  • 均值迭代 :
    xˉn+1=xˉn+xn+1−xˉnn+1 \bar{x}_{n+1} = \bar{x}n + \frac{x{n+1}-\bar{x}_n}{n+1} xˉn+1=xˉn+n+1xn+1−xˉn
  • 累计平方差迭代 :
    M2,n+1=M2,n+(xn+1−xˉn)(xn+1−xˉn+1) M_{2,n+1} = M_{2,n} + (x_{n+1}-\bar{x}n)(x{n+1}-\bar{x}_{n+1}) M2,n+1=M2,n+(xn+1−xˉn)(xn+1−xˉn+1)
  • 方差 :
    sn+12=M2,n+1n(总体方差) s_{n+1}^2 = \frac{M_{2,n+1}}{n} \quad \text{(总体方差)} sn+12=nM2,n+1(总体方差)
    sn+12=M2,n+1n−1(样本方差) s_{n+1}^2 = \frac{M_{2,n+1}}{n-1} \quad \text{(样本方差)} sn+12=n−1M2,n+1(样本方差)

这种迭代方式适合大数据、流式数据和实时计算,数值稳定且无需存储所有历史数据。


相关推荐
小羊没烦恼!4 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
一隅论数智4 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
LaughingZhu4 天前
Product Hunt 每日热榜 | 2026-09-19
人工智能·深度学习·神经网络·搜索引擎·百度
尧炎科技4 天前
防潮抗变形,就选纯品梅花全桉多层板
大数据
Asa121384 天前
R语言实现多组学因子分析(MOFA)
数据分析
猎头南楼4 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
程序员大阳4 天前
副队长大数据教程(5)--集群情况下虚拟机网络配置
大数据·集群·nat·网路
自由能燃气设备4 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
高洁014 天前
未来三年,AI 落地的五个确定性判断一
人工智能·深度学习·机器学习·transformer·知识图谱
科创致远4 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程