Difference between revisions of "Recipe/Tool"

From Open Food Facts wiki
Jump to navigation Jump to search
Line 53: Line 53:
 
This contains a lot of vegetables, which will have similar nutrient profiles, so there is the potential for a wide variance. Including carbohydrates in the analysis gives some improvement.
 
This contains a lot of vegetables, which will have similar nutrient profiles, so there is the potential for a wide variance. Including carbohydrates in the analysis gives some improvement.
  
=== Haricots Verts 100G environ 25 cal ([[/world.openfoodfacts.org/product/3083681094923|3083681094923]]) ===
+
=== [https://nl.openfoodfacts.org/product/3083681094923/haricots-verts-100g-environ-25-cal-cassegrain Haricots Verts 100G environ 25 cal] ===
 
This massively overestimates the salt. I think this is because the fat content is so low, so the current penalty gradient function is over weighting it. May want to consider having specific penalty gradients per nutrient (removing it fixes the problem for this specific recipe)
 
This massively overestimates the salt. I think this is because the fat content is so low, so the current penalty gradient function is over weighting it. May want to consider having specific penalty gradients per nutrient (removing it fixes the problem for this specific recipe)
  

Revision as of 10:05, 13 February 2025

The recipe-estimator tool uses optimisation techniques to estimate the proportion of ingredients based on a product's nutritional composition.

Some key areas where the tool has recently been changed include:

  • Using min and max values from Ciqual
  • Adjusting the variance "penalty" to take the above into account (values within the min-max range have a lower relative penalty than those outside the range).
  • Unknown ingredients (with no Ciqual code or proxy) are giving a min-max range of 0 - 100g per 100g with a nominal value of 0g
  • The Ciqual code is always looked up from the ingredients taxonomy so that this can be changed easily without having to refresh all products
  • Carbohydrates are ignored in the analysis because of the lack of clarity on whether these are net or gross (excluding or including fibre)

The recipe-estimator-metrics tool is then used to compare results with other algorithms (such as the existing Product Opener algorithm). The metrics tool hides any existing known percentages from the model and then compares these knwon percentages against those estimated by the model.

At the moment, however, the receipe-estimator still give worse average differences than the existing approach where the estimate is basically by taking a mid point of the minimum and maximum values that could occur given an ingredient's order in the ingredient list.

The following notes look at specific examples to try and determine why this is happening:

Notes on Ad-hoc Product Review

The receipe-estimator-metrics tools has been run on the fr-1000-some-specified-popular test set which gave an average difference of 26.67

The following is a the result of a quick review of the product_stats.csv table where the number of ingredients with no Ciqual code is zero:

Nut & fruit mix classic (20005726)

This has a much higher estimate for the first ingredient (the raisins) because they are mapped to Ciqual code 13112 (Grape, raw). There is no Ciqual code for raisins.

Mixed nuts (20047238)

Very difficult as all nuts have similar composition. Also en:walnut is currently mapped to 15023 (Walnut, fresh) where it should be 15005 (Walnut, dried, husked)

Röstzwiebeln (20173074)

The issue here is that the oils "huiles végétales (palme, tournesol)" are being parsed as the second and third ingredient, rather than one "second" ingredient with two sub-ingredients. So, the flour, which should be limited to be no more than the combination of both oils, is now being limited to no more than the second (sunflower) oil. There was a recent PR #11251 that addressed something similar, but I think this is a different issue.

Sardinillas en aceite de oliva (20703622)

In this case the recipe estimator comes up with a much lower estimate for the oil. The Ciqual sardine (26065) chosen seems to have a higher fat content than the one used in the product, which means that once the protein nutrient target is reached (which only comes from the sardines) the fat target has also almost been reached so only a small amount of oil is needed to match the nutrients.

It may be that calculating a min and max for each ingredient could mitigate this, but the "best estimate" would still remain the same.

Nuts Royal (20816445)

This also has the issue with en:walnut being mapped to a fresh, rather than dried, walnut. Once this is corrected the estimate for Almonds (last ingredient) improves from 0 to 9%, but the overall nutrient difference is slightly worse. This is potentially because each ingredient has a relatively similar nutrient profile, so minor differences in the quality of nut used could significantly affect the results.

Filets de maquereaux Vin blanc et aromates (3019081241216)

This currently over-estimates the Mackerel and underestimates the vegetables. This may be because carbohydrates are currently being ignored (due to differences in reporting net and gross) and because fibre is not quoted, sugars are the only other carbohydrate involved, but they have relatively low quantities so don't influence the results significantly. Also including carbohydrates in the analysis, or increasing the weight of that sugar has on the variance, gives some improvement in the estimate.

Rillettes du Mans - La véritable

In this case the estimator assumes a higher level of pork fat (second ingredient) is needed to meet the nutrient targets. It would appear that the default Ciqual pork used (28205) has a lower fat content than the pork used by the producer. A similar recipe is estimated if "Pork, jowl, rindless, raw" (28471) is used. This shows the variability of some ingredients.

A side-effect of this is that we could potentially help identify the variant / quality of an ingredient based on the stated percentage.

Note that for this estimate the last ingredient (pepper) is higher than the previous one (salt) and the optimiser reports "Inequality constraints incompatible" which requires further investigation. Switching from LinearConstraint to a function based constraint seems to resolve this although the optimisation takes about 3 times longer (from 0.1s to 0.27s)

Excellence 99% Cacao Noir Absolu

In this case the ingredients parser is incorrectly creating a cocoa solids ingredient with a 99% estimate because of the "Cocoa solids: 99% min" claim, whereas this total actually applies to the all of the ingredients, apart from the sugar.

Ratatouille cuisinée à la provençale

This contains a lot of vegetables, which will have similar nutrient profiles, so there is the potential for a wide variance. Including carbohydrates in the analysis gives some improvement.

Haricots Verts 100G environ 25 cal

This massively overestimates the salt. I think this is because the fat content is so low, so the current penalty gradient function is over weighting it. May want to consider having specific penalty gradients per nutrient (removing it fixes the problem for this specific recipe)

Incremental Changes

Used a specific penalty gradient per nutrient. Set to 1 for most ingredients, but 10 for salt.

Average difference improved to 24.99.

Fixed en:walnuts in ingredients.json

Average difference improved to 24.92

Included carbohydrates in the analysis if we don't have separate figures for both sugar and fibre and the product is not sold in the US

Average difference improved to 24.6

Next Steps

  1. Add tolerances for nutrients that don't have min / max values
  2. Calculate average values for unknown ingredients rather than using 0 to 100% range
  3. Consider replacing the constraints with penalty factors. This would allow some latitude in the order of ingredients and all ingredients adding up to 100%. It would also allow other optimisation models to be used, as not all support constraints.
  4. Maybe remove the 100% constraint altogether and just figure out evaporation at the end. Not sure how to deal with order of ingredients though in this case...
  5. Determine min and max for each ingredient. This could be done by adding a penalty to the ingredient that reduces as the ingredient increases in order to estimate the maximum (and vice-versa for minimum). Might only be able to do this if all nutrients are within tolerance
  6. Ingredients parser improvements:
    • Make sure combined oils are grouped as a sub-ingredient
    • don't includes claims like "Cocoa solids: 99% min" in the ingredients list
  7. Allow an ingredient to link to multiple Ciqual codes so the estimator can find the best match, e.g. low or high quality pork
  8. Look for alternative sources of ingredients to cover gaps in Ciqual, e.g. Raisins, uncooked cashews