This is a great discussion of the mechanics of rendering star ratings in a browser. I'd love to see a companion theory post on how to intelligently compute and rank such ratings. The arithmetic mean is notoriously sensitive to outliers, and the consequences are sometimes severe: I know a resort in Thailand that used to be ranked #1 on TripAdvisor on its island (Koh Phangan), only to fall to #17 after a 1-star review. (The tragedy is that, if you read the review, it's clearly positive—the reviewer evidently thought that 1-star was best. D'oh!) In addition, any sensible ranking should take into account statistical significance, so that (say) a 4.6 ranking consisting of 45 reviews (possibly) gets ranked above a 5-star ranking consisting of one review. How does Airbnb handle these cases, or does it just punt by calculating and sorting the arithmetic mean?
I am super surprised by your comment, because thats exactly the question I asked my friend yesterday. I am trying to implement a ranking system on my website, so I asked my more experienced friend about it and he recommended me one book:
Programming Collective Intelligence Building Smart Web 2.0 Applications by Toby Segaran, O'Reilly
It's interesting that the year 2000 way to do stars would be to have a full, empty, and half star GIF, and just to display however many stars you need by doing a loop.
So, when this article says "The goal is to avoid having a sprite that looks like this" where the sprite has all the values of stars in a line... why did people switch to doing it that way in the first place? Like the article says, it's a pain to maintain, has lots of pixels, and is not resizable.
Well, if you do it that way you can change the whole rating by just changing the class name, after you set up all the background-position rules for all the different rating classes. I guess that's why?
I liked how you guys present some of the stuff you create.
However, I'm not a huge fan of star rating. I know it's in use everywhere but I feel that it's such a flawed rating system that we need to think twice before using star ratings.
I think that Facebook's like is a good concept that can replace stars rating (a like is a like, no negative feedbacks, and you know that you either like something or you didn't).
Star ratings is too complex, I mean, something I rate 4 star is very different than somebody else's 4 star rating.
Maybe this isn't the place to discuss this but I wanted to let the word out ;)
This is touched on in some of the other posts, so I won't belabor the point, but the issue with only positive feedback is that there isn't a way to identify items that are popular but also controversial.
For example, an Airbnb venue with 5,000 likes would be considered 'better' than one with 500. But add in negative feedback, and consider if the same venue with 5,000 likes also had 4,500 dislikes, while the venue with 500 likes only had 50 dislikes.
Negative feedback helps us discern between if something is 'better' or simply 'popular' -- the latter can be gamed with marketing, while the former is much harder.
The HTML5 meter element lends itself to star ratings perfectly. Using divs with classes seems a bit old-school for today, although the blog post does say how they don't want to use JS for this.
I wrote a Raphael powered polyfill for this http://dylanfm.github.com/jquery.ratemate/. Although it requires Raphael (and JS), at least it's a bit more semantic and has a non-JS fallback in browsers that have native support for the meter element. The plugin also provides a way for controlling star ratings on input type number or range elements. However, this really isn't worth using if you're not including Raphael already (fairly large library). I'm thinking about making a canvas alternative.
This is the code that should go to the server side for calculating star ratings:
Star Ratings
I’ve been awfully busy programming lately. My Django-based side project is coming along well and I hope to have it ready for use in a few weeks. Please don’t ask more about it, that’s really all I can say for now. Anyways, I came across an interesting little math problem today and was hoping some skilled programmers out there could come up with a more elegant solution than mine.
Problem: Star Ratings
People can rate cheeseburgers on my website with a star rating of 0-5 stars (whole stars only), 5 being mighty tasty and 0 being disgusting. I would like to show the average of everyone’s ratings of a particular cheeseburger to the nearest half star. I have already calculated the average rating as a float (star_sum) and the total number of people that rated the particular cheeseburger (num_raters). The result should be stored as a float in a variable named “stars.”
My Solution (in Python):
# round to one decimal place and
# separate into whole and fractional parts
parts = str(round(star_sum/num_raters, 1)).split('.')
whole = int(parts[0])
frac = int(parts[1])
if frac < 3:
___frac = 0
elif frac > 7:
___frac = 0
___whole += 1
else:
___frac = 5
# recombine for a star rating rounded to the half
stars = float(str(whole)+’.'+str(frac))
Mmmm… In-N-Out Burgers… Please leave a comment if you’ve got a better solution.
Pretty nice. It's missing the actual content though (the rating), so it's completely inaccessible to search engines, scrapers, screen readers and the like.
I would do it another way. I'd have an on state and off state graphic as a sprite. There'd be two divisions, one laid on top of each other. The bottom layer would be the off state tiled horizontally statically at the width that is the number stars your ratings setup uses by the width of you on-off state graphic. The layer on top would be the on state with a width determined by an online style - CSS accepts percentage as a unit which can be worked out trivially. I find this is far more flexible that setting static widths in the CSS. You only haVe to set one width: the number of stars. Other things can be worked out programmatically and cached if needed.
[+] [-] mhartl|14 years ago|reply
[+] [-] gwillen|14 years ago|reply
http://www.evanmiller.org/how-not-to-sort-by-average-rating....
[+] [-] nazar|14 years ago|reply
http://shop.oreilly.com/product/9780596529321.do
[+] [-] nkurz|14 years ago|reply
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] ajtaylor|14 years ago|reply
[+] [-] smackfu|14 years ago|reply
So, when this article says "The goal is to avoid having a sprite that looks like this" where the sprite has all the values of stars in a line... why did people switch to doing it that way in the first place? Like the article says, it's a pain to maintain, has lots of pixels, and is not resizable.
[+] [-] funkah|14 years ago|reply
[+] [-] pothibo|14 years ago|reply
I think that Facebook's like is a good concept that can replace stars rating (a like is a like, no negative feedbacks, and you know that you either like something or you didn't).
Star ratings is too complex, I mean, something I rate 4 star is very different than somebody else's 4 star rating.
Maybe this isn't the place to discuss this but I wanted to let the word out ;)
[+] [-] mikehearn|14 years ago|reply
For example, an Airbnb venue with 5,000 likes would be considered 'better' than one with 500. But add in negative feedback, and consider if the same venue with 5,000 likes also had 4,500 dislikes, while the venue with 500 likes only had 50 dislikes.
Negative feedback helps us discern between if something is 'better' or simply 'popular' -- the latter can be gamed with marketing, while the former is much harder.
[+] [-] swah|14 years ago|reply
[+] [-] v01|14 years ago|reply
For example big demo button on CodDrops: http://tympanus.net/codrops/2011/10/12/flexible-slide-to-top...
[+] [-] Dylanfm|14 years ago|reply
I wrote a Raphael powered polyfill for this http://dylanfm.github.com/jquery.ratemate/. Although it requires Raphael (and JS), at least it's a bit more semantic and has a non-JS fallback in browsers that have native support for the meter element. The plugin also provides a way for controlling star ratings on input type number or range elements. However, this really isn't worth using if you're not including Raphael already (fairly large library). I'm thinking about making a canvas alternative.
[+] [-] Aloisius|14 years ago|reply
[+] [-] llgrrl_|14 years ago|reply
Star Ratings
I’ve been awfully busy programming lately. My Django-based side project is coming along well and I hope to have it ready for use in a few weeks. Please don’t ask more about it, that’s really all I can say for now. Anyways, I came across an interesting little math problem today and was hoping some skilled programmers out there could come up with a more elegant solution than mine.
Problem: Star Ratings
People can rate cheeseburgers on my website with a star rating of 0-5 stars (whole stars only), 5 being mighty tasty and 0 being disgusting. I would like to show the average of everyone’s ratings of a particular cheeseburger to the nearest half star. I have already calculated the average rating as a float (star_sum) and the total number of people that rated the particular cheeseburger (num_raters). The result should be stored as a float in a variable named “stars.”
My Solution (in Python):
Mmmm… In-N-Out Burgers… Please leave a comment if you’ve got a better solution.[+] [-] teej|14 years ago|reply
[+] [-] jeiting|14 years ago|reply
def round_to_half(x): if ( x < 1) { if (x < 3) { return 0; else if (x > 7) { return 1.0; } else { return 0.5 } } else { return round_to_half(x/10); } }
x = star_sum/num_raters dec = round_to_half(x) x = floor(x/10) + dec
This way you look smarter for using recursion.
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] Aloisius|14 years ago|reply
[+] [-] ricardobeat|14 years ago|reply
[+] [-] jwdunne|14 years ago|reply
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] swah|14 years ago|reply
[+] [-] pchristensen|14 years ago|reply
[+] [-] huxley|14 years ago|reply
[+] [-] rhdoenges|14 years ago|reply
[+] [-] dfischer|14 years ago|reply