I don’t understand wine. Can data fix that?

I like wine, but in spite of some fun analysis of wines recently, I still don’t quite understand wines the way I want to. The analysis I’d love to have would simplify all the many ways people describe wines into a few features that show how different kinds of wine relate to one another.

The prototypical example of what I’d love is something similar to what’s been done with scotch whiskey. That’s thanks to some nice analysis of whiskey data, showing that for all the many different ways we can describe them, 50% of the difference among whiskies is due to one of two main features, either the “smokiness” or the “body”. By sampling varieties along these axes, you can develop a thoughtful appreciation for whiskey.

Wine seems more complicated. While people typically use around a dozen terms to describe whiskies, people use hundreds of terms to describe wines, and it would be lovely to have a simple framework for parsing how these descriptions relate wines to one another. I compiled a list capturing ~300 taste-related terms used to describe wine, and the question I’m wondering is: what’s the simplest framework we can use to think about the taste of wine? Do we need all ~300 terms to tell reds from whites? How about Pinot Grigio from Pinot Noirs or Merlot from Malbec?

Before we dig into the data - there’s one big caveat: if you dye a white wine red, people start describing the taste in terms of a red wine. The down side of this is that our ‘taste-terms’ might not be based on taste alone. I’m okay with that. The goal here is to better understand wines, and if this data give us information beyond “red wine is different than white wine”, that’s terrific. And, on the plus side: it should be pretty easy to tell white wines from red.

So first - after loading the wine review data1, and cleaning and processing our database of wine reviews we’ll create a simple model of how wine reviews map on to our selected wine terms. This very simple model is often called a “bag-of-words” model, with each wine review described by the subset of listed terms identified in that review. While there are many more complex ways of relating our wine reviews to one another eiher using context to identify differences in how these terms are used like in a “skip-gram” model, or relating similar terms (e.g. tannins and tannic) as a single feature, it’d be quite promising if even this simple model could effectively compare wine reviews.

Can we get a simpler picture of how wines relate by looking for similarities in how wine terms are used?

Now we have a model of wine reviews: ~100k wine reviews, possessing a combination of ~300 features (where each term is a feature). Given this model, we’ll use principal components analysis (PCA) to see if there are a few features that help separate wines from one another, with these features being principle components (PCs) of the PCA composed of weighted combinations of wine terms.

So, this is pretty nice for our simplified model. Each plot shows a subset of wines from the database, projected onto the two features that best show the differences among individual wines (PC1 and PC2). Based on these features, we can tell white wines from reds just like we expected. This is clearest in the top-left plot, showing all wines labeled as Red Blends, White Blends, or Rosé (which can be made from either traditionally red or white grapes and often has similarities to both red and white wines). As a nice sanity check, it looks like Rosé wines fall right across both the red and white distributions, connecting the two. One surprise is that the difference within red and white wines is just as big as the differences between whites and reds. What’s particularly striking about this spread is that the differences between reds and whites is along a single feature - PC1, most easily seen in the histograms below each scatterplot. This is in contrast with PC2, which captures little difference between reds and whites, but instead captures much of the variability within each category. One takeaway is that that different words are used to describe red and white wines, which will be loaded heavily on PC1. Though nice, with all the individual datapoints for each wine overlain in each of these scatter plots, it’s tough to get a sense for exactly how each wine variety, on average, relates to all the others. If we take the center of each wine variety’s cloud of individual wine reviews, do we see a similar pattern of variation among wine varieties?

This is a terrific bit of insight into how varietals compare to one another, on average. While the spread of these group means aren’t as big as the spread in individual examples, there is still plenty of variation within the white and red clusters (with fun little “really red” wines visible out at the right edge of the plot), all seperated by projection onto PC1. This visualization gives us a simple framework for thinking about different grapes, in a way that seems pretty sensible. Now, what are the terms that were important for making these principle components? To get a better sense, let’s check out how individual words contribute to the first two PCs.

