{"id":469,"date":"2013-09-11T09:46:13","date_gmt":"2013-09-11T09:46:13","guid":{"rendered":"http:\/\/anna.ps\/blog\/?p=469"},"modified":"2017-03-16T16:28:36","modified_gmt":"2017-03-16T16:28:36","slug":"statistics-find-nicest-food-at-waitrose","status":"publish","type":"post","link":"https:\/\/anna.ps\/blog\/statistics-find-nicest-food-at-waitrose","title":{"rendered":"Using statistics to find the nicest (and nastiest) food at Waitrose"},"content":{"rendered":"<p><em>Using the Wilson score interval to identify the most delicious, and disgusting, foods at Britain&#8217;s best online supermarket. <a href=\"#results\">Jump to the results<\/a>.<\/em><\/p>\n<p>The hardest bit of cooking, for me, has always been <em>choosing what to cook<\/em>. Sure, it&#8217;s fine if you only make dinner once a week &#8211; then you can flick through a designer cookbook and pick the prettiest picture. <\/p>\n<p>But actual cooking, every day, without it taking up all your time &#8211; that&#8217;s tougher. You need food that is tasty, healthy, and affordable. Finding this is hard, so it&#8217;s easy to end up cooking the same things again and again. <\/p>\n<p>And online shopping makes meal-planning even less inspiring &#8211; you can&#8217;t smell a tomato to see if it&#8217;s ripe. That&#8217;s why I was so excited when I realised I could use the power of statistics to find the overall most delicious &#8211; and the most disgusting &#8211; things you can buy at <a href=\"http:\/\/ocado.com\">Ocado<\/a>. <\/p>\n<p>(For non-UK readers, Ocado is an online supermarket chain. It mostly sells food from Waitrose, the best British supermarket. And I have no affiliation with either company.)<\/p>\n<p><strong>How not to sort by average rating<\/strong><\/p>\n<p>I was mulling the above recently when I came across Evan Miller&#8217;s <a href=\"http:\/\/www.evanmiller.org\/how-not-to-sort-by-average-rating.html\">How Not To Sort By Average Rating<\/a>. It&#8217;s a great article, and I realised I could use it to make my own shopping easier. <\/p>\n<p>Ocado have great reviews on their site, with rich comments and star ratings, but they commit the second type of sin mentioned by Evan &#8211; they rank their groceries by mean rating. This means that you can&#8217;t reliably tell which groceries are actually the most popular. <\/p>\n<p>Let me show you why this matters. Say I want soup for Friday lunch. I will find the &#8220;soup&#8221; category on the Ocado site, and then sort by customer rating. These are the top results: <\/p>\n<div class=\"wp-caption center\" style=\"width: 601px\"><img loading=\"lazy\" decoding=\"async\" title=\"Screenshot of Ocado's soups, ranked by customer rating\" src=\"https:\/\/anna.ps\/blog\/wp-content\/uploads\/2013\/09\/ocado-soups-top.png\" width=\"591\" height=\"349\"><\/div>\n<p>As noted above, Ocado ranks by the average &#8211; <em>mean<\/em> &#8211; star rating for each product. This throws up some weird anomalies. <\/p>\n<p>For example, in third place is Swedish blueberry soup, with just two reviews. Both those reviews are five-star, so it has a mean rating of five stars. Swedish blueberry soup may well be delicious, but with only two reviews, I&#8217;m unwilling to take a chance. <\/p>\n<p>Much further down, in 10th place, is some gazpacho, with 48 ratings, of which 47 are positive and 46 are five-star. That means it has a slightly lower mean ranking, of 4.91 stars, so it comes further down the list. But 46 people loved it enough both to review it and give it five stars. <\/p>\n<div class=\"wp-caption center\" style=\"width: 601px\"><img loading=\"lazy\" decoding=\"async\" title=\"Gazpacho soup is popular\" src=\"https:\/\/anna.ps\/blog\/wp-content\/uploads\/2013\/09\/Screen-Shot-2013-09-04-at-12.56.30.png\" width=\"591\" height=\"349\"><\/div>\n<p>I want to try that gazpacho! But to work out it was popular, I had to click every soup to check the number of reviews. I can&#8217;t do that with every single thing on my shopping list. <\/p>\n<p><strong>Estimating true popularity with the Wilson interval<\/strong><\/p>\n<p>So how can we unleash the full potential of Ocado&#8217;s reviews? Evan&#8217;s article explains how to trade off a high average rating against the overall number of reviews. We can calculate a <em>confidence interval<\/em> for each soup&#8217;s true popularity. <\/p>\n<p>Here is Wilson&#8217;s interval in full:  <\/p>\n<div class=\"wp-caption center\" style=\"width: 601px\"><a href=\"http:\/\/www.evanmiller.org\/how-not-to-sort-by-average-rating.html\"><img loading=\"lazy\" decoding=\"async\" title=\"Wilson's score interval\" src=\"http:\/\/anna.ps\/blog\/wp-content\/uploads\/2013\/09\/rating-equation.png\" width=\"591\" height=\"349\"><\/a><\/div>\n<p>The maths looks complicated, but the premise is this (as articulated by <a href=\"https:\/\/news.ycombinator.com\/item?id=3793126\">a Hacker News comment<\/a>): <strong>&#8220;If we rounded up the entire population and forced every single person to carefully review this item and issue a rating, what&#8217;s our best guess as to the percentage of people who would rate it positively?&#8221;<\/strong><\/p>\n<p>The clever thing about the Wilson interval is that it looks at the number of ratings as well as the value of the reviews. If few people have reviewed a product, our confidence interval is wide. As more people review it, the confidence interval narrows &#8211; because we&#8217;re more confident about how good or bad it really is.  <\/p>\n<p>So, we can now rank all the foods listed on the Ocado site. I wrote <a href=\"https:\/\/github.com\/annapowellsmith\/misc\/blob\/master\/get_ocado_products.py\">a Python script<\/a> to scrape them all. For each item, I recorded the total number of reviews, and the proportion of reviewers who would recommend the product. <\/p>\n<p>Then I wrote more Python code (based on Evan&#8217;s <a href=\"http:\/\/www.evanmiller.org\/how-not-to-sort-by-average-rating.html\">Ruby example<\/a>) to calculate the Wilson score interval for each product. <a href=\"https:\/\/github.com\/annapowellsmith\/misc\/blob\/master\/calculate_score.py\">Here is the full script<\/a> &#8211; you are welcome to use it for your own projects. <\/p>\n<p><span id=\"results\"><strong>The results: sugar and convenience good&#8230;<\/strong><\/span><\/p>\n<p>Without more ado, here are the definitive results: the most popular of the 18,229 foods that you can buy at Ocado, ranked by the lower bound of the 95% Wilson score interval. <\/p>\n<p><iframe loading=\"lazy\" width=\"100%\" height=\"500\" src=\"https:\/\/anna.ps\/iframes\/ocado-best\/table.html\" frameborder=\"1\"><\/iframe><\/p>\n<p>So what does this tell us about Britons&#8217; tastes? Well, it seems we really like:<\/p>\n<ul>\n<li><em>Fattening food.<\/em> We bought the apple yogurt, in second place. It is satanic &#8211; so sugary that I threw it away unfinished. The passionfruit yogurt in 19th looks even sweeter. The green Thai soup in 13th is very nice, but at 500 calories a pot, it ought to be.<\/li>\n<li><em>Convenience food.<\/em> Frozen pain au chocolats and baguettes &#8211; these are indeed handy. Posh fish fingers. Ready-chopped shallots. You get the picture.<\/li>\n<li><em>Reliable basics.<\/em> Eggs and milk do surprisingly well. Who reviews milk?! But Clarence Court eggs are indeed very nice.<\/li>\n<li><em>Specialist foods.<\/em> Tofu, gluten-free bread, quark, dairy-free ice-cream &#8211; I guess tasty versions of these become cult items for people with restricted diets.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/docs.google.com\/spreadsheet\/ccc?key=0Atncguwd4yTedDN4Nkd6cm9SR2c5WTJ5aGxYQXVFTEE&#038;usp=sharing\">The full spreadsheet is here<\/a>. You&#8217;ll see that I exclude some branded products from the list. This was because they had sponsored reviews, so I didn&#8217;t think it was fair to include them. <\/p>\n<p><strong>&#8230;Heston Blumenthal and runner beans bad<\/strong><\/p>\n<p>We can also calculate the most negatively rated items. This is quite simple &#8211; we just plug the same data into the same equation, but instead of looking at the number of reviewers who would recommend the item, we look at the number who wouldn&#8217;t. <\/p>\n<p>Here are the most hated things sold by Ocado, ranked by the lower bound of the 95% Wilson confidence interval. <\/p>\n<p><iframe loading=\"lazy\" width=\"100%\" height=\"500\" src=\"https:\/\/anna.ps\/iframes\/ocado-worst\/table.html\" frameborder=\"1\"><\/iframe><\/p>\n<p>What are the patterns here? It seems fresh fruit and vegetables are often disappointing. We tried the runner beans &#8211; they tasted of stringy dishwater &#8211; and the peaches, which went from rock-hard to rotten overnight. <\/p>\n<p>British bagels also suck, but we all knew that. <\/p>\n<p>Speaking of serious problems, I really want to try the <a href=\"http:\/\/ocado.com\/webshop\/product\/Heston-from-Waitrose-Baked-Alaska-Ice-Cream\/78556011\">Heston Blumenthal baked alaska<\/a>, which apparently consists of &#8220;smooth raspberry parfait encased in crisp chocolate glaze surrounded by banana and caramel parfait wrapped in a light sponge and covered in soft meringue&#8221;. Just 8 out of 91 reviewers recommended it, and this is what people said: <\/p>\n<blockquote><p>Horrible&#8230; <br \/>Synthetic&#8230; <br \/>Bleuch&#8230;<br \/>Just wrong&#8230;<br \/>[Tastes of] amyl acetate and the artificial strawberry flavour in the penicillin we had as kids&#8230;<br \/>Chemical Ali could have made better&#8230;<br \/>Simply the foulest dessert we&#8217;ve ever tasted&#8230;<br \/>Worst product I have ever had&#8230;<br \/>Even my dog wouldn&#8217;t eat it.<\/p><\/blockquote>\n<p><a href=\"https:\/\/docs.google.com\/spreadsheet\/ccc?key=0Atncguwd4yTedDN4Nkd6cm9SR2c5WTJ5aGxYQXVFTEE&#038;usp=sharing\">Here&#8217;s the full spreadsheet<\/a>. The &#8220;Proportion positive&#8221; and &#8220;Proportion negative&#8221; columns show the Wilson boundaries &#8211; perhaps it will inspire your own shopping. <\/p>\n<p>With luck, Ocado will eventually change the way they rank their items. In the mean time, I&#8217;ll be using the spreadsheet to find inspiration &#8211; and steering clear of Heston&#8217;s runner-bean surprise. <\/p>\n<p><em>If you are interested in the maths behind the Wilson score interval, there&#8217;s a <a href=\"https:\/\/news.ycombinator.com\/item?id=3792627\">good discussion at Hacker News<\/a>, including links to some critiques of the approach. <\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using the Wilson score interval to identify the most delicious, and disgusting, foods at Britain&#8217;s best online supermarket. Jump to the results. The hardest bit of cooking, for me, has always been choosing what to cook. Sure, it&#8217;s fine if you only make dinner once a week &#8211; then you can flick through a designer [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,12],"tags":[],"class_list":["post-469","post","type-post","status-publish","format-standard","hentry","category-life-hacking","category-retail"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/posts\/469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/comments?post=469"}],"version-history":[{"count":122,"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/posts\/469\/revisions"}],"predecessor-version":[{"id":732,"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/posts\/469\/revisions\/732"}],"wp:attachment":[{"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/media?parent=469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/categories?post=469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/anna.ps\/blog\/wp-json\/wp\/v2\/tags?post=469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}