Aller au contenu principal

GFM VitaScore

Le Gap Filling Module VitaScore calcule les incidences sur la santé humaine des produits alimentaires basées sur les facteurs de risque alimentaire de l'étude Charge mondiale de morbidité (Global Burden of Disease - GBD). Il convertit la composition alimentaire en années de vie corrigées de l'incapacité (AVCI, ou DALYs en anglais), permettant des comparaisons d'incidence sur la santé parallèlement aux métriques environnementales.

Référence rapide

PropriétéDescription
S'exécute surFoodProductFlowNode
DépendancesAggregationGapFillingWorker, DailyFoodUnitGapFillingWorker
Entrée cléQuantités par catégorie alimentaire, valeurs nutritionnelles, unité alimentaire quotidienne
SortieVitaScore en DALYs par facteur de risque alimentaire
DéclencheurLe produit dispose de catégories alimentaires agrégées et d'une unité alimentaire quotidienne

Conditions d'exécution

Le module se déclenche lorsque :

  1. L'agrégation des catégories alimentaires est terminée
  2. Le calcul de l'unité alimentaire quotidienne (DFU) est terminé
  3. Le noeud dispose de données amount_per_category_in_flow valides
  4. Le noeud dispose d'une valeur daily_food_unit valide

Sortie clé

Le module produit :

  • VitaScore total : Incidence sur la santé agrégée en DALYs
  • Scores par facteur : Contributions individuelles en DALYs de chaque facteur de risque alimentaire
  • Versions actuelle et héritée : Deux méthodes de calcul pour comparaison

Méthodologie scientifique

Le VitaScore quantifie l'incidence sur la santé de la consommation alimentaire en utilisant les années de vie corrigées de l'incapacité (DALYs) basées sur l'étude Charge mondiale de morbidité. Un DALY représente la perte d'une année de pleine santé.

Cadre de la Charge mondiale de morbidité

L'étude GBD identifie les facteurs de risque alimentaire contribuant à la charge de morbidité. Le VitaScore utilise 13 facteurs de risque regroupés en deux catégories :

Facteurs de risque positifs (une consommation plus élevée est bénéfique) :

  • Régime pauvre en fruits
  • Régime pauvre en légumes
  • Régime pauvre en céréales complètes
  • Régime pauvre en noix et graines
  • Régime pauvre en lait

Facteurs de risque négatifs (une consommation plus élevée est nocive) :

  • Régime riche en sodium
  • Régime riche en viande transformée
  • Régime riche en viande rouge
  • Régime riche en énergie
  • Régime riche en lipides
  • Régime pauvre en lipides
  • Régime riche en protéines
  • Régime pauvre en protéines

Niveau d'exposition à risque théorique minimum (TMREL)

Chaque facteur de risque alimentaire a une plage de consommation optimale appelée TMREL - le niveau d'exposition qui minimise le risque pour la santé. Le VitaScore calcule l'écart entre la consommation réelle et cette plage optimale.

Le TMREL est défini par deux bornes :

  • t_1 : Borne inférieure de la plage optimale
  • t_2 : Borne supérieure de la plage optimale

La formule VitaScore

La formule centrale calcule une fraction de risque (f_r) pour chaque facteur de risque alimentaire, puis multiplie par la charge de DALYs associée :

Pour les facteurs positifs (où consommer plus est mieux) :

f_r = (t_2 / (t_2 - t_1)) - x_r / (scaling * (t_2 - t_1))

Pour les facteurs négatifs (où consommer moins est mieux) :

f_r = x_r / (scaling * (t_2 - t_1)) - (t_1 / (t_2 - t_1))

Où :

  • x_r : Quantité du facteur de risque dans le produit alimentaire
  • t_1, t_2 : Bornes inférieure et supérieure du TMREL
  • scaling : Facteur de normalisation (voir ci-dessous)
  • f_r : Fraction de risque (limitée à la plage 0-1)

Calcul final :

VitaScore[r] = DALY_r * f_r
VitaScore total = somme(VitaScore[r] pour tous les facteurs de risque)