Ok so this makes sense, PC1 seems to call out a number of big red and white wine terms, as tannins, cherry, spice and plum flavour all play a big role in wines ending on the positive end of PC1, and apple, lime, peach, and citrus, traditionally white wine terms, play a role in wines falling on the negative side of PC1. PC2 doesn’t lend itself to nearly as simple an interpretation, but the simplest interpretation is differentiating wines with more robust and rounded flavor (e.g. rich, oaky, full, big, buttery) from lighter, more acidic wines (e.g. bright, flower, fresh, citrus). While this extra feature doesn’t really help tell reds from whites, it, along with the next few dimensions, aids substantially in telling individual wine varieties from one another.

Can we identify what kind of wine was reviewed based on these features?

If we have all this information to tell apart wines, how well can we do at classifying wines by category or varietal from these terms? Does this model actually distil useful information? To start, let’s do a quick classification of just the 4 “Big” wines - varieties that have more than 5000 reviews in our database - can we tell them apart? For this classification we’ll use support vector machines on 5000 reviews for each varieity, projected onto the first few principle components (though any classifier that can handle multiple classes performs well).

They look like they classify pretty well: on average 73% of reviews were correctly assigned to the variety they belonged to, and if we’re misclassifying it’s within the same category. While it’s not suprising we can tell apart reds from whites pretty well (they’re usually described with different terms, after all), it’s reassuring we’re quite good at telling wines apart within red and white categories.

Here’s an interesting thought: Could we use this model to find individual wines that are particularly good examples of their class (like an ur-merlot) or wines that really taste like other things (e.g. can I find a cabernet that tastes like a white wine?). In fact, I just wrote a shiny app to do this, right here if you’re interested in playing with the underlying data.

Until then - let’s get back to our question: how well can we really tell apart wines based on these reviews, and how many features do we need to do that?

How many features do you need to identify wines by category or variety?

When deciding how many features (like our principle components) to include in simplified model of the underlying data, there are a few common heuristics. One commonly used with PCA is the “elbow method” to pick the PC past which all PCs have a similar and low ability to explain the variance in the data. This is done using a “scree plot” of eigenvalues for the principle components analysis, plotted above on the left. Each PC has a decreasing ability to explain the variation among wine reviews. Beyond 12 PCs, each additional PC adds a small bit of explanatory power. One other common heuristic uses the percent of the total variance explained to choose features; by this approach we’d need 150-200 dimensions to explain 90% of the total variance among wine reviews. For my question, the key problem with these heuristics is that they’re both focused on any and all variance in the underlying data, and my interest was a bit more specific. My initial question was: how many features were required to tell wines apart, either by category (white from red) or variety (Cabernet from Pinot). One solution is to simply classify the data with different numbers of features and see how well the classification performs. With this approach we can ask a very specific question that addresses my initial goal: how many dimensions do we need to get to 80% or 90% of our peak ability to classify?

As it turns out (perhaps unsurprisingly) it looks like the number of relevant dimensions for thinking about wine taste depends highly on context. The above plot normalizes classification accuracy to the peak accuracy for each kind of classification (classifying wines by category had a cross-validated accuracy of 95%, while the classifier was 73% accurate with 5 grapes having the most reviews and 50% accurate telling apart all 30+ varieties). In the context of telling broad categories of wines apart, all you need are the two dimensions plotted earlier. These give you all of your ability to classify reds from whites. While these two dimensions also allow you to tell apart some wine varieties relatively well (giving you >70% of your total ability to classify wines), to do better you need to consider more ways in which wines vary. Somewhere between 10 and 20 dimensions are needed to give us 95% of our classification ability, with ~20-30 dimensions giving us near-peak classification performance. That's more a modest number of ways in which wines are described than the initial 300, and while that's still pretty complicated, it's a simpler way of how wines relate to one another than I had before.


written by Brian Sadacca, 8.30.2017


  1. for all code see associated git repository, code for this was wine_text…Rmd : [https://www.github.com/sadacca/wineR].