Difference between revisions of "Recipe/Example/Vegetarian lasagne"
(Created page with "[https://world.openfoodfacts.org/product/3270160862702/lasagne-legume-picard This product] will be tested for a recipe. == Data == === Ingredients === These are the listed ing...") |
|||
(125 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
[https://world.openfoodfacts.org/product/3270160862702/lasagne-legume-picard This product] will be tested for a recipe. | [https://world.openfoodfacts.org/product/3270160862702/lasagne-legume-picard This product] will be tested for a recipe. | ||
− | == | + | == Product data == |
=== Ingredients === | === Ingredients === | ||
These are the listed ingredients: | These are the listed ingredients: | ||
Line 8: | Line 8: | ||
[[File:VegetableLasagneNutrients.png|300 px|thumb|center|Nutritional values]] | [[File:VegetableLasagneNutrients.png|300 px|thumb|center|Nutritional values]] | ||
In usable format: | In usable format: | ||
− | (6.2,2.4,13,3.1,1.5,0.49) | + | (6.2,2.4,13,3.1,1.5,5.0,0.49) |
+ | |||
+ | == Ingredients data == | ||
+ | |||
+ | ==== LAIT écrémé réhydraté ==== | ||
+ | Milk, powder, whole (19021) (26.8,17.3,37.5,37.5,0,27.4,0.9) | ||
+ | |||
+ | ==== Champignons de Paris ==== | ||
+ | Button mushroom or cultivated mushroom, raw (20056) (0.36, 0.067, 3.15,2.5,1,2.62,0.098) | ||
+ | |||
+ | ==== Pulpes de tomates ==== | ||
+ | (limits are translated to 0) | ||
+ | Tomato pulp, canned (20169) (0,0,3.63,3.2,1.8,1.2,0.068) | ||
+ | |||
+ | ==== semoule de BLÉ dur (GLUTEN) ==== | ||
+ | Durum wheat semolina, raw (9610) (1.25,0.21,71.6,1,3.37,10.9,0.003) | ||
+ | |||
+ | ==== crème fraîche liquide ==== | ||
+ | |||
+ | Liquid cream 30% fat, UHT (19415) (30.7,21.4,1.94,1.94,0,2.49,0.073) | ||
+ | |||
+ | ==== oignon ==== | ||
+ | Onion, raw (20034) (0.62,0.2,6.25,4.8,1.7,1.1,0.098) | ||
+ | |||
+ | ==== purée de tomate ==== | ||
+ | Tomato puree, canned (20170) (0.4,0.085,7.54,3.64,2.38,1.4,0.51) | ||
+ | ==== OEUF entier de poule élevée en plein air ==== | ||
+ | Egg, raw (22000) (9.83, 2.64, 0.27, 0.27, 0, 12.7, 0.31) | ||
+ | |||
+ | ==== fromage râpé ==== | ||
+ | Emmental cheese, grated, from cow's milk (12118) (28.6, 18.1, 0, 0, 0, 28.1, 0.75) | ||
+ | |||
+ | == Fitting (lm) == | ||
+ | The fitting is done by adding one ingredient at the time and seeing how the variance goes down. The fitting algorithm only forces a fit through (0,0). | ||
+ | {| class="wikitable" | ||
+ | |+ Fitting with lm results | ||
+ | |- | ||
+ | ! #ingredients !! Max residual !! variance !! fractions | ||
+ | |- | ||
+ | | milk || 5.2 (carbs) || 53.78 || 0.21 | ||
+ | |- | ||
+ | | milk, mushroom || 4.6 (carbs) || 49.50 || 0.15, 0.9 | ||
+ | |- | ||
+ | | milk, mushroom, tomato || 4.5 (carbs) || 49.3 || 0.15, 0.67, 0.2 | ||
+ | |- | ||
+ | | milk, mushroom, tomato, semolina || 2.1 (fiber) || 9.15 || 0.16, -0.14, -0.5, 0.13 | ||
+ | |- | ||
+ | | milk, mushroom, tomato, semolina, cream || -1.0 (sat. fat) || 1.8 || 0, 1.5, -0.2, 0.1, 0.16 | ||
+ | |- | ||
+ | | milk, mushroom, tomato, semolina, cream, onion || 0.16 (salt) || 0.027 || -0.4, 6.9, -7.9, 0, 0.3, 5.1 | ||
+ | |- | ||
+ | | milk, mushroom, tomato, semolina, cream, onion, tomato puree || 0 || 0 | ||
+ | |} | ||
+ | With 7 ingredients the solution will be exact. Should we leave out ingredients that are too similar? How to find these? The fractions also become negative, resulting in nonsense solutions. | ||
+ | |||
+ | == Fitting (nnfit) == | ||
+ | The fitting is done by adding one ingredient at the time and seeing how the variance goes down. The fitting algorithm forces positive fractions only. | ||
+ | {| class="wikitable" | ||
+ | |+ Fitting iterations | ||
+ | |- | ||
+ | ! #ingredients !! Max residual !! variance !! fractions | ||
+ | |- | ||
+ | | milk || 5.2 (carbs) || 53.78 || 0.21 | ||
+ | |- | ||
+ | | milk, mushroom || 4.6 (carbs) || 49.50 || 0.15, 0.90 | ||
+ | |- | ||
+ | | milk, mushroom, tomato || 4.5 (carbs) || 49.3 || 0.15, 0.67, 0.2 | ||
+ | |- | ||
+ | | milk, mushroom, tomato, semolina || 2.6 (fat) || 11.6 || 0.13, 0, 0, 0.11 | ||
+ | |- | ||
+ | | milk, mushroom, tomato, semolina, cream || -1.0 (sat. fat) || 2.0 || 0, 1.2, 0, 0.13, 0.16 | ||
+ | |- | ||
+ | | milk, mushroom, tomato, semolina, cream, onion || 1.1 (sat.fat) || 2.0 || 0, 1.16, 0, 0.13, 0.16, 0 | ||
+ | |} | ||
+ | |||
+ | == Fitting (nnfit) + removal == | ||
+ | The fitting is done by adding one ingredient at the time and seeing how the variance goes down. The fitting algorithm forces positive fractions only. Ingredients that are 0 will be remove if they replaced by another ingredient. | ||
+ | {| class="wikitable" | ||
+ | |+ Fitting iterations | ||
+ | |- | ||
+ | ! #ingredients !! Max residual !! variance !! fractions | ||
+ | |- | ||
+ | | milk || 5.2 (carbs) || 53.78 || 0.21 | ||
+ | |- | ||
+ | | milk, mushroom || 4.6 (carbs) || 49.50 || 0.15, 0.90 | ||
+ | |- | ||
+ | | milk, mushroom, tomato || 4.5 (carbs) || 49.3 || 0.15, 0.67, 0.2 | ||
+ | |- | ||
+ | | milk, mushroom, semolina || 2.6 (fat) || 11.6 || 0.13, 0, 0.11 | ||
+ | |- | ||
+ | | mushroom, semolina, cream || -1.0 (sat. fat) || 2.0 || 1.16, 0.13, 0.16 | ||
+ | |- | ||
+ | | mushroom, semolina, cream, egg || -0.9 (sat.fat) || 1.50 || 0.99, 1.33, 0.14, 0.07 | ||
+ | |} | ||
+ | |||
+ | Replacements: | ||
+ | * milk -> cream | ||
+ | * tomato -> mushroom | ||
+ | |||
+ | Try another cream: | ||
+ | Thick cream 30% fat, refrigerated (19410) (30.7, 21.4, 1.94, 1.94, 0, 2.49, 0.073) | ||
+ | {| class="wikitable" | ||
+ | |+ Another cream | ||
+ | |- | ||
+ | ! #ingredients !! Max residual !! variance !! fractions | ||
+ | |- | ||
+ | | mushroom, semolina, creamFat, egg || -0.9 (sat.fat) || 1.50 || 0.99, 1.33, 0.14, 0.07 | ||
+ | |} | ||
+ | Another cream has no impact. | ||
+ | |||
+ | == Ingredient selection == | ||
+ | Which ingredients should be taken into account and which ones not? If the ingredients have a similar nutritional profile, then we cannot distinguish between them. And it will not matter which one to use. Probably the nutritional profiles will be strongly correlated. | ||
+ | |||
+ | So why not start with the ingredients that are least correlated? And those that give the best initial correlation. These are mushroom and egg with a correlation coefficient of 0.05. Then we look 2nd least correlated: cream and milk with a coefficient of 0.15. Egg/Semolina: -0.19. Milk/Egg: 0.26; Semolina/Cream -0.27; | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |+ Fitting 2 ingredients | ||
+ | |- | ||
+ | ! #ingredients !! correlation !! max residual !! variance !! fractions !! comments | ||
+ | |- | ||
+ | | mushroom, egg || 0.05 || 3.82 (fat)|| 67.00 || 2.48,0.15 || mushroom has a large fraction | ||
+ | |- | ||
+ | | milk, cream || 0.15 || 5.1 (carbs) || 53.75 || 0.0, 0.2 || small fractions, but lower variance | ||
+ | |- | ||
+ | | egg, semolina || -0.19 || 2.8 (sugar) || 18.8 || 0.40, 0.18 || better variance | ||
+ | |- | ||
+ | | milk, egg || 0.26 || -5.0 (carbs) || 53.4 || 0.2, -0.04 || negative fraction | ||
+ | |- | ||
+ | | semolina, cream || -0.27 || 2.6 (sugar) || 16.7 || 0.18, 0.17 || | ||
+ | |} | ||
+ | |||
+ | The correlation is not a great predictor for the first ingredients, but gives a good starting point. | ||
+ | |||
+ | The combinations (egg, semolina) and (semolina, cream) give optimal results (low variance). Can we call these the important nutritional ingredients? | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |+ Fitting 3 ingredients | ||
+ | |- | ||
+ | ! #ingredients !! max residual !! variance !! fractions !! comments | ||
+ | |- | ||
+ | | egg, semolina, cream || 2.6 (sugar) || 8.4 || 0.231, 0.178, 0.111 || low variance | ||
+ | |} | ||
+ | |||
+ | How to find the next ingredient? We are missing sugar as a nutrient. Adding a vegetable? | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |+ Fitting 4 ingredients | ||
+ | |- | ||
+ | ! #ingredients !! max residual !! variance !! fractions !! comments | ||
+ | |- | ||
+ | | egg, semolina, cream, mushroom || 0.6 (fat) || 1.5 || 0.072, 0.133, 0.14, 0.99 || lower variance | ||
+ | |- | ||
+ | | egg, semolina, cream, tomato || -0.7 (sat.fat) || 1.0 || 0.198, 0.138, 0.118, 0.77 || even lower variance | ||
+ | |- | ||
+ | | egg, semolina, cream, onion || -0.5 (sat.fat) || 0.54 || 0.229, 0.127, 0.100, 0.576 || and even lower variance | ||
+ | |- | ||
+ | | egg, semolina, cream, tomato puree || -0.5 (sat.fat) || 0.75 || 0.222, 0.106, 0.106, 0.679 || | ||
+ | |} | ||
+ | The better fit is given by adding onion | ||
+ | |||
+ | Can we do better than four ingredients? The largest residuals are for saturated fat and fiber. | ||
+ | {| class="wikitable" | ||
+ | |+ Fitting 5 ingredients | ||
+ | |- | ||
+ | ! #ingredients !! max residual !! variance !! fractions !! comments | ||
+ | |- | ||
+ | | egg, semolina, cream, onion, tomato puree || -0.5 (sat.fat) || 0.49 || 0.227, 0.120, 0.102, 0.411, 0.204 || | ||
+ | |- | ||
+ | | egg, semolina, cream, onion, mushroom || - || - || - || gives a negative fraction | ||
+ | |- | ||
+ | | egg, semolina, cream, onion, tomato || - || - || - || gives a negative fraction | ||
+ | |- | ||
+ | | egg, semolina, cream, onion, milk powder || - || - || - || gives a negative fraction | ||
+ | |} | ||
+ | So only tomato puree has a positive impact. | ||
+ | |||
+ | Probably no other ingredient can further be added. | ||
+ | |||
+ | Note that the egg fraction is much too large, much larger than what is found on the ingredient list. It should not be there. So what could replace the eggs? | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |+ Fitting Ingredients incl. cheese | ||
+ | |- | ||
+ | ! #ingredients !! max residual !! variance !! fractions !! comments | ||
+ | |- | ||
+ | | cheese, semolina, cream, onion, tomato puree || -1.0 (sat.fat) || 1.6 || 0.10, 0.12, 0.07, 0.47, 0.17 || | ||
+ | |- | ||
+ | | cheese, semolina, cream, onion, tomato puree, olive oil || 0.28 (salt) || 0.09 || 0.10, 0.12, 0.0, 0.49, 0.16, 0.03 || | ||
+ | |} | ||
+ | |||
+ | == Milk == | ||
+ | In the ingredient list milk is the first ingredient. In the calculations so far this has been replaced by milk powder, thinking that this would be a proxy for milk. We would need less milk powder than milk. There is about a factor of 8 difference between the two. This would also make milk an insignificant ingredient from a nutritional point of view. | ||
+ | |||
+ | Milk is defined by: | ||
+ | Milk, whole, UHT (19023) (3.63,2.4,4.85,4.2,0,3.32,0.11) | ||
+ | |||
+ | The correlation between milk and milk powder is 0.99. So no need to investigate further. | ||
+ | |||
+ | The correlation between milk powder and cream is only 0.14, so cream cannot be a substitute for cream. | ||
+ | |||
+ | == Carrots == | ||
+ | The carrots in the ingredients have not been used. Would this make a difference? | ||
+ | |||
+ | Carrot, raw (20009) (0,0,7.59,6,2.7,0.63,0.11) | ||
+ | |||
+ | These resemble a lot onions (correlation 0.98) and a bit less tomato puree (corr. 0.95). So if we already use onion, it does not matter. | ||
+ | |||
+ | == Garlic/Ail == | ||
+ | |||
+ | Garlic, fresh (11000) (0,0, 18.6, 1.2, 5.8, 5.31, 0.023) | ||
+ | |||
+ | == Tomate mi-séchée 0,8% == | ||
+ | |||
+ | Tomato, dried (20189) (2.99, 0.46, 48.3, 37.6, 12.3, 14.2, 0.62) | ||
+ | |||
+ | == Order constraints attempt 1== | ||
+ | If we base ourselves only on the nutritional values, eggs will predominate the solution. A solution might be to enforce an order of the coefficients. This is dictated by the ingredient list. | ||
+ | |||
+ | There are multiple ways to approach this. We try to find the best approach. | ||
+ | |||
+ | === Only order constraints === | ||
+ | Using milk, mushroom, semolina, cream and eggs. The amount of milk breaks the constraint (milk/mushroom), it is not able to increase it enough. The amount of mushroom is very large, probably because it i used as a proxy for carrots and tomatoes. This solution has an intercept, so not a valid solution. (see the table under comparisons) | ||
+ | |||
+ | === Order constraints without intercept === | ||
+ | The amount of milk decreases even further and the amount of mushrooms increases | ||
+ | |||
+ | === Ingredient similis === | ||
+ | What ingredients look very similar that we can view them as the same? For this we can look at the correlation of nutritional values of each ingredient: | ||
+ | |||
+ | [[File:VegetarianLasagneIngredientCorrelations.pdf|400px|thumb|center]] | ||
+ | |||
+ | It shows a few similis: (onion, tomatoPuree, carrots), (olive oil, cream) and (egg, cheese). Ingredients with the highest nutrient density are olive oil (fat), semolina (carbohydrates), cheese (proteins), cheese (salt), carrots (sugar, fiber). These can be seem as the drivers for the nutritional values of lasagne. | ||
+ | |||
+ | Can we use this to select the most important ingredients? | ||
+ | * semolina/cream/egg - egg is to large replace with cheese; | ||
+ | * semolina/cream/cheese - seems a better fit, which roughly fulfils the order; | ||
+ | * semolina/carrots/cream/cheese - carrots clearly have a role to play. The largest residuals are for fat and saturated fat. Add the eggs? | ||
+ | * semolina/carrots/cream/cheese/eggs - these makes the fit quality better, but makes the cheese negative. Add olive oil instead? | ||
+ | * semolina/carrots/cream/cheese/oliveOil - these makes the fit quality better. Can I add both oil and egg? -> No makes others negative; | ||
+ | * semolina/onion/carrots/cream/cheese/oliveOil - including onion gives a better, but dominates right away. | ||
+ | |||
+ | === Comparisons === | ||
+ | {| class="wikitable" | ||
+ | |+ Caption text | ||
+ | |- | ||
+ | ! Solver !! Milk !! Mushroom !! Semolina !! Onion !! Carrots !! Cream !! Cheese !! Egg !! Olive oil !! RMSE | ||
+ | |- | ||
+ | | ConsReg (with intercept) || 0.08 || 0.83 || 0.13 || - || - || 0.13 || - || 0.08 || - || - | ||
+ | |- | ||
+ | | ConsReg (without intercept) || 0.04 || 0.94 || 0.13 || - || - || 0.14 || - || 0.07 || - || - | ||
+ | |- | ||
+ | | Semolina/Cream/Egg || - || - || 0.178 || - || - || 0.111 || - || 0.231 || - || - | ||
+ | |- | ||
+ | | Semolina/Cream/Cheese || - || - || 0.181 || - || - || 0.083 || 0.097 || - || - || 1.22 | ||
+ | |- | ||
+ | | Semolina/Carrots/Cream/Cheese || - || - || 0.31 || - || 0.461 || 0.065 || 0.113 || - || - || 0.53 | ||
+ | |- | ||
+ | | Semolina/Carrots/Cream/Cheese/Egg || - || - || 0.131 || - || 0.421 || 0.148 || -0.115 || 0.487 || - || 0.14 | ||
+ | |- | ||
+ | | Semolina/Carrots/Cream/Cheese/OliveOil || - || - || 0.136 || - || 0.474 || 0.003 || 0.106 || - || 0.035 || 0.34 | ||
+ | |- | ||
+ | | Semolina/Onion/Carrots/Cream/Cheese/OliveOil || - || - || 0.112 || 0.66 || 0.045 || 0.0023 || 0.119 || - || 0.020 || 0.30 | ||
+ | |} | ||
+ | |||
+ | === Order constraints Attempt 2 === | ||
+ | In this attempt I rewrote the functions, which must be minimised. This results in a hard order. It used the nnls function in Rstudio. | ||
+ | {| class="wikitable" | ||
+ | |+ Adding an ingredient one at the time | ||
+ | |- | ||
+ | ! RMS !! Milk !! Mushroom !! Tomato pulp !! Semolina !! Cream !! Onion !! Tomato puree !! Carrots !! Cheese !! Olive oil !! Grilled onion || Tomato || Farine || Oeuf || Ail || Tomate séchée || Sel | ||
+ | |- | ||
+ | | || - || 12% || 11.7 || - || - || 5.9 || 5.8 || 4.6 || 4.2 || - || 2.9 || 2.9 || - || - || - || 0.8 || - | ||
+ | |- | ||
+ | | 41.01 || 1.31 || 0.76 || - || - || - || - || - || - || - || - || | ||
+ | |- | ||
+ | | 41.01 || 1.31 || 0.76 || 0.00 || - || - || - || - || - || - || - || | ||
+ | |- | ||
+ | | 10.17 || 1.04 || 0.10 || 0.10 || 0.10 || - || - || - || - || - || - || | ||
+ | |- | ||
+ | | 3.16 || 0.425 || 0.425 || 0.125 || 0.125 || 0.115 || - || - || - || - || - || | ||
+ | |- | ||
+ | | 3.16 || 0.425 || 0.425 || 0.125 || 0.125 || 0.115 || 0.00 || - || - || - || - || | ||
+ | |- | ||
+ | | 3.16 || 0.425 || 0.425 || 0.125 || 0.125 || 0.115 || 0.00 || 0.00 || - || - || - || | ||
+ | |- | ||
+ | | 3.16 || 0.425 || 0.425 || 0.125 || 0.125 || 0.115 || 0.00 || 0.00 || 0.00 || - || - || | ||
+ | |- | ||
+ | | 1.87 || 0.158 || 0.158 || 0.158 || 0.129 || 0.081 || 0.081 || 0.081 || 0.081 || 0.073 || - || | ||
+ | |- | ||
+ | | 0.50 || 0.299 || 0.299 || 0.129 || 0.129 || 0.040 || 0.040 || 0.040 || 0.040 || 0.040 || 0.024 || | ||
+ | |- | ||
+ | | 0.50 || 0.145 || 0.145 || 0.129 || 0.129 || 0.041 || 0.041 || 0.041 || 0.041 || 0.041 || 0.024 || 0.015 | ||
+ | |- | ||
+ | | 0.50 || 0.261 || 0.261 || 0.10 || 0.110 || 0.041 || 0.041 || 0.041 || 0.041 || 0.041 || 0.024 || 0.016 || 0.016 | ||
+ | |- | ||
+ | | 0.50 || 0.122 || 0.122 || 0.105 || 0.105 || 0.041 || 0.041 || 0.041 || 0.041 || 0.041 || 0.024 || 0.024 || 0.024 || 0.024 | ||
+ | |- | ||
+ | | 0.29 || 0.283 || 0.283 || 0.105 || 0.105 || 0.034 || 0.034 || 0.034 || 0.034 || 0.034 || 0.026 || 0.026 || 0.026 || 0.026 || 0.026 | ||
+ | |- | ||
+ | | 0.10 || 0.283 || 0.283 || 0.098 || 0.098 || 0.035 || 0.035 || 0.035 || 0.035 || 0.035 || 0.026 || 0.026 || 0.026 || 0.026 || 0.026 || 0.026 || 0.003 || 0.003 | ||
+ | |} | ||
+ | |||
+ | [[File:VegetarianLasagneNutrients2.png|400px|thumb|center|Vegetarian lasagne nutritional values (predicted vs observed)]] | ||
+ | The predicted versus observed values seem pretty close. I do not think we can do better without over-interpreting. | ||
+ | [[File:VegetarianLasagneRecipe.png|400 px|thumb|center|Vegetarian lasagne recipe development]] | ||
+ | The evolution of the recipe when adding ingredients. The total does not seem to evolve. There is only replacement between ingredients. | ||
+ | |||
+ | == Conclusions == | ||
+ | * '''Multiple solutions''' - Just using the ingredients, it is possible to find solutions for the nutritional values of the product. In fact there seems to be more than one solution. Additional information is need to select the best solution; | ||
+ | * '''Single nutrient ingredients''' - It is always possible to find a solution by using single nutrient ingredients, like oil, sugar, salt. This will probably force the wrong recipe; | ||
+ | * '''Similar ingredients''' - some ingredients are very similar from a nutritional point of view. These ingredients have a high correlation (> 0.9). These ingredients should be handled as one ingredient. The fitting approach can not distinguish between these ingredients; | ||
+ | * '''Maximum number of ingredients''' - if a free fit is done, then the maximum number of ingredients needed is 7, for 7 nutrients. It will be a system of 7 equations with 7 unknowns. If we you use the forced origin fit, we could get more ingredients mathematically, but il will not have any meaning; | ||
+ | * '''Constraints''' - These are really required to get a good coverage of all ingredients, whilst also getting good results. | ||
+ | |||
+ | |||
+ | [[Category:Recipe]] |
Latest revision as of 08:58, 12 February 2025
This product will be tested for a recipe.
Product data
Ingredients
These are the listed ingredients:
LAIT écrémé réhydraté, champignon de Paris 12%, pulpe de tomate 11,7%, semoule de BLÉ dur (GLUTEN), crème fraîche liquide (LAIT), oignon 5,9%, purée de tomate 5,8%, carotte 4,6%, fromage râpé (contient LAIT) 4,2%, huile d'olive, oignon grillé 2,9%, tomate 2,9%, farine de BLÉ (GLUTEN), CEUF entier de poule élevée en plein air (liquide, pasteurisé), ail, tomate mi-séchée 0,8%, sel, eau, basilic, persil, amidon de riz, poivre
Nutrients
In usable format:
(6.2,2.4,13,3.1,1.5,5.0,0.49)
Ingredients data
LAIT écrémé réhydraté
Milk, powder, whole (19021) (26.8,17.3,37.5,37.5,0,27.4,0.9)
Champignons de Paris
Button mushroom or cultivated mushroom, raw (20056) (0.36, 0.067, 3.15,2.5,1,2.62,0.098)
Pulpes de tomates
(limits are translated to 0)
Tomato pulp, canned (20169) (0,0,3.63,3.2,1.8,1.2,0.068)
semoule de BLÉ dur (GLUTEN)
Durum wheat semolina, raw (9610) (1.25,0.21,71.6,1,3.37,10.9,0.003)
crème fraîche liquide
Liquid cream 30% fat, UHT (19415) (30.7,21.4,1.94,1.94,0,2.49,0.073)
oignon
Onion, raw (20034) (0.62,0.2,6.25,4.8,1.7,1.1,0.098)
purée de tomate
Tomato puree, canned (20170) (0.4,0.085,7.54,3.64,2.38,1.4,0.51)
OEUF entier de poule élevée en plein air
Egg, raw (22000) (9.83, 2.64, 0.27, 0.27, 0, 12.7, 0.31)
fromage râpé
Emmental cheese, grated, from cow's milk (12118) (28.6, 18.1, 0, 0, 0, 28.1, 0.75)
Fitting (lm)
The fitting is done by adding one ingredient at the time and seeing how the variance goes down. The fitting algorithm only forces a fit through (0,0).
#ingredients | Max residual | variance | fractions |
---|---|---|---|
milk | 5.2 (carbs) | 53.78 | 0.21 |
milk, mushroom | 4.6 (carbs) | 49.50 | 0.15, 0.9 |
milk, mushroom, tomato | 4.5 (carbs) | 49.3 | 0.15, 0.67, 0.2 |
milk, mushroom, tomato, semolina | 2.1 (fiber) | 9.15 | 0.16, -0.14, -0.5, 0.13 |
milk, mushroom, tomato, semolina, cream | -1.0 (sat. fat) | 1.8 | 0, 1.5, -0.2, 0.1, 0.16 |
milk, mushroom, tomato, semolina, cream, onion | 0.16 (salt) | 0.027 | -0.4, 6.9, -7.9, 0, 0.3, 5.1 |
milk, mushroom, tomato, semolina, cream, onion, tomato puree | 0 | 0 |
With 7 ingredients the solution will be exact. Should we leave out ingredients that are too similar? How to find these? The fractions also become negative, resulting in nonsense solutions.
Fitting (nnfit)
The fitting is done by adding one ingredient at the time and seeing how the variance goes down. The fitting algorithm forces positive fractions only.
#ingredients | Max residual | variance | fractions |
---|---|---|---|
milk | 5.2 (carbs) | 53.78 | 0.21 |
milk, mushroom | 4.6 (carbs) | 49.50 | 0.15, 0.90 |
milk, mushroom, tomato | 4.5 (carbs) | 49.3 | 0.15, 0.67, 0.2 |
milk, mushroom, tomato, semolina | 2.6 (fat) | 11.6 | 0.13, 0, 0, 0.11 |
milk, mushroom, tomato, semolina, cream | -1.0 (sat. fat) | 2.0 | 0, 1.2, 0, 0.13, 0.16 |
milk, mushroom, tomato, semolina, cream, onion | 1.1 (sat.fat) | 2.0 | 0, 1.16, 0, 0.13, 0.16, 0 |
Fitting (nnfit) + removal
The fitting is done by adding one ingredient at the time and seeing how the variance goes down. The fitting algorithm forces positive fractions only. Ingredients that are 0 will be remove if they replaced by another ingredient.
#ingredients | Max residual | variance | fractions |
---|---|---|---|
milk | 5.2 (carbs) | 53.78 | 0.21 |
milk, mushroom | 4.6 (carbs) | 49.50 | 0.15, 0.90 |
milk, mushroom, tomato | 4.5 (carbs) | 49.3 | 0.15, 0.67, 0.2 |
milk, mushroom, semolina | 2.6 (fat) | 11.6 | 0.13, 0, 0.11 |
mushroom, semolina, cream | -1.0 (sat. fat) | 2.0 | 1.16, 0.13, 0.16 |
mushroom, semolina, cream, egg | -0.9 (sat.fat) | 1.50 | 0.99, 1.33, 0.14, 0.07 |
Replacements:
- milk -> cream
- tomato -> mushroom
Try another cream:
Thick cream 30% fat, refrigerated (19410) (30.7, 21.4, 1.94, 1.94, 0, 2.49, 0.073)
#ingredients | Max residual | variance | fractions |
---|---|---|---|
mushroom, semolina, creamFat, egg | -0.9 (sat.fat) | 1.50 | 0.99, 1.33, 0.14, 0.07 |
Another cream has no impact.
Ingredient selection
Which ingredients should be taken into account and which ones not? If the ingredients have a similar nutritional profile, then we cannot distinguish between them. And it will not matter which one to use. Probably the nutritional profiles will be strongly correlated.
So why not start with the ingredients that are least correlated? And those that give the best initial correlation. These are mushroom and egg with a correlation coefficient of 0.05. Then we look 2nd least correlated: cream and milk with a coefficient of 0.15. Egg/Semolina: -0.19. Milk/Egg: 0.26; Semolina/Cream -0.27;
#ingredients | correlation | max residual | variance | fractions | comments |
---|---|---|---|---|---|
mushroom, egg | 0.05 | 3.82 (fat) | 67.00 | 2.48,0.15 | mushroom has a large fraction |
milk, cream | 0.15 | 5.1 (carbs) | 53.75 | 0.0, 0.2 | small fractions, but lower variance |
egg, semolina | -0.19 | 2.8 (sugar) | 18.8 | 0.40, 0.18 | better variance |
milk, egg | 0.26 | -5.0 (carbs) | 53.4 | 0.2, -0.04 | negative fraction |
semolina, cream | -0.27 | 2.6 (sugar) | 16.7 | 0.18, 0.17 |
The correlation is not a great predictor for the first ingredients, but gives a good starting point.
The combinations (egg, semolina) and (semolina, cream) give optimal results (low variance). Can we call these the important nutritional ingredients?
#ingredients | max residual | variance | fractions | comments |
---|---|---|---|---|
egg, semolina, cream | 2.6 (sugar) | 8.4 | 0.231, 0.178, 0.111 | low variance |
How to find the next ingredient? We are missing sugar as a nutrient. Adding a vegetable?
#ingredients | max residual | variance | fractions | comments |
---|---|---|---|---|
egg, semolina, cream, mushroom | 0.6 (fat) | 1.5 | 0.072, 0.133, 0.14, 0.99 | lower variance |
egg, semolina, cream, tomato | -0.7 (sat.fat) | 1.0 | 0.198, 0.138, 0.118, 0.77 | even lower variance |
egg, semolina, cream, onion | -0.5 (sat.fat) | 0.54 | 0.229, 0.127, 0.100, 0.576 | and even lower variance |
egg, semolina, cream, tomato puree | -0.5 (sat.fat) | 0.75 | 0.222, 0.106, 0.106, 0.679 |
The better fit is given by adding onion
Can we do better than four ingredients? The largest residuals are for saturated fat and fiber.
#ingredients | max residual | variance | fractions | comments |
---|---|---|---|---|
egg, semolina, cream, onion, tomato puree | -0.5 (sat.fat) | 0.49 | 0.227, 0.120, 0.102, 0.411, 0.204 | |
egg, semolina, cream, onion, mushroom | - | - | - | gives a negative fraction |
egg, semolina, cream, onion, tomato | - | - | - | gives a negative fraction |
egg, semolina, cream, onion, milk powder | - | - | - | gives a negative fraction |
So only tomato puree has a positive impact.
Probably no other ingredient can further be added.
Note that the egg fraction is much too large, much larger than what is found on the ingredient list. It should not be there. So what could replace the eggs?
#ingredients | max residual | variance | fractions | comments |
---|---|---|---|---|
cheese, semolina, cream, onion, tomato puree | -1.0 (sat.fat) | 1.6 | 0.10, 0.12, 0.07, 0.47, 0.17 | |
cheese, semolina, cream, onion, tomato puree, olive oil | 0.28 (salt) | 0.09 | 0.10, 0.12, 0.0, 0.49, 0.16, 0.03 |
Milk
In the ingredient list milk is the first ingredient. In the calculations so far this has been replaced by milk powder, thinking that this would be a proxy for milk. We would need less milk powder than milk. There is about a factor of 8 difference between the two. This would also make milk an insignificant ingredient from a nutritional point of view.
Milk is defined by:
Milk, whole, UHT (19023) (3.63,2.4,4.85,4.2,0,3.32,0.11)
The correlation between milk and milk powder is 0.99. So no need to investigate further.
The correlation between milk powder and cream is only 0.14, so cream cannot be a substitute for cream.
Carrots
The carrots in the ingredients have not been used. Would this make a difference?
Carrot, raw (20009) (0,0,7.59,6,2.7,0.63,0.11)
These resemble a lot onions (correlation 0.98) and a bit less tomato puree (corr. 0.95). So if we already use onion, it does not matter.
Garlic/Ail
Garlic, fresh (11000) (0,0, 18.6, 1.2, 5.8, 5.31, 0.023)
Tomate mi-séchée 0,8%
Tomato, dried (20189) (2.99, 0.46, 48.3, 37.6, 12.3, 14.2, 0.62)
Order constraints attempt 1
If we base ourselves only on the nutritional values, eggs will predominate the solution. A solution might be to enforce an order of the coefficients. This is dictated by the ingredient list.
There are multiple ways to approach this. We try to find the best approach.
Only order constraints
Using milk, mushroom, semolina, cream and eggs. The amount of milk breaks the constraint (milk/mushroom), it is not able to increase it enough. The amount of mushroom is very large, probably because it i used as a proxy for carrots and tomatoes. This solution has an intercept, so not a valid solution. (see the table under comparisons)
Order constraints without intercept
The amount of milk decreases even further and the amount of mushrooms increases
Ingredient similis
What ingredients look very similar that we can view them as the same? For this we can look at the correlation of nutritional values of each ingredient:
File:VegetarianLasagneIngredientCorrelations.pdf
It shows a few similis: (onion, tomatoPuree, carrots), (olive oil, cream) and (egg, cheese). Ingredients with the highest nutrient density are olive oil (fat), semolina (carbohydrates), cheese (proteins), cheese (salt), carrots (sugar, fiber). These can be seem as the drivers for the nutritional values of lasagne.
Can we use this to select the most important ingredients?
- semolina/cream/egg - egg is to large replace with cheese;
- semolina/cream/cheese - seems a better fit, which roughly fulfils the order;
- semolina/carrots/cream/cheese - carrots clearly have a role to play. The largest residuals are for fat and saturated fat. Add the eggs?
- semolina/carrots/cream/cheese/eggs - these makes the fit quality better, but makes the cheese negative. Add olive oil instead?
- semolina/carrots/cream/cheese/oliveOil - these makes the fit quality better. Can I add both oil and egg? -> No makes others negative;
- semolina/onion/carrots/cream/cheese/oliveOil - including onion gives a better, but dominates right away.
Comparisons
Solver | Milk | Mushroom | Semolina | Onion | Carrots | Cream | Cheese | Egg | Olive oil | RMSE |
---|---|---|---|---|---|---|---|---|---|---|
ConsReg (with intercept) | 0.08 | 0.83 | 0.13 | - | - | 0.13 | - | 0.08 | - | - |
ConsReg (without intercept) | 0.04 | 0.94 | 0.13 | - | - | 0.14 | - | 0.07 | - | - |
Semolina/Cream/Egg | - | - | 0.178 | - | - | 0.111 | - | 0.231 | - | - |
Semolina/Cream/Cheese | - | - | 0.181 | - | - | 0.083 | 0.097 | - | - | 1.22 |
Semolina/Carrots/Cream/Cheese | - | - | 0.31 | - | 0.461 | 0.065 | 0.113 | - | - | 0.53 |
Semolina/Carrots/Cream/Cheese/Egg | - | - | 0.131 | - | 0.421 | 0.148 | -0.115 | 0.487 | - | 0.14 |
Semolina/Carrots/Cream/Cheese/OliveOil | - | - | 0.136 | - | 0.474 | 0.003 | 0.106 | - | 0.035 | 0.34 |
Semolina/Onion/Carrots/Cream/Cheese/OliveOil | - | - | 0.112 | 0.66 | 0.045 | 0.0023 | 0.119 | - | 0.020 | 0.30 |
Order constraints Attempt 2
In this attempt I rewrote the functions, which must be minimised. This results in a hard order. It used the nnls function in Rstudio.
RMS | Milk | Mushroom | Tomato pulp | Semolina | Cream | Onion | Tomato puree | Carrots | Cheese | Olive oil | Grilled onion | Tomato | Farine | Oeuf | Ail | Tomate séchée | Sel |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | 12% | 11.7 | - | - | 5.9 | 5.8 | 4.6 | 4.2 | - | 2.9 | 2.9 | - | - | - | 0.8 | - | |
41.01 | 1.31 | 0.76 | - | - | - | - | - | - | - | - | |||||||
41.01 | 1.31 | 0.76 | 0.00 | - | - | - | - | - | - | - | |||||||
10.17 | 1.04 | 0.10 | 0.10 | 0.10 | - | - | - | - | - | - | |||||||
3.16 | 0.425 | 0.425 | 0.125 | 0.125 | 0.115 | - | - | - | - | - | |||||||
3.16 | 0.425 | 0.425 | 0.125 | 0.125 | 0.115 | 0.00 | - | - | - | - | |||||||
3.16 | 0.425 | 0.425 | 0.125 | 0.125 | 0.115 | 0.00 | 0.00 | - | - | - | |||||||
3.16 | 0.425 | 0.425 | 0.125 | 0.125 | 0.115 | 0.00 | 0.00 | 0.00 | - | - | |||||||
1.87 | 0.158 | 0.158 | 0.158 | 0.129 | 0.081 | 0.081 | 0.081 | 0.081 | 0.073 | - | |||||||
0.50 | 0.299 | 0.299 | 0.129 | 0.129 | 0.040 | 0.040 | 0.040 | 0.040 | 0.040 | 0.024 | |||||||
0.50 | 0.145 | 0.145 | 0.129 | 0.129 | 0.041 | 0.041 | 0.041 | 0.041 | 0.041 | 0.024 | 0.015 | ||||||
0.50 | 0.261 | 0.261 | 0.10 | 0.110 | 0.041 | 0.041 | 0.041 | 0.041 | 0.041 | 0.024 | 0.016 | 0.016 | |||||
0.50 | 0.122 | 0.122 | 0.105 | 0.105 | 0.041 | 0.041 | 0.041 | 0.041 | 0.041 | 0.024 | 0.024 | 0.024 | 0.024 | ||||
0.29 | 0.283 | 0.283 | 0.105 | 0.105 | 0.034 | 0.034 | 0.034 | 0.034 | 0.034 | 0.026 | 0.026 | 0.026 | 0.026 | 0.026 | |||
0.10 | 0.283 | 0.283 | 0.098 | 0.098 | 0.035 | 0.035 | 0.035 | 0.035 | 0.035 | 0.026 | 0.026 | 0.026 | 0.026 | 0.026 | 0.026 | 0.003 | 0.003 |
The predicted versus observed values seem pretty close. I do not think we can do better without over-interpreting.
The evolution of the recipe when adding ingredients. The total does not seem to evolve. There is only replacement between ingredients.
Conclusions
- Multiple solutions - Just using the ingredients, it is possible to find solutions for the nutritional values of the product. In fact there seems to be more than one solution. Additional information is need to select the best solution;
- Single nutrient ingredients - It is always possible to find a solution by using single nutrient ingredients, like oil, sugar, salt. This will probably force the wrong recipe;
- Similar ingredients - some ingredients are very similar from a nutritional point of view. These ingredients have a high correlation (> 0.9). These ingredients should be handled as one ingredient. The fitting approach can not distinguish between these ingredients;
- Maximum number of ingredients - if a free fit is done, then the maximum number of ingredients needed is 7, for 7 nutrients. It will be a system of 7 equations with 7 unknowns. If we you use the forced origin fit, we could get more ingredients mathematically, but il will not have any meaning;
- Constraints - These are really required to get a good coverage of all ingredients, whilst also getting good results.