Skip to content

openfoodfacts/off-product-environmental-impact

Repository files navigation

Test

Environmental impact estimation of Open Food Facts products

This repository contains a Python program to estimate the environmental impact of the agricultural steps of a product of the Open Food Facts database.

✔️ What this tool does

This tool gives an estimation of the environmental impact of the agricultural steps of a product by browsing its possible recipes according to its ingredient list and nutritional composition.

❌ What this tool does NOT do

  • Giving the exact environmental impact of a product
  • Taking into account the origin of the ingredients
  • Taking into account the packaging of the product
  • Making a complete Life Cycle Assessment of the product
  • Reverse engineering the recipe of the product

Installation

This program uses the PySCIPOpt package and the SCIP Optimization Suite V7.0. Installation instructions can be found here (PySCIPOpt) and here (SCIP).

See requirements.txt for the other required Python packages.

Usage

Impact estimation of a product can be done using impacts_estimation.estimate_impacts().

from impacts_estimation import estimate_impacts
from openfoodfacts import get_product

product = get_product(barcode='3175681790285')['product']

impact_categories = ['EF single score',
                     'Climate change']

impact_estimation_result = estimate_impacts(product=product,
                                            impact_names=impact_categories)

for impact_category in impact_categories:
    print(f"{impact_category}: "
          f"{impact_estimation_result['impacts_geom_means'][impact_category]:.4} "
          f"{impact_estimation_result['impacts_units'][impact_category]}")
# EF single score: 0.03832 mPt
# Climate change: 0.3819 kg CO2 eq

If safe_mode is set to True, it will change the parameters in case of error to ensure getting a result.

from impacts_estimation import estimate_impacts, RecipeCreationError
from openfoodfacts import get_product

product = get_product(barcode='3564707104920')['product']

try:
    impact_estimation_result = estimate_impacts(product=product,
                                                impact_names='EF single score',
                                                safe_mode=False)
except RecipeCreationError:
    print("No possible recipe with the given input data.")
# No possible recipe with the given input data.

impact_estimation_result = estimate_impacts(product=product,
                                            impact_names='EF single score',
                                            safe_mode=True)

print(impact_estimation_result['impacts_geom_means']['EF single score'])
# 0.16486248336651319

print(impact_estimation_result['warnings'])
# ['from impacts_estimation import estimate_impacts, RecipeCreationError
from openfoodfacts import get_product

product = get_product(barcode='3564707104920')['product']

try:
    impact_estimation_result = estimate_impacts(product=product,
                                                impact_names='EF single score',
                                                safe_mode=False)
except RecipeCreationError:
    print("No possible recipe with the given input data.")
# No possible recipe with the given input data.

impact_estimation_result = estimate_impacts(product=product,
                                            impact_names='EF single score',
                                            safe_mode=True)

print(impact_estimation_result['impacts_geom_means']['EF single score'])
# 0.050604882643004834

print(impact_estimation_result['warnings'])
# ['Parameter use_defined_prct has been set to False in order to get a result.']']

The reporting module can be used to create HTML impact estimation reports.

from reporting import ProductImpactReport

reporter = ProductImpactReport(barcode='3292590830953')

reporter.to_html()

Parameters

The function impacts_estimation.estimate_impacts() accepts the following parameters:

