Variance

有限內存的在線方差估計

  • September 15, 2016

我正在創建一個組件,旨在計算與一段時間內發生的事件相關的指標的平均值和方差,但內部內存有限。

想像一下,這些事件是進入商店的訪客,衡量標準是他們的年齡。

在一段時間內,我的組件會收到每個訪問者年齡的事件。我不希望我的組件記住每個時代的歷史。理想情況下,我想要一個僅存儲的輕量級組件:平均值A、方差 V 和事件數N

在每個年齡事件之後E,我想更新這三個值:

N<=N+1
A<=(A*N+E)/(N+1)
V<=???

有什麼用V?我正在考慮類似的事情:

V<=(V*N+(E-A)^2)/(N+1)

我知道這不准確,因為我以前V使用的是舊A的,不再是平均水平。

Q1 - 有確切的公式嗎?

Q2 - 如果不是,我的建議是一個好的估計嗎?有偏見嗎?N增加時它會正確收斂嗎?

Q3 - 有沒有更好的配方?

Welford (1962) 描述了在線計算方差的簡單算法。下面你可以看到它的 C++/Rcpp 實現,它可以離線工作,但可以很容易地適應在線場景:

List welford_cpp(NumericVector x) {

 int n = x.length();
 double delta;
 double msq = 0;
 double mean = x[0];

 if (n > 1) {
   for (int i = 1; i < n; i++) { 
     delta = x[i] - mean;
     mean += delta / (i+1);
     msq += delta * (x[i] - mean);
   }
   return Rcpp::List::create(Rcpp::Named("mean") = mean,
                             Rcpp::Named("variance") = msq / (n-1));
 }

 return Rcpp::List::create(Rcpp::Named("mean") = mean,
                           Rcpp::Named("variance") = NAN);
}

如您所見,它只需要存儲四個變量:n、和 ,delta並根據需要同時計算均值和方差。msq``mean


英國石油公司韋爾福德 (1962)。關於計算校正平方和乘積的方法的注意事項。技術計量學 4(3):419-420。

引用自:https://stats.stackexchange.com/questions/235129

comments powered by Disqus