I'd like to implement a passive rating system, and though this seems like a standard problem, I've been unable to find any implemented solutions.
My use case is:
As a user, I didn't like a book and want a different book. (this decreases the book's rating) As a user, I finished reading the book and marked it finished. (this increases the book's rating)
In ruby pseudocode:
class Book
include Mongoid::Document
field :subject, type: String
field :rating, type: Float
end
def request_replacement
self.rating -= 0.01
return Book.where(subject: self.subject).all.sample
end
@book.request_replacement
The rating influences the likelihood the book will be recommended to readers in the future.
I initialized each book's rating as 0.50. I naively figured each time a user requested a substitute, I'd decrease the book's rating (-0.01), and each time a user marked the book finished, I'd increase the book's rating (+0.01).
I am afraid, however, that a bunch of early negative reviews could push a book's rating so low it's never recommended, and that too many positive reviews would lead to excessive recommendation of the book.
Is there a conventional way to increase and decrease the value of the float to prevent such runaway effects (perhaps asymptotically approaching 1 and 0 respectively?)
Thanks for your time and insights!
If you need a kind of coefficient, that starts from some value and asymptotically approaches 1, you can use exponential function e-x in the following way:
1 - k*exp(-mt)
where t
is time or count of book queries, m
is "speed" of growth (the bigger is m, the faster whole coefficient reaches ~1), 1 - k
is the value at t = 0.
Here, k = 0.5 and m = 1/20