Méthodes de normalisation

Le VitaScore prend en charge trois méthodes de normalisation pour différents facteurs de risque :

MéthodeDescriptionUtilisation
per_dfuMise à l'échelle par unité alimentaire quotidienneLa plupart des facteurs de risque (fruits, légumes, viande, etc.)
per_total_energyMise à l'échelle par contenu énergétique totalLipides et protéines en pourcentage des calories
per_selfPas de mise à l'échelle (facteur = 1,0)Mesures directes

Unité alimentaire quotidienne (DFU)

L'unité alimentaire quotidienne représente la quantité de consommation quotidienne typique d'une catégorie alimentaire. Elle normalise le calcul de sorte que l'incidence sur la santé d'un aliment soit proportionnelle à la part qu'il représente dans le régime quotidien.


Détails d'implémentation

Facteurs de risque alimentaire couverts

Le module calcule les incidences sur la santé pour 13 facteurs de risque alimentaire. Chaque facteur a un niveau d'exposition à risque théorique minimum (TMREL) définissant la plage de consommation optimale.

Facteurs de risque positifs (une consommation plus élevée est bénéfique)

Facteur de risqueTMREL inférieurTMREL supérieurUnitéNormalisationDALYRéférence de recommandation alimentaire
Régime pauvre en fruits200300g/jourper_dfu61,24L'OMS recommande ≥400 g/jour fruits et légumes combinés1
Régime pauvre en légumes340500g/jourper_dfu30,57L'OMS recommande ≥400 g/jour fruits et légumes combinés1
Régime pauvre en céréales complètes100150g/jourper_dfu82,86Recommandations américaines : 3-4 portions/jour (~48-64 g)2
Régime pauvre en noix et graines1625g/jourper_dfu13,98EAT-Lancet : ~50 g/jour de noix3
Régime pauvre en lait350520g/jourper_dfu9,422-3 portions de produits laitiers/jour (~400-600 ml)4

Facteurs de risque négatifs (une consommation plus élevée est nocive)

Facteur de risqueTMREL inférieurTMREL supérieurUnitéNormalisationDALYRéférence de recommandation alimentaire
Régime riche en sodium (sel)15g/jourper_dfu29,43L'OMS recommande <5 g sel/jour (<2 g sodium)5
Régime riche en viande transformée04g/jourper_dfu96,94EAT-Lancet : éviter ou minimiser la viande transformée3
Régime riche en viande rouge1827g/jourper_dfu74,25EAT-Lancet : ~14 g/jour (~100 g/semaine)3

