online-mean
Online mean calculation (piece-by-piece)
Usage
const Mean = // Create a new mean object calling Mean() or new Mean()// Each of these object stores inner variables// So we need this extra step to be able to calculate means of multiple data flowsconst m1 = const m2 = // same as const m2 = Mean() // Update calling mean objects directly, as a function:;1 2 3 4 5 // Or via .fit() method. These two ways are identical!;4 5 6 7 8 // Using with arrays: // Keep in mind - this line updates m1 with 3 new data values, not just averages the array // Get mean value calling mean object with no arguments:console // -> 5.625 // Or via .value getterconsole // -> 6 // Total number of observations:console // -> 5 // Merge multiple mean objects:const m3 = Meanconsole // -> ~5.769 // 'n' and 'value' are not just object keys, but object getters.// If you really need to change their values use .setN() and .setValue() methods:m2m2console // -> 0 0
How it works
A classical formula of a sample mean is defined as follows:
ān = (Σi=1..n xi) / n
It basically iterates over all values of x
, sums them and divides on total number of samples. That works when the length of x
is small and you don't need to update the mean when new values added. To calculate mean ā
in on-line fashion we will use a recursive formula:
ān = ān-1 + (xn - ān-1) / n
It's still based on the classical formula, however instead of summing all values we calculate ā
recursively. Derivation:
ān = (Σi=1..n xi) / n
ān = (Σi=1..n-1 xi + xn) / n
ān = ((n-1) × ān-1 + xn) / n
ān = ān-1 + (-ān-1 + xn) / n
ān = ān-1 + (xn - ān-1) / n
To merge multiple means without iterating over all values of x, we will expand the formula a little:
ānm = (Σi=1..n xi + Σj=1..m xj) / (n + m)
ānm = (n * ān + m * ām) / (n + m)
Such multiplications in the numerator could produce quite big numbers, so it's better to change the expression:
ānm = (n * ān + m * ān - m * ān + m * ām) / (n + m)
ānm = ān + (- m * ān + m * ām) / (n + m)
ānm = ān + (ām - ān) * m / (n + m)
Much better! :)