Parameter Type Default Description
product dict Open Food Facts product to analyze
impact_names string or iterable Names of the impacts to compute in French or in English. They must correspond to the impact categories used by Agribalyse. See list of available impact categories.
quantity float 100 Quantity of product in grams for which the impact must be calculated. If None, will use the 'product_quantity' attribute of the product. If 'product_quantity' is undefined, will use 100g by default.
ignore_unknown_ingredients bool True Should ingredients absent of OFF taxonomy and without defined percentage be considered as parsing errors and ignored?
min_run_nb int 30 Minimum number of run for the Monte-Carlo loop
max_run_nb int 1000 Maximum number of run for the Monte-Carlo loop
forced_run_nb int None Used to bypass natural Monte-Carlo stopping criteria and force the number of runs
confidence_interval_width float 0.05 Width of the confidence interval that will determine the convergence detection. See documentation for more information.
confidence_level float 0.95 Confidence level of the confidence interval.
use_nutritional_info bool True Should nutritional information be used to estimate recipe?
maximum_evaporation float 0.8 Upper bound of the evaporation coefficient [0-1[. I.e. maximum proportion of ingredients water that can evaporate.
total_mass_used float None Total mass of ingredient used in grams, if known.
min_prct_dist_size int 30 Minimum size of the reference ingredients percentage distribution that will be used to pick a proportion for an ingredient. If the distribution (adjusted to the possible value interval) has less data, uniform distribution will be used instead. See documentation for more information.
dual_gap_type str 'absolute' 'absolute' or 'relative'. Determines the precision type of the variable optimization by the solver.
dual_gap_limit float 0.001 Determines the precision of the variable optimization by the solver. Relative or absolute according to dual_gap_type.
solver_time_limit float 60 Maximum time for the solver optimization (in seconds). Set to None or 0 to set no limit.
time_limit_dual_gap_limit float 0.01 Accepted precision of the solver in case of time limit hit. Relative or absolute according to dual_gap_type
use_ingredients_impact_uncertainty bool True Should ingredients impacts uncertainty data be used?
confidence_weighting bool True Should the recipes be weighted by their confidence score (deviation of the recipes nutritional composition to the reference product's nutritional composition). See documentation for more information.
quantiles_points iterable (0.05, 0.25, 0.5, 0.75, 0.95) List of impacts quantiles cutting points to return in the result.
distributions_as_result bool False Should the recipes, the distributions of their impacts, the mean confidence interval and the confidence score be added to the result?
confidence_score_weighting_factor float 10 Weighting factor used for the confidence score calculation. It corresponds to the weight of the nutritional distance against the absolute difference between the total mass and 100g/100g. See documentation for more information.
safe_mode bool True If set to True, the constraints will be progressively relaxed in order to get a result.

Result

The result of impacts_estimation.estimate_impacts() is a dictionary containing the calculated impacts as well as several additional data.

Key Description
impact_geom_means Geometric means of the impacts of all sampled recipes in each impact category. The main result.
impact_geom_stdevs Geometric standard deviations of the impacts of all sampled recipes in each impact category.
impacts_quantiles Quantiles of the impacts of all sampled recipes in each impact category. Cutting points are defined by quantiles_points.
impacts_relative_interquartile Relative interquartile of the impacts of all sampled recipes in each impact category. Useful to estimate the spread of the possible impact.
ingredients_impact_share Average share of the impact carried by each ingredient for each impact category.
impacts_units Units in which the impacts are expressed.
product_quantity Quantity of product in grams for which the impact have been calculated.
warnings List of possible text warnings.
ignored_unknown_ingredients List of ingredients that have been ignored if ignore_unknown_ingredients have been set to True.
uncharacterized_ingredients List of ingredients with no data about nutrition and/or environmental impact.
uncharacterized_ingredients_ratio Ratio ingredients with no data about nutrition and/or environmental impact.
uncharacterized_ingredients_mass_proportion Average mass proportion of ingredients with no data about nutrition and/or environmental impact.
number_of_runs Number of runs before impact convergence.
number_of_ingredients Number of ingredients of the product.
calculation_time Impact calculation time.
impact_distributions Distributions of the impacts of all sampled recipes in each impact category.
mean_confidence_interval_distribution Distributions of the confidence interval of the mean of the impacts of all sampled recipes in each impact category.
confidence_score_distribution Distributions of the confidence score of all sampled recipes.

Available environmental impact categories

The ingredients environmental impact data come from Agribalyse. The impact categories are:

French name English name
Score unique EF EF single score
Changement climatique Climate change
Appauvrissement de la couche d'ozone Ozone depletion
Rayonnements ionisants Ionizing radiations
Formation photochimique d'ozone Photochemical ozone formation
Particules Particulate matter
Acidification terrestre et eaux douces Terrestrial and freshwater acidification
Eutrophisation terreste Terrestrial eutrophication
Eutrophisation eaux douces Freshwater eutrophication
Eutrophisation marine Marine eutrophication
Utilisation du sol Land use
Écotoxicité pour écosystèmes aquatiques d'eau douce Freshwater ecotoxicity
Épuisement des ressources eau Water depletion
Épuisement des ressources énergétiques Resource use, energy carriers
Épuisement des ressources minéraux Resource use, minerals and metals

Algorithm

The algorithm used by this program is based on a Monte-Carlo approach to estimate the impact of a product. Its principle is to pick random possible recipes of the product and compute their impact until the geometric mean of the impacts of all sampled recipes stabilizes within a given confidence interval. The sampling of possible recipes is made as accurate as possible by using a non-linear programming solver (SCIP), and nutritional information of the product.

Documentation

off-product-environmental-impact.readthedocs.io

See the analysis directory for an analysis of the precision of this tool.

Contributing

For contribution guidelines, please see CONTRIBUTING.md.

Testing

This project can be tested using pytest on the automated tests contained in the /tests/ directory.

Disclaimer

The results given by this tool are estimates of the environmental impact of a food product. These estimates are subject to potential bias and uncertainties due to the stochastic nature of the algorithm and the uncertainty inherent to the background data. Thus, the accuracy of the result cannot be guaranteed.

Hardware compatibility issues

Hardware compatibility issue have been observed for this software on a 2012 MacBook Pro (2.5 GHz Dual-Core Intel Core i5) running macOS Catalina.

References

ADEME - Agribalyse, 2020

Anses - Table de composition nutritionnelle des aliments Ciqual, 2020

Santé Canada - Fichier canadien sur les éléments nutritifs , 2015

The SCIP Optimization Suite