Ty Scales

Open Nutrition Dataset

If you went to the grocery store and copied each product’s food label, you’d end up with something like the Open Nutrition dataset. Open Nutrition sources from other public datasets, like FoodData Central.

Nutrients in the dataset are normalized to per 100G. This makes it easy to write a query to find out which products are offering the most caffeine.

import csv
import json

with open("data/data.tsv", "r", encoding="utf-8") as tsv_file:
    reader = csv.DictReader(tsv_file, delimiter='\t')

    caffeine_products = []
    for row in reader:
        nutrients = row['nutrition_100g']
        d = json.loads(nutrients)
        if "caffeine" in d:
            caffeine_products.append((row['name'], d["caffeine"]))

    most_caffeine = sorted(caffeine_products, key=lambda x: x[1], reverse = True)
('Soda by Double-Cola Company (Usa)', 10000)
('Instant Green Tea', 3500)
('Energy Sticks by Alani Nu', 3450)
('Alani Energy Sticks by Alani Nu', 3450)
('Matcha', 3200)
('Instant Black Tea', 3000)
('British Blend Black Tea by Tetley', 2217.7419)
('Low Caffeine Instant Coffee', 1571)
('Southern Iced Tea by Luzianne', 714.2857)
('Coffee Extract', 600)
('Perk Energy by Funtastik', 455)
('Café de Olla', 400)
("Espresso, Single Shot by Dunkin'", 393.3333)
("Espresso, Double Shot by Dunkin'", 393.3333)
('Sweetened Mocha Coffee Mix', 360)
('Sweetened Instant Coffee', 303)
('Espresso, Double Shot by Krispy Kreme', 250)
('Espresso, Single Shot by Krispy Kreme', 250)
('Espresso Con Panna, Solo by Starbucks', 250)
('Espresso Macchiato, Solo by Starbucks', 250)
('Espresso Macchiato, Doppio by Starbucks', 250)
('Espresso Con Panna, Doppio by Starbucks', 250)
("Natural Unsweetened Cocoa by Hershey's", 240)
("Natural Unsweetened Cocoa Powder by Hershey's", 240)
('Organic Cacao Powder by Betterbody Foods', 240)

right away we see some outliers, which I suspect is junk data or has been calculated differently from the others (perhaps as a bulk product rather than individual serving).

Here is the same query for added sugars

('Nuun Instant Watermelon by Nuun', 500)
('Pine River Dairy Fudge by Pine River Pre-Pack', 300)
('Nutrition Shake Plus by Food Club', 250)
('Reddi Wip Dairy Whipped Topping by Egg Beaters', 240)
('Raw Manuka Honey by Manuka Health', 240)
('Caffe Latte Specialty Coffee Beverage by Starbucks', 188)
('Strawberry Nutrition Shake by Food Club', 175)
('Chocolate Pediatric Shake by Food Club', 175)
('Rice Whip by Tofutown North America', 167)
('Stevia & Monk Fruit Sweetner by Pure Via', 167)
('Cinnamon Flavored Mints by 365 Everyday Value', 149)
('Peppermint Naturally Flavored Mints by 365 Everyday Value', 149)
('Wintergreen Mints by Altoids', 143)
('Cinnamon Curiously Strong Mints by Altoids', 143)
("Curiously Strong Mints by Wrigley's", 143)
("Curiously Strong Mints by Wrigley's", 143)
('Caramel Sauce', 140)
('Pediasure by Rib Rack', 140)
('All Purpose Seasoning by Grace', 133)
("Mango Kombucha by GT's", 125)
('Organic Stevia Blend by Sugar In The Raw', 125)
('Organic Stevia in the Raw by Sugar In The Raw', 125)
('Equal Plus by Equal', 125)
('Orange Crystallized Orange by True Citrus Co.', 125)
('Bananaberry Drinkable Yogurt by Yo Gusto', 125)

We can make a rough estimate of nutritionally similar products using Euclidean distance. Here is an example for Red Bull.

def compute_distance(a, b, keys):
    return math.sqrt(sum((float(a.get(k, 0) or 0) - float(b.get(k, 0) or 0)) ** 2 for k in keys))

def findSimilarProducts(reference, data):
    reference_nutrients = json.loads(reference['nutrition_100g'])
    all_keys = set()
    # get all unique keys in the dataset.
    for item in data:
        nt = json.loads(item['nutrition_100g'])
        all_keys.update(nt.keys())

    distances = []
    for product in data:
        if product['id'] == reference['id']:
            continue
        product_nutrients = json.loads(product['nutrition_100g'])
        dist = compute_distance(reference_nutrients, product_nutrients, all_keys)
        distances.append((dist, product['name']))
    return sorted(distances, key=lambda x: x[0])

if __name__ == '__main__':
    with open("data/data.tsv", "r", encoding="utf-8") as tsv_file:
        reader = csv.DictReader(tsv_file, delimiter='\t')
        data = list(reader)

        redbull = None
        for product in data:
            # Red Bull Product Id
            if product['id'] == 'fd_AN091iY8O6rZ':
                redbull = product
        res = findSimilarProducts(redbull, data, 10)
        for i in res[:25]:
            print(i)

Here are the top 25, a lower score indicates a closer similiarity in nutrition.

(46.61261566893666, 'Diddy on the Beach by TGI Fridays')
(62.355189037962184, 'Strawberry Watermelon Energy Drink by Prime')
(77.14704501800442, 'Red Bull Passion Slush by TGI Fridays')
(77.30601533587149, 'Herbal Energy Drink')
(78.00579800751993, 'Sparkling Mango Passionfruit Energy Drink by Celsius')
(78.16809589538433, 'Arctic Vibe Frozen Berry Energy Drink by Celsius')
(78.2168620631127, 'Sparkling Wild Berry Energy Drink by Celsius')
(78.2168620631127, 'Raspberry Acai Green Tea Energy Drink by Celsius')
(79.90943145399046, 'Energy Original by Monster')
(85.98598702556131, 'Ultra Strawberry Dreams by Monster')
(87.371774527876, 'Ultra Watermelon Zero Sugar by Monster')
(91.9120960534031, 'Ultra Paradise Drink by Monster')
(92.77772608509005, 'Low Carb Energy Drink by Monster')
(95.83332604235335, 'Zero Ultra Energy Drink by Monster')
(98.59415735716797, 'Orange Cream by Ghost')
(98.7099894714309, 'Sour Patch Kids Blue Raspberry Energy Drink by Ghost')
(99.07548993292943, 'Warheads Watermelon Energy Drink by Ghost')
(124.78352109597644, 'Energy Drink')
(275.2666309001329, 'Moules Marinières')
(278.97467308691307, 'Spezi')
(279.04935706111206, 'Blended Strawberry Lemonade, Grande by Starbucks')
(279.0906669774538, "Rainbow Lemonades, 14 fl oz by Applebee's")
(279.0922222570346, "Rainbow Lemonades, Mucho by Applebee's")
(279.198935721127, 'Blended Strawberry Lemonade, Tall by Starbucks')
(279.20756376020694, 'Blended Strawberry Lemonade, Venti by Starbucks')

Perhaps to be expected, most nutrionally similar products to Red Bull are other types of Energy Drinks.