A Computational Exploration of Alcoholic Beverages
Author
Isabel Skidmore
Title
A Computational Exploration of Alcoholic Beverages
Description
Cheers! Food Blog Livestream Notebook
Category
Essays, Posts & Presentations
Keywords
Livestream, Food, Beverages
URL
http://www.notebookarchive.org/2022-10-2cq1l0a/
DOI
https://notebookarchive.org/2022-10-2cq1l0a
Date Added
2022-10-05
Date Last Modified
2022-10-05
File Size
0.84 megabytes
Supplements
Rights
Redistribution rights reserved
Download
Open in Wolfram Cloud
A Computational Exploration of Alcoholic Beverages
A Computational Exploration of Alcoholic Beverages
Oct 2022
Isabel Skidmore, Lead Food Developer, Wolfram | Alpha Scientific Content
Oct 2022
Isabel Skidmore, Lead Food Developer, Wolfram | Alpha Scientific Content
Isabel Skidmore, Lead Food Developer, Wolfram | Alpha Scientific Content
Adapted from “Cheers! A Computational Exploration of Alcoholic Beverages with the Wolfram Language” blog post (https://blog.wolfram.com/2022/09/15/cheers-a-computational-exploration-of-alcoholic-beverages-with-the-wolfram-language/)
For 10,000 years, humans have been using fermentation to produce beverages for pleasure, for rituals and for healing. In ancient Greece, honey was fermented to produce mead. Today, popular sources of beverage fermentation are grains, grapes, berries and rice. The science of fermentation — known as zymology (or zymurgy) — is a fascinating blend of chemistry, biology, history and geography. Wolfram Language now brings a new dimension to the study of alcoholic beverages, through an extensive data set ready to be explored and analyzed.
Food Basics
Food Basics
In[]:=
refried beans | » | |||||
|
In[]:=
RandomSampleEntityList@
,10
| ||||||||
|
Out[]=
,,,,,,,,,
San Marcos, Emsanmar, Refried Black Beans
(USDA: Branded, LabelInsight)
Cadia, Organic Refried Vegetarian Beans
(USDA: Branded, LabelInsight)
FAT FREE REFRIED BEANS
(USDA: Branded, LabelInsight)
ROSARITA Non Fat Refried Beans, 16 OZ
(USDA: Branded, GS1)
TRADITIONAL REFRIED BEANS
(USDA: Branded, LabelInsight)
TRADITIONAL REFRIED BEANS
(USDA: Branded, LabelInsight)
ORGANIC FAT FREE REFRIED BLACK BEANS
(USDA: Branded, LabelInsight)
REFRIED BEANS
(USDA: Branded, LabelInsight)
Ducal, Refried Black Beans
(USDA: Branded, LabelInsight)
Original Refried Beans - #10 Can, Unprepared
(USDA: Branded)
EntityProperty["Food","AlanineContentPerServing"]
In[]:=
EntityValue["Food","Properties"]//Select[StringContainsQ[Last@#,"calorie",IgnoreCase->True]&]
Out[]=
,,,,,,,,,,,,,,,,,,
alcohol calorie content per typical item size
alcohol calorie content per typical serving size
calorie label
carbohydrate-calorie factor
carbohydrate calories per typical item size
carbohydrate calories per typical serving size
fat calorie factor
fat calorie content per typical item size
fat calorie content per typical serving size
protein calorie factor
protein calorie content per typical item size
protein calorie content per typical serving size
relative alcohol calorie content
relative carbohydrate calorie content
relative fat calorie content
relative protein calorie content
relative calorie content
calorie content per typical item size
calorie content per typical serving size
In[]:=
EntityValue
,
| ||||||||
|
relative fat calorie content
Out[]=
0.147123
Cal/g
In[]:=
100g of refried beans | |||||
EntityInstance
100 g |
Out[]=
EntityInstance
,
| ||||
|
100
g
Alcohol Arithmetic
Alcohol Arithmetic
Wolfram Language offers more than 5,000 functions, including arithmetic functions like Max, Min, Mean and Median. Let’s look at the median alcohol content per serving and default serving size volume for all rums in the alcoholic beverages data.
In[]:=
MedianDeleteMissingEntityValueEntityList@
,{"AlcoholContentPerServing","DefaultServingSizeVolume"},"PropertyAssociation",1,2
| |||||
|
Out[]=
AlcoholContentPerServing,DefaultServingSizeVolume
15.7479
g
44.3603
mL
This mimics EntityValue’s default behavior when working with attributed Food entities:
In[]:=
EntityValue
,{"AlcoholContentPerServing","DefaultServingSizeVolume"},"PropertyAssociation"
| |||||
|
Out[]=
AlcoholContentPerServing,DefaultServingSizeVolume
15.9697
g
44.3603
mL
You can apply the same calculation to other alcoholic beverages, including alcohol FoodTypes “Cognac,” “Sake” and “Brandy,” to see how they compare with “Rum.”
Wolfram Language data on the alcohol content of beverages can help when deciding how much to drink. On a night out, approximately how many drafts of beer equate to the usual glass of Chardonnay you have at home? The average glass of wine is about 5 fluid ounces:
Wolfram Language data on the alcohol content of beverages can help when deciding how much to drink. On a night out, approximately how many drafts of beer equate to the usual glass of Chardonnay you have at home? The average glass of wine is about 5 fluid ounces:
In[]:=
glassOfWine=EntityInstance
,Quantity[5,"FluidOunces"]["AbsoluteAlcoholContent"]
| ||||||||
|
Out[]=
15.6755
g
A serving of draft beer is usually 1 pint:
In[]:=
draftBeer=EntityInstance
,Quantity[1,"Pints"]["AbsoluteAlcoholContent"]
| |||||
|
Out[]=
26.4
g
So, every pint of beer is equivalent in alcohol content to slightly more than 1 ½ glasses of wine:
In[]:=
N[draftBeer/glassOfWine]
Out[]=
1.68416
Knowledge of alcohol content can be useful when designing or choosing cocktails. Once liquors start to mix, it becomes harder to determine the actual alcohol content of the drink. Disclosing this information on menus could help less experienced bar patrons have a better understanding of what’s on offer.
Here’s a function that gets the total alcohol content of a group of alcohols (assuming the density of most alcohols is about 1 g/mL, the density of water):
In[]:=
totalAlcoholContent[ingredients_Association]:=Module[{approxDensity,alcoholContents},approxDensity=Quantity[1,"GramsPerMilliliter"];alcoholContents=KeyValueMap[#1["RelativeAlcoholContent"]*approxDensity*UnitConvert[#2,"Milliliters"]&]@ingredients;If[AnyTrue[alcoholContents,!FreeQ[#,_Missing]&],Missing["NotAvailable"],Plus@@alcoholContents]];
Let’s apply this function to a whiskey sour and a gin martini to compare the total alcohol content for these mixed drinks. A whiskey sour is often made with 2 fl oz of whiskey, and a classic gin martini can include 2 fl oz of gin and 1 fl oz of dry vermouth.
In[]:=
whiskeySour=<|
->Quantity[2,"FluidOunces"]|>;ginMartini=<|
->Quantity[2,"FluidOunces"],
->Quantity[1,"FluidOunces"]|>;
| |||||
|
| |||||
|
| |||||
|
In[]:=
totalAlcoholContent[ginMartini]
Out[]=
30.0319
g
In[]:=
totalAlcoholContent[whiskeySour]
Out[]=
25.4332
g
In this example, the martini has a higher total alcohol content than the whiskey sour. But we are leaving the most important question for you to decide — shaken or stirred?
Counting Calories
Counting Calories
If you count calories, have you ever wondered whether red wines and white wines differ in calorie content? Or, do all white wines have similar calories? You can create informative plots that answer questions like these.
First, query the “RelativeTotalCaloriesContent” for both red and white wines using EntityValue:
In[]:=
{redWineCalories,whiteWineCalories}=DeleteMissing[EntityValue[EntityList@#,"RelativeTotalCaloriesContent","EntityAssociation"]]&/@
,
;
| ||||||||
|
| ||||||||
|
Create ListPlots to visualize the data:
In[]:=
ListPlot[Sort[redWineCalories],AxesLabel->Automatic,PlotStyle->Red,PlotLabel"Red Wine Calories",LabelStyle->Red]
Out[]=
In[]:=
ListLinePlot[Sort[whiteWineCalories],AxesLabel->Automatic,Filling->Axis,FillingStyle->LinearGradientFilling[{Yellow,Blue},Top],PlotLabel"White Wine Calories",LabelStyle->Blue]
Out[]=
World of Whiskey
World of Whiskey
If you enjoy whiskey, geography or travel, GeoBubbleChart can answer the question, “Where in the world are the whiskey producers?” You come away with an informative visualization and an entertaining tongue-twister.
Query the FoodLocation attribute for all whiskeys in the alcoholic beverages data:
In[]:=
whiskeyLocations=EntityValue
["Entities"],"Location"//Flatten//DeleteMissing;
| |||||
|
Use Interpreter to get the GeoPositions that correspond to the FoodLocation entities:
In[]:=
geoPositionLookupWhiskey=AssociationMap[Interpreter["Location"][#["Name"]]&,Union[whiskeyLocations]];
Tally the GeoPositions and then plot them on a GeoBubbleChart to visualize the data:
In[]:=
locationTallyWhiskey=Tally[Map[Lookup[geoPositionLookupWhiskey,#]&,whiskeyLocations]];GeoBubbleChart[locationTallyWhiskey,GeoRange->"World"]
Out[]=
According to the data, the most common locations for whiskey producers are Kentucky, Tennessee, Scotland and Ireland, with less prolific whiskey producers in Canada and Japan. In this way, you could make sure that whiskeys from all around the world are represented in your home collection and explore the different flavors produced across different regions.
You can reuse the code above to produce more GeoBubbleCharts and discover where alcohol FoodTypes “Rum”, “Beer” and “Vodka” are produced globally.
Wine or Beer?
Wine or Beer?
Machine learning and neural networks are prevalent in our everyday lives. You can apply Wolfram Language machine learning to the alcoholic beverages data. Use Classify to train a neural network to distinguish wines from beers based on relative alcohol content.
In[]:=
allWineAlcoholContent=EntityValue
["Entities"],"RelativeAlcoholContent","EntityAssociation"//DeleteMissing;
| |||||
|
In[]:=
allBeerAlcoholContent=EntityValue
["Entities"],"RelativeAlcoholContent","EntityAssociation"//DeleteMissing;
| |||||
|
We split the data obtained from EntityValue into a training set (80% of the available data) and a testing set, to make sure we can tell how well our ClassifierFunction works on values it hasn’t seen before:
In[]:=
winesDataSplit=With[{lengthWines=Length[allWineAlcoholContent]},<|"TrainingSet"->#[[;;Round[0.8*lengthWines]]],"TestingSet"->#[[Round[0.8*lengthWines]+1;;]]|>&@Normal[allWineAlcoholContent]];beersDataSplit=With[{lengthBeers=Length[allBeerAlcoholContent]},<|"TrainingSet"->#[[;;Round[0.8*lengthBeers]]],"TestingSet"->#[[Round[0.8*lengthBeers]+1;;]]|>&@Normal[allBeerAlcoholContent]];allData=AssociationThread[{"Wines","Beers"},{winesDataSplit,beersDataSplit}];
Create the ClassifierFunction:
In[]:=
alcoholClassify=Classify[<|"Wine"->Values[allData["Wines"]["TrainingSet"]],"Beer"->Values[allData["Beers"]["TrainingSet"]]|>]
Out[]=
ClassifierFunction
|
Classify a subset of the testing set data we reserved earlier:
In[]:=
randomBeveragesAlcoholContent=Association@RandomSample[Flatten[RandomSample[allData[#]["TestingSet"],10]&/@{"Wines","Beers"}]]
Out[]=
,,,,,,,,,,,,,,,,,,,
SweetWater Brewing Company 420 Extra Pale Ale
0.057
g/g
Sixpoint Sweet Action Pale Ale
0.05
g/g
Tenuta San Guido Le Difese 2018
0.14
g/g
White wine, sweet
(EuroFIR: GB)
0.102
g/g
Shafer Relentless 2016
0.158
g/g
Sloop Brewing Company Sabro Bomb
0.065
g/g
Vipra Rosso Dolce - Sweet Red
0.07
g/g
Tröegs Sunshine Pilsner
0.045
g/g
Twenty Bench Cabernet Sauvignon 2017
0.137
g/g
Tenet Wines The Pundit Syrah 2016
0.145
g/g
Victoria Lager
0.04
g/g
Tilia Malbec 2018
0.135
g/g
Talbott Logan Pinot Noir 2016
0.142
g/g
The Alementary Brewing Co. Magellan Pale Ale
0.055
g/g
Southern Tier Brewing Company Pumking Imperial Ale
0.086
g/g
Tom Gore Cabernet Sauvignon 2018
0.135
g/g
Yards Brewing Company IPA
0.07
g/g
St. Pauli Girl Lager
0.05
g/g
Taylor Dry Sherry
0.18
g/g
Zero Gravity Green State Lager
0.049
g/g
In[]:=
alcoholsClassified=alcoholClassify/@randomBeveragesAlcoholContent;
In[]:=
niceGrid=ResourceFunction["NiceGrid"];niceGrid@alcoholsClassified
Out[]=
SweetWater Brewing Company 420 Extra Pale Ale | Beer |
Sixpoint Sweet Action Pale Ale | Beer |
Tenuta San Guido Le Difese 2018 | Wine |
White wine, sweet (EuroFIR: GB) | Wine |
Shafer Relentless 2016 | Wine |
Sloop Brewing Company Sabro Bomb | Beer |
Vipra Rosso Dolce - Sweet Red | Beer |
Tröegs Sunshine Pilsner | Beer |
Twenty Bench Cabernet Sauvignon 2017 | Wine |
Tenet Wines The Pundit Syrah 2016 | Wine |
Victoria Lager | Beer |
Tilia Malbec 2018 | Wine |
Talbott Logan Pinot Noir 2016 | Wine |
The Alementary Brewing Co. Magellan Pale Ale | Beer |
Southern Tier Brewing Company Pumking Imperial Ale | Beer |
Tom Gore Cabernet Sauvignon 2018 | Wine |
Yards Brewing Company IPA | Beer |
St. Pauli Girl Lager | Beer |
Taylor Dry Sherry | Wine |
Zero Gravity Green State Lager | Beer |
Flavorful Fruits
Flavorful Fruits
The alcoholic beverages available via Wolfram Language are full of flavors. Several functions give you the ability to explore and visualize the data.
In[]:=
| ||||||||
|
Out[]=
Absolut Citron Vodka |
Grey Goose Vodka Le Citron |
Hangar One Citron Buddha's Hand Vodka |
Ketel One Citroen |
New Amsterdam Lemon Vodka |
Stolichnaya Citros |
Svedka Citron Vodka |
You can continue to explore vodka flavors, like “Mango,” “Peach” and “Coconut.”
Use Manipulate to investigate other flavored alcoholic beverages:
In[]:=
allAlcoholFlavors=EntityValue
["Entities"],"Flavor"//Flatten//DeleteCases#,
&;mostCommonAlcoholFlavors=Tally[allAlcoholFlavors]//ReverseSortBy[Last]//Take[#,10]&//Map[First];
| |||||
|
flavored | FLAVOR |
In[]:=
Entity["Food",{EntityProperty["Food","FoodTypeGroup"]->Entity["FoodTypeGroup","AlcoholicBeverages"],EntityProperty["Food","AddedFoodTypes"]->ContainsExactly[{}],EntityProperty["Food","Flavor"]->Entity["FoodFlavor","Coffee"]}]
Out[]=
| ||||
|
In[]:=
Manipulate[With[{attributedFood=Entity["Food",{EntityProperty["Food","FoodTypeGroup"]->Entity["FoodTypeGroup","AlcoholicBeverages"],EntityProperty["Food","AddedFoodTypes"]->ContainsExactly[{}],EntityProperty["Food","Flavor"]->flavor}]},niceGrid[{{"Food",attributedFood},{"FoodTypes",Column@Intersection[EntityValue[attributedFood,"FoodType"],EntityValue[Entity["FoodTypeGroup","AlcoholicBeverages"],"FoodTypes"]]},{"Calories",EntityValue[attributedFood,"RelativeTotalCaloriesContent"]}}]],{flavor,mostCommonAlcoholFlavors},SaveDefinitions->True]
Out[]=
| |||||
|
In[]:=
Length[EntityList@Entity["Food",{EntityProperty["Food","Flavor"]->Entity["FoodFlavor","Grapefruit"]}]]
Out[]=
77
In[]:=
RandomSample[EntityValue["FoodFlavor","Entities"],10]
Out[]=
,,,,,,,,,
pear
grape
chocolate chip cookie dough
bruschetta
cashew
cocoa
smoked
bear foot brownie
coffee
ora gingernge
Flavors in Focus
Flavors in Focus
Wolfram Language can visualize data in many different ways. ImageCollage can tell your data story in full color.
In[]:=
vodkaFlavors=DeleteMissingEntityValue
["Entities"],"Flavor"//Flatten;
| |||||
|
Find the images corresponding to the vodka FoodFlavor entities:
In[]:=
vodkaFlavorsNames=EntityValue[vodkaFlavors,"Name"];
In[]:=
flavorToImageLookup=AssociationMap[(Interpreter["FoodType"][#])["Image"]&,Union[vodkaFlavorsNames]]//DeleteMissing;
Use ImageCollage and Scaled to create a visualization of the most common flavors among vodkas in Wolfram Language alcoholic beverages data:
In[]:=
imagesWithWeights=Map[Scaled[#[[2]]]->Lookup[flavorToImageLookup,#[[1]],Missing[]]&,Tally[vodkaFlavorsNames]]//DeleteMissing[#,1,2]&;ImageCollage[imagesWithWeights,ImagePadding->2,Background->GrayLevel[0.9]]
Out[]=
From this image, we can quickly see that citrus fruits are among the most popular vodka flavors, as well as strawberry, cherry, raspberry, cucumber and coconut. The data reveals some surprising flavors like pumpkin, dragon fruit, espresso and caramel.
WordCloud also provides an interesting weighted visualization of the most common vodka flavors:
In[]:=
WordCloud[vodkaFlavorsNames]
Out[]=
A Parting Toast
A Parting Toast
I have enjoyed sharing some of the innovative ways you can analyze and visualize the wide range of alcoholic beverages data now available. I hope you continue to explore Wolfram Language food and beverage data and that you share your exploration with us. (And if you drink, please don’t drive. Arrange a designated driver.) Here’s to our wonderful Wolfram Community:
In[]:=
WordTranslation["cheers","English"->All]
Out[]=
{salud},{saúde},乾杯,乾盃,喝采,{à votre santé,santé,à la vôtre,à la bonne vôtre},{prost,prosit},{salute,alla salute,cin cin},{proost},{skål}
Spanish
Portuguese
Japanese
French
German
Italian
Dutch
Swedish
Cite this as: Isabel Skidmore, "A Computational Exploration of Alcoholic Beverages" from the Notebook Archive (2022), https://notebookarchive.org/2022-10-2cq1l0a
Download