【问题标题】:Calculate the running standard deviation计算运行标准差
【发布时间】:2023-04-11 02:04:01
【问题描述】:

我正在将方程式转换为 C++。这对于运行标准偏差是否正确。

this->runningStandardDeviation = (this->sumOfProcessedSquaredSamples - sumSquaredDividedBySampleCount) / (sampleCount - 1);

这是完整的功能:

void BM_Functions::standardDeviationForRunningSamples (float samples [], int sampleCount)
{
    // update the running process samples count
    this->totalSamplesProcessed += sampleCount;

    // get the mean of the samples
    double mean = meanForSamples(samples, sampleCount);

    // sum the deviations
   // sum the squared deviations
   for (int i = 0; i < sampleCount; i++)
   {
        // update the deviation sum of processed samples
        double deviation = samples[i] - mean;
        this->sumOfProcessedSamples += deviation;

        // update the squared deviations sum
        double deviationSquared = deviation * deviation;
        this->sumOfProcessedSquaredSamples += deviationSquared;
    }

    // get the sum squared
    double sumSquared = this->sumOfProcessedSamples * this->sumOfProcessedSamples;

    // get the sum/N
    double sumSquaredDividedBySampleCount = sumSquared / this->totalSamplesProcessed;

    this->runningStandardDeviation = sqrt((this->sumOfProcessedSquaredSamples -     sumSquaredDividedBySampleCount) / (sampleCount - 1));
}

【问题讨论】:

  • sumOfProcessedSquaredSamples - sumSquaredDividedBySampleCount 看起来很可疑,您能否添加一些 cmets 以显示您想要实现的目标以及每个变量的含义?谢谢。
  • 另外,不应该有平方根吗?
  • 谢谢,错过了平方根。为什么方程显示 σ * σ = ... 而不是 σ = sqrt(....) ?
  • σ * σ 是方差,比 sqrt 符号更容易写。
  • sumSquaredDividedBySampleCount = 偏差求和然后平方。除以样本数。

标签: c++ statistics


【解决方案1】:

用于计算运行均值和方差/SD 的数值稳定且高效的算法是Welford's algorithm

一个 C++ 实现是:

std::pair<double,double> getMeanVariance(const std::vector<double>& vec) {
    double mean = 0, M2 = 0, variance = 0;

    size_t n = vec.size();
    for(size_t i = 0; i < n; ++i) {
        double delta = vec[i] - mean;
        mean += delta / (i + 1);
        M2 += delta * (vec[i] - mean);
        variance = M2 / (i + 1);
        if (i >= 2) {
            // <-- You can use the running mean and variance here 
        }
    }

    return std::make_pair(mean, variance);
}

注意:要获取 SD,只需输入sqrt(variance)

【讨论】:

  • 如果您可以看一下,我已经添加了我的实现。我昨天“正式”开始使用 c++,所以请原谅任何错误。
  • 我会投票支持将“稳定”更改为“更稳定”。有了这些浮点除法,我就不太确定效率了……
  • 在一次运行中高效,没有调整到完美(这会使算法难以通过)。如果您知道一种无需除法即可计算均值或方差的方法,我很想听听。
  • 这种方法1到5的方差变成了6.04165。我想念什么吗。方差尚未定义!
  • 修复了代码中的一个栅栏错误并使其编译。感谢 user1436187 指出这一点!
【解决方案2】:

您可以检查是否有足够的 sampleSount(1 会导致除以零)

确保变量具有合适的数据类型(浮点)

否则这看起来是正确的......

【讨论】:

  • 关于数据类型。我在所有这些方程式中都使用双打。这是低效的吗?我会在一段时间内完成这个库,所以计算机只会更强大。未来的证明?我认为如果任何音频程序员故意通过 1,它应该崩溃,如果它有副作用,崩溃可能会突出问题。
最近更新 更多