Variance
有限內存的在線方差估計
我正在創建一個組件,旨在計算與一段時間內發生的事件相關的指標的平均值和方差,但內部內存有限。
想像一下,這些事件是進入商店的訪客,衡量標準是他們的年齡。
在一段時間內,我的組件會收到每個訪問者年齡的事件。我不希望我的組件記住每個時代的歷史。理想情況下,我想要一個僅存儲的輕量級組件:平均值
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。