Facteurs de risque des macronutriments (énergie et pourcentage de l'énergie totale)

Facteur de risqueTMREL inférieurTMREL supérieurUnitéNormalisationDALYRéférence de recommandation alimentaire
Régime riche en énergie6501250kcalper_self88,66Un repas équilibré : 450-850 kcal (~⅓ de 2200 kcal/jour)4
Régime riche en lipides27,5 %50 %% de kcalper_total_energy88,66Recommandations EFSA/américaines : 20-35 % d'énergie des lipides46
Régime pauvre en lipides5 %27,5 %% de kcalper_total_energy88,66Recommandations EFSA/américaines : 20-35 % d'énergie des lipides46
Régime riche en protéines22,5 %60 %% de kcalper_total_energy88,66AMDR américain : 10-35 % d'énergie des protéines6
Régime pauvre en protéines0 %22,5 %% de kcalper_total_energy88,66AMDR américain : 10-35 % d'énergie des protéines6

Les valeurs DALY sont exprimées en DALYs pour 100 000 personnes-années et représentent la charge de morbidité attribuable à chaque facteur de risque alimentaire.

Conversion sodium en sel

Comme les recommandations alimentaires font souvent référence au sel (chlorure de sodium) plutôt qu'au sodium, le module convertit les valeurs de sodium :

# Le sodium représente environ 39,3 % du sel en masse
NA_PERCENT_IN_NACL = 39.337 # %

# Convertir le sodium en équivalent sel
salt_quantity = sodium_quantity * (100 / NA_PERCENT_IN_NACL)

Conversion énergétique des macronutriments

Les lipides et les protéines sont convertis de la masse en énergie pour les calculs de pourcentage de calories :

FAT_CALORIES_PER_GRAM = 9.0      # kcal/g
PROTEIN_CALORIES_PER_GRAM = 4.0 # kcal/g

fat_kcal = fat_grams * FAT_CALORIES_PER_GRAM
protein_kcal = protein_grams * PROTEIN_CALORIES_PER_GRAM

Support des versions

Le module maintient deux versions de calcul :

VersionDescription
currentDernières valeurs DALY GBD 2021
legacyValeurs DALY originales pour la rétrocompatibilité

Les deux versions sont calculées et stockées, permettant la comparaison des résultats entre les mises à jour méthodologiques.


Référence complète du code

Flux de calcul principal

async def run(self, calc_graph: CalcGraph) -> None:
"""Effectuer le calcul du vitascore."""
# Obtenir les catégories alimentaires agrégées et l'unité alimentaire quotidienne
amount_per_category_in_flow_prop = self.node.amount_per_category_in_flow
dfu_prop = self.node.daily_food_unit

# Ajouter les facteurs de risque dérivés du sel et de la nutrition
salt_qty, energy_qty, fat_qty, protein_qty = (
self.retrieve_salt_and_nutrition_amounts_for_activity_production_amount()
)

# Calculer le vitascore pour les deux versions
for version in (VitascoreVersionEnum.legacy, VitascoreVersionEnum.current):
vitascore_for_local = self.compute_vitascore(
amount_per_category_in_flow_prop,
dfu_prop,
version,
ReferenceAmountEnum.amount_for_activity_production_amount,
)
# ... stocker les résultats

Implémentation de la formule VitaScore centrale

def vitascore_formula(
self,
food_category: QuantityPackageProp,
dfu: float,
legacy_or_current: str,
for_reference_amount: ReferenceAmountEnum,
) -> dict[UuidStr, ReferencelessQuantityProp]:
"""Formule de calcul du vitascore."""
vitascore = {
self.gfm_factory.vitascore_term.uid: ReferencelessQuantityProp(
value=0.0, unit_term_uid=self.gfm_factory.daly_unit_term.uid
)
}

for idx, term in enumerate(
self.gfm_factory.positive_terms + self.gfm_factory.negative_terms
):
if term.xid in self.gfm_factory.used_categories_xid:
# Obtenir les bornes TMREL depuis les données du terme
t_1 = float(term.data.get("tmrel").get("lower"))
t_2 = float(term.data.get("tmrel").get("upper"))
normalization = TmrelNormalizationEnum(
term.data.get("tmrel").get("tmrel_normalization")
)

# Obtenir la quantité depuis les catégories alimentaires
if term.uid in amount_per_category_in_flow_present:
x_r = float(amount_per_category_in_flow_present[term.uid].value)
else:
x_r = 0.0

# Obtenir la charge DALY pour ce facteur de risque
daly_r = float(term.data.get(legacy_or_current).get("amount"))

# Déterminer le facteur de mise à l'échelle
if normalization == TmrelNormalizationEnum.per_dfu:
scaling = dfu
elif normalization == TmrelNormalizationEnum.per_total_energy:
scaling = energy_kcal_value
elif normalization == TmrelNormalizationEnum.per_self:
scaling = 1.0

# Calculer la fraction de risque
if scaling <= 0.0:
f_r = 0.0
else:
if idx < len(self.gfm_factory.positive_terms):
# Facteurs positifs : plus c'est mieux
f_r = (t_2 / (t_2 - t_1)) - x_r / (scaling * (t_2 - t_1))
else:
# Facteurs négatifs : moins c'est mieux
f_r = x_r / (scaling * (t_2 - t_1)) - (t_1 / (t_2 - t_1))

# Limiter la fraction de risque à [0, 1]
f_r = max(0, min(1, f_r))

# Calculer et accumuler le vitascore
vitascore[term.uid] = ReferencelessQuantityProp(
value=daly_r * f_r,
unit_term_uid=self.gfm_factory.daly_unit_term.uid
)
vitascore[self.gfm_factory.vitascore_term.uid].value += daly_r * f_r

return vitascore

Récupération du sel et de la nutrition

def retrieve_salt_and_nutrition_amounts_for_activity_production_amount(
self,
) -> Tuple[Optional[ReferencelessQuantityProp], ...]:
"""Extraire les quantités de sel et de macronutriments depuis les données nutritionnelles."""

# Vérifier d'abord les nutriments agrégés, puis les valeurs nutritionnelles
if aggregated_nutrients := self.node.aggregated_nutrients:
nutrition_pkg = aggregated_nutrients.amount_for_activity_production_amount()
elif nutrient_values := self.node.nutrient_values:
nutrition_pkg = nutrient_values.amount_for_activity_production_amount()

# Gérer la séparation du chlorure de sodium
if nutrition_pkg and (sodium_chloride_term.uid in nutrition_pkg.quantities):
nutrition_pkg = split_sodium_chloride(nutrition_pkg)

# Convertir le sodium en sel
if sodium_term.uid in nutrition_pkg.quantities:
salt_qty = nutrition_pkg.quantities[sodium_term.uid].duplicate()
salt_qty.value *= 100 / NA_PERCENT_IN_NACL

# Obtenir l'énergie et convertir lipides/protéines en kcal
energy_kcal_qty = nutrition_pkg.quantities.get(energy_term.uid)

if fat_mass_qty := nutrition_pkg.quantities.get(fat_term.uid):
fat_in_grams = convert_to_grams(fat_mass_qty)
fat_qty = ReferencelessQuantityProp(
value=fat_in_grams * FAT_CALORIES_PER_GRAM,
unit_term_uid=kcal_term.uid
)

if protein_mass_qty := nutrition_pkg.quantities.get(protein_term.uid):
protein_in_grams = convert_to_grams(protein_mass_qty)
protein_qty = ReferencelessQuantityProp(
value=protein_in_grams * PROTEIN_CALORIES_PER_GRAM,
unit_term_uid=kcal_term.uid
)

return salt_qty, energy_kcal_qty, fat_qty, protein_qty

Exemple de calcul

Scénario : Calculer le VitaScore pour 100 g de jambon transformé

Étape 1 : Identifier les quantités de facteurs de risque

Depuis l'agrégation des catégories alimentaires :

  • Viande transformée : 100 g
  • Viande rouge : 0 g (comptée séparément de la viande transformée)
  • Fruits : 0 g
  • Légumes : 0 g

Depuis les valeurs nutritionnelles :

  • Sodium : 1200 mg (converti en 3050 mg de sel)
  • Énergie : 145 kcal
  • Lipides : 8 g (72 kcal)
  • Protéines : 18 g (72 kcal)

Étape 2 : Calculer les fractions de risque

Régime riche en viande transformée (facteur négatif) :

  • TMREL : 0-0 g par jour (l'optimal est une consommation nulle)
  • Mise à l'échelle : Unité alimentaire quotidienne (supposons 2000 g d'apport alimentaire quotidien)
  • Quantité normalisée : 100 g / 2000 g = 0,05 (5 % de l'apport quotidien)
  • Fraction de risque : Calculée selon l'écart au TMREL

Régime riche en sodium :

  • TMREL : 1000-5000 mg par jour
  • Quantité de sel : 3050 mg
  • Fraction de risque : Basée sur où 3050 mg se situe dans la plage TMREL

Régime pauvre en fruits (facteur positif) :

  • Quantité : 0 g
  • Fraction de risque : Maximum (pas de contenu en fruits)

Étape 3 : Appliquer les valeurs DALY

Chaque fraction de risque est multipliée par la charge DALY associée depuis les données GBD :

  • Charge DALY viande transformée : ~40 DALYs pour 100 000 personnes-années
  • Charge DALY sodium : ~30 DALYs pour 100 000 personnes-années

Étape 4 : Additionner le VitaScore total

VitaScore total = somme de (DALY_r * f_r) pour les 13 facteurs de risque

Le résultat est exprimé en micro-DALYs par portion, représentant la charge de santé proportionnelle.


Sources de données

Étude Charge mondiale de morbidité

Le VitaScore est basé sur l'étude GBD 2021 :

GBD 2021 Risk Factors Collaborators (2024). Global burden and strength of evidence for 88 risk factors in 204 countries and 811 subnational locations, 1990-2021: a systematic analysis for the Global Burden of Disease Study 2021. The Lancet.

Données clés extraites :

  • Charges DALY pour chaque facteur de risque alimentaire
  • Plages TMREL pour une consommation optimale
  • Estimations de risque relatif

Valeurs TMREL

Les niveaux d'exposition à risque théorique minimum proviennent de :

  1. Annexe 1 GBD 2021 : Spécifications détaillées du TMREL pour chaque facteur de risque
  2. Matériaux supplémentaires du Lancet : Données de support pour la dérivation du TMREL

Facteurs de médiation

Le GBD utilise des facteurs de médiation pour tenir compte des voies de risque qui se chevauchent. Par exemple, la viande rouge impacte la santé à la fois directement et par son effet sur l'indice de masse corporelle (IMC).


Limitations connues

Contraintes méthodologiques

  • Moyennes de population : Les valeurs DALY représentent des moyennes mondiales ou régionales, pas des risques individuels
  • Spécificité âge/sexe : L'implémentation actuelle utilise des valeurs à l'échelle de la population (des valeurs spécifiques âge/sexe sont disponibles mais non implémentées)
  • Chevauchement des facteurs de risque : Les facteurs de médiation traitent partiellement mais pas totalement les risques corrélés

Limitations des données

  • Correspondance alimentaire : Nécessite une classification précise des catégories alimentaires
  • Complétude nutritionnelle : Les calculs sodium/lipides/protéines dépendent de données nutritionnelles complètes
  • Incertitude TMREL : Les plages de consommation optimales comportent une incertitude scientifique inhérente

Lacunes de couverture

  • Spécificité par pays : Les valeurs DALY peuvent être rendues spécifiques par pays mais utilisent actuellement des estimations mondiales
  • Aliments transformés : Les aliments transformés complexes peuvent avoir une correspondance de catégorie incomplète
  • Nouveaux aliments : Les nouvelles catégories alimentaires peuvent manquer d'associations établies avec les facteurs de risque

Références

  1. GBD 2021 Risk Factors Collaborators (2024). Global burden and strength of evidence for 88 risk factors in 204 countries and 811 subnational locations, 1990-2021. The Lancet, 403(10440), 2162-2203.

  2. Eaternity (2017). Documentation VitaScore. https://eaternity.org/assets/smart-chefs/2017-12-12_VitaScore_Documentation_web.pdf

  3. Ernstoff, A., et al. (2020). Towards Win-Win Policies for Healthy and Sustainable Diets. Nutrients, 12(9), 2745.

  4. Murray, C.J.L., et al. (2020). Global burden of 87 risk factors in 204 countries and territories, 1990-2019: a systematic analysis for the Global Burden of Disease Study 2019. The Lancet, 396(10258), 1223-1249.

  5. Outil de résultats GBD. Institute for Health Metrics and Evaluation. https://vizhub.healthdata.org/

Footnotes

  1. Fiche d'information OMS Régime alimentaire sain 2

  2. Recommandations alimentaires américaines et céréales complètes

  3. Régime de santé planétaire EAT-Lancet 2 3

  4. Valeurs de référence alimentaires EFSA 2 3 4

  5. Réduction du sodium OMS

  6. Recommandations alimentaires américaines - Plages de distribution acceptables des macronutriments 2 3 4