Having implemented the Reddit ranking algorithm and Wilson Score, I’ve recently been fascinated with Evan Miller’s article on Ranking Hotness with Newton’s Law of Cooling because of its simplicity and ease of implementation.
What I like most about exponential decay:
Minimize writes to the database
You only need to write to the database when you’re incrementing the temperature. No longer need to run Cron jobs to constantly update the db.
Scale with site usage
As your site grows, the algorithm will scale with usage. It’ll only need minor modifications to your parameters to surface New/Popular items to your liking.
Easy to add more signals that influence popularity
When incrementing the temperature, it’s easy to add more signals such as commenting/sharing activity into the equation.
Here’s my simple code implementation in Ruby/Rails:
Your migration rb file:
1 2 3 4 5 6 |
|
In your Active Record Post
class, two helper methods using the Ruby Math
module:
1 2 3 4 5 6 7 8 9 10 |
|
To understand the implementation, let’s look at the general equation for exponential decay:
1 2 3 4 5 |
|
How do we find an appropriate decay constant? First, we need to find a good half-life value. Let’s say 24
hours. Now we can solve for lambda:
1 2 3 |
|
The general pseudo-logic is:
- Set a default temperature for new items (eg.
10.0
) - Pick the lambda (in this case,
0.02888
) - Pick a temperature increment (eg.
1.0
) - When there’s new activity on an item:
- Calculate the item’s current temperature
- Increment the item’s temperature
- Update the item’s record along with the current time (
Time.now
)
- Sort items based on current temperature
In your model or controller, it would look like:
1 2 3 |
|
And that’s it! You can now sort popular items based on exponential decay. Now you can easily tweak the half-life parameters or add additional signal weightings when incrementing the temperature.