Tuesday, February 19, 2013

Programming: Calculating Ongoing/Moving Average - Average Over Time

Problem:
I am writing a platform that will track ratings of people over time and display an average star rating per person. It dawned on me that there should be a solution out there, so I went looking. If you're not familiar with calculating an average, you would normally do a mean average like this:

(n1 + n2 + n3 + n4) / n_count

Like this:

(1 + 2 + 3 + 4) / 4     // The 4 as the divisor because we added 4 numbers together.

But this doesn't work very efficiently when your programming an application that will constantly be displaying the user's average, not to mention having to do the query to get all the values and run the calculation every time would mean using a lot more in server resources.

Solution:
Use a weighted average over time (also sometimes called an ongoing average, rolling average, running average, or moving average). You will still need a couple reference points in order to do this, but you will find it will be much simpler on both the calculation and the resource usage. This will only need to be calculated when input numbers affecting the weighted average have changed (been added, removed, or modified).

new_avg = (existing_avg * existing_number_of_ratings + new_rating) / (existing_number_of_ratings + 1)

Now new_avg will be the current weighted average for that user. Just be sure to store the existing number of ratings so you can compute this again later.

Note: Mean average and weighted averages wont always produce the same result.



No comments: