L’alimentation est la première préoccupation de l’homme d’un point de vue biologique. En effet, elle est synonyme de bon fonctionnement du corps humain et donc de bonne santé. Manger varié et équilibré est essentiel dans le cadre de la prévention des maladies.
Par conséquent, en France, de plus en plus de consommateurs sont attentifs à la provenance des aliments, à leur composition et leur qualité. Cependant, les choix alimentaires dépendent de différents facteurs comme la culture, la société, le revenu, les goûts de chacun etc.
On répartit généralement les aliments en 7 groupes, néanmoins leur consommation doit respecter ce qu’on appelle la pyramide alimentaire.
Cette pyramide se lit de bas en haut, c’est-à-dire de la famille alimentaire qui doit être consommée le plus souvent et en plus grande quantité (sur la journée) à la moins fréquente et en quantité diminuée.
Les aliments sont composés d’éléments qu’on appelle des nutriments. Les besoins nutritionnels nécessaires au bon fonctionnement du corps sont apportés par 3 grandes catégories de nutriments : les macronutriments (protéines, lipides, glucides…), les micronutriments (vitamines, oligo-éléments…) et les fibres.
Malheureusement, aucun aliment ne contient à la fois des lipides, des glucides, des protéines, des fibres, des minéraux et des vitamines. D’où l’utilisation de la pyramide alimentaire afin de choisir des aliments des différents groupes.
Les politiques de santé publique font, aujourd’hui, de l’alimentation une priorité en matière de prévention.
Anses, Agence nationale de sécurité sanitaire de l’alimentation, de l’environnement et du travail, contrôle la chaine alimentaire et évalue les risques sanitaires de la production primaire jusqu’à l’assiette du consommateur. Elle développe également des méthodes de diagnostic, mêne des travaux de recherche et conduit des expertises scientifiques d’evaluation des risques sur les produits. Elle assure enfin des missions de surveillance et de vigilance dans le domaine de la nutrition. L’Agence dispose des connaissances sur les apports nutritionnels de la population française indispensables pour orienter les politiques publiques en matière de nutrition.
Afin d’aider les consommateurs à évaluer la qualité des produits alimentaires qui lui sont proposés, en termes nutritionnels et selon des critères de santé, un label officiel Nutri-score a été mis en place en France en octobre 2017. Ce logo nutritionnel a été conçu par Santé publique France, à la demande de la Direction générale de la santé. Affiché sur la face avant des emballages, il attribue un score aux aliments selon leur qualité nutritionnelle et les classe dans une des 5 catégories identifiées par une lettre (du vert foncé au rouge) et une lettre (de A à E).
Le calcul du score (pour 100 grammes de produit) est évalué en fonction de la teneur :
L’algorithme est public et se base sur les éléments de composition des aliments déclarés de façon obligatoire. Ainsi, le Nutri-Score a déjà été intégré à différentes applications permettant de scanner le code barre des produits, notamment la base publique alimentaire Open Food Facts. Cette table des données répertorie les produits alimentaires dans le monde. Elle est remplie par des particuliers et peut-être consultée par tous.
L’objectif de cette étude est :
Dans un premier temps, nous allons effectuer une analyse descriptive de notre jeu de données. Dans un deuxième temps, en passant par des méthodes d’apprentissage non supervisé, nous allons essayer de retrouver les différentes catégories attribuées par l’Anses. Dans un troixième temps, nous allons tenter de prédire la catégorie d’un nouveau produit issu d’une seconde table. Ensuite, nous réaliserons notre propre score nutritionnel. Pour finir, à partir d’autres tables issues d’une même étude, nous allons analyser le comportement des consommateurs.
En France, la base de données de référence sur la composition nutritionnelle des aliments est gérée par l’Anses. Nous avons selectioné la table TableCiqual2017_ExcelFR_2017 11 17.xls disponible sur le site data.gouv.fr. Elle fournit la composition nutritionnelle (c’est-à-dire les teneurs en lipides, acides gras, glucides, sucres, protéines, sel, vitamines et minéraux…) ainsi que les valeurs énergétiques de plus de 2800 aliments représentatifs de ceux consommés en France en 2017. Pour chaque aliment, l’Anses estime la composition moyenne en combinant plusieurs produits de marques différentes. Les données sont toujours calculées pour 100 grammes de la partie comestible de l’aliment, c’est-à-dire sans les os, les coquilles, le trognon etc.
#data <- read_excel("~/_M2 Maths Appli et Stat/Semestre 10 - MSS/Projet Données Massives/PBD open data/TableCiqual2017.xls")
data <- read_excel("C:/Users/matic/Desktop/Projet Open Data/TableCiqual2017_ExcelFR_2017 11 17.xls")
data$alim_grp_code <- as.factor(data$alim_grp_code)
data$alim_ssgrp_code <- as.factor(data$alim_ssgrp_code)
data$alim_ssssgrp_code <- as.factor(data$alim_ssssgrp_code)
data$alim_code <- as.factor(data$alim_code)
data$alim_grp_nom_fr <- as.factor(data$alim_grp_nom_fr)
data$alim_ssgrp_nom_fr <- as.factor(data$alim_ssgrp_nom_fr)
data$alim_ssssgrp_nom_fr <- as.factor(data$alim_ssssgrp_nom_fr)
data$alim_nom_fr <- as.factor(data$alim_nom_fr)
alim_ssssgrp_nom_fr_cmp <- rep(NA, 2807)
alim_ssssgrp_code_cmp <- rep(NA, 2807)
for(i in 1:2807){
if(is.na(data$alim_ssssgrp_nom_fr[i])){
alim_ssssgrp_nom_fr_cmp[i] <- as.character(data$alim_ssgrp_nom_fr[i])
}else{
alim_ssssgrp_nom_fr_cmp[i] <- as.character(data$alim_ssssgrp_nom_fr[i])
}
if(data$alim_ssssgrp_code[i] == 0){
alim_ssssgrp_code_cmp[i] <- as.character(data$alim_ssgrp_code[i])
}else{
alim_ssssgrp_code_cmp[i] <- as.character(data$alim_ssssgrp_code[i])
}
}
alim_ssssgrp_nom_fr_cmp <- as.factor(alim_ssssgrp_nom_fr_cmp)
alim_ssssgrp_code_cmp <- as.factor(alim_ssssgrp_code_cmp)
# Imputation d'un jeu de donnees avec PCA
df <- as.data.frame(data[, 9:68])
ncomp <- estim_ncpPCA(df)
res_imp <- imputePCA(df, ncp = ncomp$ncp)
data[, 9:68] <- res_imp$completeObs
#paged_table(data)
dimension <- dim(data)
On dispose d’un jeu de données contenant 2807 aliments et 68 variables :
On observe dans cette table que les produits alimentaires sont répartis en 11 groupes d’aliments (alim_grp_nom_fr), qui eux-mêmes, sont séparés en sous-groupe (alim_ssgrp_nom_fr), 58 au total. Pour certains sous-groupes, les produits sont encore divisés dans différents blocs, notés les “sous-sous groupes” (alim_ssssgrp_nom_fr), 75 au total. On remarque donc que certains aliments n’ont pas de sous-groupe ou de sous-sous-groupe.
Les 11 groupes d’aliments sont les suivants :
levels(data$alim_grp_nom_fr)
## [1] "aides culinaires et ingrédients divers"
## [2] "aliments infantiles"
## [3] "boissons"
## [4] "entrées et plats composés"
## [5] "fruits, légumes, légumineuses et oléagineux"
## [6] "glaces et sorbets"
## [7] "lait et produits laitiers"
## [8] "matières grasses"
## [9] "produits céréaliers"
## [10] "produits sucrés"
## [11] "viandes, ufs, poissons"
Pour les variables quantitatives on retrouve bien les 60 constituants comprenant les énergies (au nombre de 3) et les 7 principales familles de nutriments :
Les nutriments ne sont pas tous de la même unité : les énergies sont en kcal/100g ou kJ/100g, les nutriments énergétiques (lipides, glucides et protéines) sont en g/100g excepté le cholestérol qui est en mg/100g, les minéraux sont en mg/100g excepté le sel et les cendres qui sont en g/100g, l’eau est en g/100g, les oligoéléments sont en mg/100g excepté l’iode et le sélénium qui sont en \(\mu\)g/100g et les vitamines sont en \(\mu\)g/100g excepté les vitamines E, C, B1, B2 B3, B5 et B6 qui sont en mg/100g.
On observe 3 valeurs énergétiques différentes. En effet, l’énergie des aliments peut-être calculée de plusieurs méthodes :
Cliquer sur un onglet et passer la souris sur le diagramme pour lire les données.
plot_ly(as.data.frame(table(data$alim_grp_nom_fr)),
x = ~Var1,
y = ~Freq,
marker = list(color = "rgb(93,71,139)")) %>%
layout( title = "Histogramme correspondant au \nnombre d'aliments dans chaque groupe")%>%
layout(xaxis = list(title = "Nom des groupes d'aliments"), yaxis = list(title = "Nombre d'aliments"))
plot_ly(as.data.frame(table(data$alim_ssgrp_nom_fr)),
x = ~Var1,
y = ~Freq,
marker = list(color = "rgb(60,179,113)")) %>%
layout( title = "Histogramme correspondant au \nnombre d'aliments dans chaque sous-groupe") %>%
layout(xaxis = list(title = "Nom des sous-groupes d'aliments"), yaxis = list(title = "Nombre d'aliments"))
plot_ly(as.data.frame(table(data$alim_ssssgrp_nom_fr)),
x = ~Var1,
y = ~Freq,
marker = list(color = "rgb(123,104,238)")) %>%
layout( title = "Histogramme correspondant au \nnombre d'aliments dans chaque sous-sous-groupe")%>%
layout(xaxis = list(title = "Nom des sous-sous-groupes d'aliments"), yaxis = list(title = "Nombre d'aliments"))
Pour la variable catégorielle alim_grp_nom_fr, on observe que le groupe contenant le plus grand nombre d’aliments est viandes, oeufs, poissons avec 739 aliments et le plus bas est le groupe glaces et sorbets avec 26 aliments. De plus, pour la variable catégorielle alim_ssgrp_nom_fr, on constate que le groupe contenant le plus grand nombre d’aliments est legumes avec 208 aliments et le plus bas est le groupe sorbets avec 3 aliments. De même, pour la variable catégorielle alim_ssssgrp_nom_fr_cmp, on remarque que le groupe contenant le plus grand nombre d’aliments est legumes crus avec 113 aliments et le plus bas est le groupe sauces sucrees avec 2 aliments.
On en déduit alors, qu’importe la variable catégorielle, les aliments ne sont pas répartis de façon homogène dans les différents groupes.
On remarque que dans notre table il manque le nom de groupe de certains aliments car ils sont considérés comme aliments moyens. On détient tout de même leur code de groupe d’aliments (alim_grp_code). Nous traitons les données sans utiliser ces aliments moyens.
On observe que le sous-groupe contenant le plus d’aliments, legumes, n’appartient pas au groupe possédant le plus grand nombre d’aliments viandes, oeufs, poissons.
table(data$alim_ssgrp_nom_fr, data$alim_grp_nom_fr)[c(10,24,25,34,35,45,46,57,58), c(5, 11)]
##
## fruits, légumes, légumineuses et oléagineux
## charcuteries 0
## fruits 93
## fruits à coque et graines oléagineuses 49
## légumes 208
## légumineuses 37
## poissons crus 0
## poissons cuits 0
## viandes crues 0
## viandes cuites 0
##
## viandes, ufs, poissons
## charcuteries 159
## fruits 0
## fruits à coque et graines oléagineuses 0
## légumes 0
## légumineuses 0
## poissons crus 108
## poissons cuits 61
## viandes crues 153
## viandes cuites 125
Lorsque l’on regarde, de plus près, la répartition des produits dans chaque sous-groupe pour les groupes viandes, oeufs, poissons et fruits, legumes, legumineuses et oleagineux, on a :
On remarque alors que la répartition des aliments dans les sous-groupe de ces 2 groupes est totalement différente. En effet, le sous-groupe legumes contient bien le plus d’aliments avec 208. Cependant, les autres sous-groupes du groupe fruits, legumes, legumineuses et oleagineux contiennent peu d’aliments (inférieurs à 100). A contrario, le groupe viandes, oeufs, poissons n’a pas de sous-groupe avec plus de 200 aliments mais plusieurs avec plus de 100 aliments. Ceci explique donc que le groupe viandes, oeufs, poissons est bien le groupe ayant le plus d’aliments.
plot_ly(as.data.frame(prop.table(table(data$alim_grp_nom_fr))), labels = ~Var1, values = ~Freq, type = "pie" ) %>%
layout(title = "Diagramme circulaire correspondant à la proportion d'aliments dans chaque groupe (en %)")
Pour la variable catégorielle alim_grp_nom_fr, la catégorie viandes, oeufs, poissons contient 26.4% des aliments, la catégorie lait et produits laitiers contient 8.8% des aliments ou encore la catégorie glaces et sorbets ne contient que 0.9% des aliments.
On en conclut qu’il n’y a pas de répartition uniforme des produits dans chaque groupe. En effet, comme on a pu le voir précédemment, nous avons des groupes qui ont plus de sous-groupe que d’autres mais avec peu de produits. D’autre part, nous avons des groupes qui ont moins de sous-groupe que d’autres mais contenant beaucoup de produits.
Comme nous l’avons décrit auparavant, nous avons 60 variables quantitatives : eau, protéines, glucides, etc. Nous allons tout d’abord nous concentrer sur la variable Energie, Règlement UE N 1169/2011 (kcal/100g) car elle est determinée par d’autres variables de la table. Cette valeur permet de savoir aussi l’apport nutritionnelle des aliments.
D’après les informations fournies par Anses sur la table, pour l’ensemble des aliments, la valeur énergétique a été calculée en utilisant les coefficients suivants :
energie <- data$`Energie, Règlement UE N° 1169/2011 (kcal/100g)`
boxplot(energie, horizontal = TRUE, col = "mediumspringgreen", ylim = c(0, 1000),
main = "Boite à moustache de la valeur énergétique",
xlab = "Valeur énergétique (en kcal/100g)")
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0 89.4 195.0 217.2 315.5 900.0
Pour la valeur énergétique, nous avons une teneur moyenne de 217.22 kcal/100g. On a 25% des aliments ayant une valeur énergétique qui ont une teneur inférieure ou égale à 89.4 kcal/100g. On a 75% des aliments ayant une valeur énergétique qui ont une teneur inférieure ou égale à 315.5 kcal/100g. On a 50% des aliments ayant une valeur énergétique qui ont une teneur inférieure ou égale à 195 kcal/100g. On a une teneur maximale de 900 et minimale de 0.
data %>% plot_ly(x = ~alim_grp_nom_fr,y = ~energie,split = ~alim_grp_nom_fr,type = 'box') %>%
layout(xaxis = list(title = "Groupe d'aliments"),yaxis = list(title = "Valeur énergetique (en kcal/100g)",zeroline = F)) %>%
layout( title = "Boîtes à moustache de la valeur énergétique par groupe d'aliments")
Lorsque nous observons la distribution de la variable numérique Energie, Règlement UE N° 1169/2011 (kcal/100g) en fonction des différents groupes, on s’aperçoit qu’elles sont différentes. En effet, pour le groupe glaces et sorbets, il n’y a pas de grande dispertion entre les valeurs énergétiques. Elles se situent entre 120 kcal/100g et 359 kcal/100g, soit une différence de 239 kcal/100g. Or, pour le groupe matiere grasse, on a une très grande distribution des valeurs énergétiques, comprises entre 0 et 900 kcal/100g. On peut donc dire que dans ce groupe que 50% des aliments ont un très grand apport énergétique, entre 518 et 900 kcal/100g, par rapport aux autres aliments des autres groupes. Le groupe produits sucres est le second groupe ayant des aliments qui ont un apport énergétique entre 216 et 611 kcal/100g, soit une différence de 365 kcal/100g. On remarque aussi que les groupes boissons, fruit, legumes, legumineuses et oleagineux et viande, oeufs, poissons ont de nombreuses valeurs extrêmes. De plus, les aliments du groupe boissons sont les derniers en apport énergétique, 50% de ces aliments ont une valeur énergétique comprise entre 0 et 76.5 kcal/100g.
c <- ggplot(data, aes(x = energie))
c <- c + geom_density(fill="mediumturquoise")
c <- c + labs(title = "Répartition des aliments en fonction de la valeur énergétique",
x = "Valeur énergetique (en kcal/100g)",
y = "Densité")
d <- ggplot(data, aes(x = energie))
d <- d + geom_histogram(fill="mediumturquoise", bins = floor(sqrt(max(energie))))
d <- d + labs(x = "Valeur énergetique (en kcal/100g)",
y = "Nombre")
grid.arrange(c, d, nrow = 2)
Lorsque nous regardons la densité des aliments en fonction de la valeur énergétique, on observe une décroissance, donc plus la valeur énergétique augmente, plus le nombre d’aliments diminue. Ainsi, sur l’histogramme, on oberve un pic avec plus de 325 aliments qui ont une valeur énergétique comprise entre 210 et 240 kcal/100g alors qu’entre 840 et 870 kcal/100g on peut voir qu’aucun n’aliment ne possède de valeur énergétique. A partir de 330 kcal/100g on voit une nette décroissance du nombre d’aliments en fonction de l’énergie.
Nous allons regarder s’il y a un lien entre les variables numériques. On recupère les variables les plus corrélées entre elles (\(|corr(var_i,var_j)| > 0.75\)).
M <- as.matrix(data[, 9:68])
R<-cor(M)
rownames(R) <- as.character(seq(9, 68, 1))
colnames(R) <- as.character(seq(9, 68, 1))
N <- matrix(NA, 60, 60)
for(i in 1:60){
for(j in 1:60){
if(abs(R[i, j]) > 0.75 & (i != j)){
N[, j] = R[, j]
}
}
}
col <- colorRampPalette(c("darkorange3", "white", "darkorchid4"))(20)
corrplot(R[-c(2, 3, 5, 6, 7, 9, 10, 11, 12, 14, 15, 24, 29, 30, 33, 35, 37:44, 46:60),
-c(2, 3, 5, 6, 7, 9, 10, 11, 12, 14, 15, 24, 29, 30, 33, 35, 37:44, 46:60)], col = col, tl.col = "black", tl.cex = 1, tl.srt = 45,type = "upper", order = "hclust")
On constate que : La variable Energie, Règlement UE N° 1169/2011 (n°9) est corrélée négativement avec l’Eau (n°12) et positivement avec les Lipides (n°16). Les Lipides sont corrélés aussi avec AG satures (n°24) et AG monoinsatures (n°25). La Cendre (n°21) est corrélée avec le sel (n°42), le chlorure (n°44) et le sodium (n°53). Les AG satures sont corrélés aussi aux AG 16:0, palmitique (n°33). Les AG monoinsatures sont corrélés aussi aux AG 18:1 9c (n9), oléique (n°35). Les AG polyinsaturés (n°26) sont corrélés avec AG 18:2 9c,12c (n6) linoléique (n°36). Les AG 4:0, butyrique (n°27) sont corrélés avec les AG 6:0, caproïque (n°28) et les AG 10:0, caprique (n°30). Les AG 8:0, caprylique (n°29) sont corrélés avec les AG 10:0, caprique et les AG 12:0, laurique (n°31). Les AG 10:0, caprique sont corrélés aussi aux AG 6:0, caproïque et aux AG 4:0, butyrique. Les AG 16:0, palmitique sont corrélés aussi aux AG 18:0, stéarique (n°34). Les AG 20:5 5c,8c,11c,14c,17c (n3) EPA (n°39) sont corrélés avec les AG 22:6 4c,7c,10c,13c,16c,19c (n3) DHA (n°40). Le sel est corrélé aussi au chlorure et au sodium. Le chlorure est corrélé aussi au sodium. Les autres variables ont une corrélation modérée ou proche de 0.
Nous allons nous intéresser de plus près aux corrélations entre les variables Sel,Sodium, et Cendres car ce sont les plus corrélées postivement. Et aux variables Energie, Règlement UE N° 1169/2011 et Eau car ce sont les plus corrélées négativements. En effet, ceci est évident car il n’y a pas d’Energie dans l’Eau.
Nous savons déjà que les variables Sel,Sodium et Cendres appartiennent à la même famille de nutriments, celle des minéraux. De plus, le Sodium est contenu dans le Sel (NAcl) et n’existe pas tout seul, il n’est donc pas pertinent d’étudier leur corrélation car c’est évident qu’elle doit être extrêmement forte.
On cherche à estimer l’association entre deux variables. Nous utilisons le test de Spearman car nos données ne proviennent pas d’une distribution normale. La statistique rhô de Spearman est basée sur un test de rang.
cor.test(data$`Energie, Règlement UE N° 1169/2011 (kcal/100g)`, data$`Eau (g/100g)`, method = "spearman")
##
## Spearman's rank correlation rho
##
## data: data$`Energie, Règlement UE N° 1169/2011 (kcal/100g)` and data$`Eau (g/100g)`
## S = 6812300000, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## -0.8480762
cor.test(data$`Sel chlorure de sodium (g/100g)`, data$`Cendres (g/100g)`, method = "spearman")
##
## Spearman's rank correlation rho
##
## data: data$`Sel chlorure de sodium (g/100g)` and data$`Cendres (g/100g)`
## S = 1014500000, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.7247783
cor.test(data$`Cendres (g/100g)`, data$`Sodium (mg/100g)`, method = "spearman")
##
## Spearman's rank correlation rho
##
## data: data$`Cendres (g/100g)` and data$`Sodium (mg/100g)`
## S = 1.097e+09, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.7024058
Le coefficient de Spearman permet de tester la significativité de la corrélation entre deux variables. Pour les variables, Energie, Règlement UE N° 1169/2011 et Eau on obtient un rhô de -0.85, ce qui est proche de -1, cela signifie qu’il y a bien une forte corrélation négative entre ces deux variables. En effet, comme rhô est négatif leur liaison est donc décroissante, lorsque l’Energie augmente l’Eau diminue et inversement.
En revanche, pour les variables Sel et Cendres et les variables Cendres et Sodium on obtient un rhô respectivement de 0.72 et 0.70. Il y a bien une corrélation croissante (car rhô positf) entre ces variables mais elle n’est pas très forte.
cendre <- data$`Cendres (g/100g)`
sel <- data$`Sel chlorure de sodium (g/100g)`
sodium <- data$`Sodium (mg/100g)`
eau <- data$`Eau (g/100g)`
mod1 <- lm(energie ~ eau)
mod2 <- lm(sodium ~ cendre)
mod3 <- lm(sel ~ cendre)
coef1 <- coefficients(mod1)
coef2 <- coefficients(mod2)
coef3 <- coefficients(mod3)
eq1 <- paste0("y = ", round(coef1[2], 2), "*x + ", round(coef1[1], 2))
eq2 <- paste0("y = ", round(coef2[2], 2), "*x + ", round(coef2[1], 2))
eq3 <- paste0("y = ", round(coef3[2], 2), "*x + ", round(coef3[1], 2))
e <- ggplot(data, aes(eau, energie, colour=alim_grp_nom_fr))
e <- e + geom_point()
e <- e + geom_abline(intercept = coef1[1], slope = coef1[2],
color = "mediumblue", linetype = "dashed") +
ggtitle("Nuages de points entre deux variables avec droite de régression linéaire")
e <- e + labs(subtitle = eq1)
f <- ggplot(data, aes(cendre, sodium, colour=alim_grp_nom_fr))
f <- f + geom_point() + theme(legend.position="none")
f <- f + geom_abline(intercept = coef2[1], slope = coef2[2],
color = "mediumblue", linetype = "dashed") + labs(subtitle = eq2)
g <- ggplot(data, aes(cendre, sel, colour=alim_grp_nom_fr))
g <- g + geom_point() + theme(legend.position="none")
g <- g + geom_abline(intercept = coef3[1], slope = coef3[2],
color = "mediumblue", linetype = "dashed") + labs(subtitle = eq3)
grid.arrange(e, arrangeGrob(f, g, ncol = 2), nrow = 2)
Sur la graphique représentant les nuages de points les variables Sel et Cendre, et, Sodium et Cendre sont modérément positives. En effet, on observe que certains points sont proches de la ligne, mais d’autres en sont éloignés. Les relations sont positives car lorsqu’une variable augmente l’autre augmente aussi.
A contrario, la relation linéaire entre Energie et Eau est modérément négative. En effet, il y a des points qui qui suivent la droite de régréssion linéaire, mais d’autres en sont très éloignés. On confirme bien que la relation est négative car lorsqu’une variable augmente l’autre diminue.
On obtient bien la même conclusion qu’avec le test de Spearman.
Nous allons donc pratiquer une ACP. Nous devons tout d’abord choisir le nombre de composantes principales que nous allons utiliser.
df <- as.data.frame(data[, 9:68])
res <- PCA(df, graph = FALSE)
fviz_eig(res,choice = "eigenvalue", addlabels = TRUE, ylim = c(0, 10), barfill = "mediumvioletred") + labs(title = "Ebouli des valeurs propres",
x = "Composantes principales", y = "Valeurs Propres")
Si l’on utilise la règle de Kaiser (choisir les valeurs propres plus grandes que 1) alors nous aurons le choix entre 16 premières valeurs propres, ce qui conduit à un taux d’inertie expliquée de 73.43%. Nous aurons une bonne projection des variables et des individus. Mais pour la représentation graphique des données, on choisira les deux premières composantes principales. Or cela va nous conduire à un taux d’inertie expliquée de 25.16%, infèrieur à 50%. Nous aurons une grande perte de la qualité de projection des données.
fviz_pca_var(res, col.var = "cos2", select.var = list(cos2 = 0.5),
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE, # Évite le chevauchement de texte
title = "Projection des variables sur les 2 premières \ncomposantes principales (ayant un cos2 > 0.5)")
Les flèches des variables les plus proches du cercle sont les mieux projetées. Les flèches entre la teneur en Eau et l’Energie sont de sens opposé. Donc ces variables sont corrélées négativement. On peut donc dire que les produits ayant des valeurs énergétiques élevées, ont une teneur en eau faible. De plus, les flèches entre les valeurs énergétiques et les teneurs en acide gras sont dans le même sens et sont proches. Donc ces variables sont corrélées positivement. On peut donc dire que les produits ayant des valeurs énergétiques élevées, ont des teneurs en acides gras élevées aussi. De même, les flèches des vitamines sont plus ou moins perpendiculaires à celles des valeurs énergétiques. Donc ces variables ont une corrélation nulle. On peut donc dire qu’il n’y a pas de relation linéaire entre les vitamines et la valeur énergétique.
Cliquer sur un onglet.
# Groupe
df <- as.data.frame(data[, c(1, 9:68)])
res <- PCA(df, quali.sup = 1, graph = FALSE)
fviz_pca_ind(res, geom.ind = "point", habillage = 1, palette = rainbow(11), legend.title = "Groupes alimentaires",
title = " Projection des individus sur les 2 premieres composantes principales")
# Sous Groupe
df <- as.data.frame(data[, c(2, 9:68)])
res <- PCA(df, quali.sup = 1, graph = FALSE)
plot(res, choix = "ind", label = "none", invisible = "quali", habillage = 1,
title = "Projection des individus sur les 2 premieres composantes principales")
# Sous sous Groupe
df <- as.data.frame(cbind(alim_ssssgrp_code_cmp, data[, 9:68]))
res <- PCA(df, quali.sup = 1, graph = FALSE)
plot(res, choix = "ind", label = "none", invisible = "quali", habillage = 1,
title = "Projection des individus sur les 2 premieres composantes principales")
On remarque que les points les plus éloignés du centre sont ceux qui contributs le moins à l’inertie expliquée et peuvent être enlevés. Comme on l’a vu, le premier axe oppose la teneur énergétique avec la teneur en eau. En effet, l’aliment tout à droite de cet axe, Beurre à 82% MG, doux fait parti des matières grasses. Ainsi, on peut donc dire que le Beurre à 82% MG, doux a des valeurs énergétiques élevées et des teneurs en acides gras élevées aussi. Pour le second axe, les vitamines sont corrélées positivement. En effet, l’aliment le plus haut de l’axe 2, Levure de boulanger, compressee fait partie des ingrédients divers. Ainsi, on peut donc dire que la Levure de boulanger, compressee contient un nombre élevé de vitamines, plus précisement, la Vitamine B3 ou PP ou Niacine (mg/100g), la Vitamine B5 ou Acide pantotheque (mg/100g) ou encore la Vitamine B6 (mg/100g).
Avant d’utiliser le clustering, on regarde graphiquement si nous pouvons délimiter des frontières entre chaque catégorie. Si on regarde par groupe, on a pu voir qu’il n’y a pas de frontière entre les groupes. Ils sont superposés les uns sur les autres. Par sous-groupe, il n’y a pas d’amélioration au niveau des frontières. Les points sont assez hétérogènes. Par sous-sous-groupe, nous ne voyons toujours pas de délimitation entre chaque groupe.
Il est fort probable que le clustering ne fonctionne pas a première vu. Soit il faut regarder en fonction des autres composantes principales si on peut détérminer une délimitation. Soit il faudrait séparer certaine catégorie, comme les liquides et les solides qui sont assez différent sur le plan nutritionnel.
Nous utilisons le clustering uniquement pour les aliments par groupe.
# Groupe
df <- as.data.frame(data[, 9:68])
res <- PCA(df, graph = FALSE, ncp = 16)
n <- nrow(df)
C <- res$ind$coord
delta <- dist(C[, 1:16])^2/(2*n)
tree <- hclust(delta, method = 'ward.D')
memb <- cutree(tree, k = 11)
memb <- as.factor(memb)
# Projection
df <- as.data.frame(cbind(memb, data[, 9:68]))
res <- PCA(df, quali.sup = 1, graph = FALSE)
fviz_pca_ind(res,
geom.ind = "point",
habillage = 1,
palette = rainbow(11),
legend.title = "Groupes alimentaires",
title = " Projection des individus sur les 2 premieres composantes principales")
Pour un regroupement à 11 clusters avec 2 composantes principales, on distincte bien les différents groupes mais elles ne reflètent pas visuellement les catégories de notre ensemble. Pour un regroupement à 11 clusters avec 16 composantes principales, on peut distinguer les groupes mais certains groupes se chevauchent les uns sur les autres. Plus on augmente le nombre de cluster et plus les groupes sont de moins en moins distinguables.
Nous utilisons la fonction catdes() pour voir si il y a un lien entre les catégories de notre ensemble et les clusters déterminés par la fonction cutree().
# Groupe
gp <- as.factor(cutree(tree, k = length(levels(data$alim_grp_code))))
test <- catdes(data.frame(gp, data[, -c(2, 3, 5, 6, 7, 8)]), num.var = 1)
#table(gp, data$alim_grp_code)
#cluster1
print(test$category$`1`[1:2, ], digits = 2)
print(test$quanti$`1`[1:5, ], digits = 2)
#...#
#cluster11
print(test$category$`11`[1:2, ], digits = 2)
print(test$quanti$`11`[1:5, ], digits = 2)
Cluster 1 :
La catégorie alim_grp_nom_fr=viandes, oeufs, poissons (resp. alim_grp_code=4) est surreprésentée ({v.test = Inf} > 0) chez les individus (les aliments) du cluster 1.
Pour le cluster 1 :
De même, on regarde les variables quantitatives qui sont significatives pour le cluster.
On peut donc dire que les variables Protéines..g.100g, Protéines.brutes..N.x.6.25..g.100g, Vitamine.B3.ou.PP.ou.Niacine..mg.100g, Zinc..mg.100g, et AG.20.4.5c.8c.11c.14c..n6…arachidonique..g.100g sont surreprésentées (v.test > 0) et sont liées de manière significative au cluster 1 (p.value < 0.01).
Or la catégorie alim_grp_nom_fr=viandes, oeufs, poissons (resp. alim_grp_code=4) est surreprésentée aussi ({v.test = 5.3} > 0) chez les individus (les aliments) du cluster 8. Mais, pour le cluster 8 :
De plus, la variable Rétinol..µg.100g, Cuivre..mg.100g, Vitamine.B12..µg.100g, Vitamine.B9.ou.Folates.totaux..µg.100g et Vitamine.B2.ou.Riboflavine..mg.100g sont surreprésentées (v.test > 0) et sont liées de manière significative au cluster 1 (p.value < 0.01).
Tableau recapitulatif :
Cluster | Groupe | P-valeur | V-test |
---|---|---|---|
1 | 4 | \(0\) | \(Inf\) |
2 | 6 | \(1.3 \times 10^{-98}\) | \(21\) |
3 | 5 | \(7.2 \times 10^{-60}\) | \(16\) |
4 | 3 | \(3.8 \times 10^{-148}\) | \(26\) |
5 | 3 | \(1.6 \times 10^{-25}\) | \(10\) |
4 | 9 | \(2.5 \times 10^{-49}\) | \(15\) |
7 | 10 | \(1.7 \times 10^{-41}\) | \(13\) |
8 | 4 | \(1.2 \times 10^{-07}\) | \(5.3\) |
9 | 9 | \(5.5 \times 10^{-06}\) | \(4.5\) |
10 | 10 | \(4.5 \times 10^{-16}\) | \(8.1\) |
11 | 10 | \(1.4 \times 10^{-06}\) | \(4.8\) |
En fin de compte, le clustering n’est pas une bonne méthode d’apprentissage non supervisé sur nos données.
Nous avons également essayé la méthode des k-means, cela n’a pas été plus informatif. Les groupes ne sont jamais bien délimités, ils se chevauchent. Selon les méthodes, ACP, Clustering, K-means certains aliments ne sont pas dans le même groupe à chaque fois.
De plus, ayant un taux d’inertie expliquée de 25.16%, on suppose alors que la grande pertie de la qualité de projection des données doit contribuer au chevauchement des groupes.
Finalement, les méthodes d’apprentissage supervisé ne nous ont pas permises de retrouver les catégories des aliments attribuées par l’Anses.
Notre objectif suivant est d’essayé de classer un produit qui n’est pas dans notre table avec de l’apprentissage supervisé. Pour cela, nous allons utiliser plusieurs méthodes. Nous allons tout d’abord séparer notre jeu de données en un échantillon d’apprentissage (soit 80% de notre data) et un échantillon de validation (soit 20% de notre data).
data_train <- data[, c(1, 12:13, 17:19, 21:22, 24:26, 41, 43:56, 58, 61)]
n <- 2807
p <- 27
y <- as.data.frame(data_train[, 1])
x <- as.data.frame(data_train[, -1])
B = 10
tbc = matrix(NA, B, 5)
TBC <- function(y_pred, y_test){
sum(y_pred == y_test)/length(y_test)
}
for (b in 1:B){
tr = sample(1:n, floor(n*80/100))
train = as.data.frame(data_train[tr, ])
test = as.data.frame(data_train[-tr, ])
# Methodes
g_lda = lda(alim_grp_code ~ ., data = train)
mod = svm(alim_grp_code ~ ., data = train, type = "C-classification")
tree <- rpart(alim_grp_code ~ ., data = train, cp = 0, method = "class", minsplit = 2)
tree1 = prune(tree, cp = tree$cptable[which.min(tree$cptable[ ,"xerror"]), 1])
rf = randomForest(train[, -1], train[, 1], mtry = floor(sqrt(p)), nodesize = 1, ntree = 400)
rfdef <- randomForest(train[, -1], train[, 1], important = TRUE)
rfdefimp <- rfdef$importance[, 1]
rfdefimpsort <- sort(rfdefimp, index.return = TRUE, decreasing = TRUE)
varsel <- rfdefimpsort$ix[1:27]
xs <- train[, varsel+1]
rfs = randomForest(xs, train[, 1])
# prediction
pred_lda = predict(g_lda, test[, -1])$class
pred_svm = predict(mod, test[, -1], type = "class")
pred_tree = predict(tree1, test[, -1], type = "class")
pred_rf = predict(rf, test[, -1])
pred_rfs = predict(rfs, test[, -1])
#Taux de bon classement
tbc[b, 1] = TBC(pred_lda, test$alim_grp_code)
tbc[b, 2] = TBC(pred_svm, test$alim_grp_code)
tbc[b, 3] = TBC(pred_tree, test$alim_grp_code)
tbc[b, 4] = TBC(pred_rf, test$alim_grp_code)
tbc[b, 5] = TBC(pred_rfs, test$alim_grp_code)
}
boxplot(tbc, main = sprintf("Taux de bon classement, B = %s fois", B),
names = c("LDA", "SVM", "CART", "Random Forest", "VI"), ylim = c(0.65, 0.95),
col = 2:6)
abline(h = 0.90, col = "black", lty = 3, lwd = 1)
abline(h = 0.85, col = "black", lty = 3, lwd = 1)
abline(h = 0.80, col = "black", lty = 3, lwd = 1)
abline(h = 0.75, col = "black", lty = 3, lwd = 1)
abline(h = 0.70, col = "black", lty = 3, lwd = 1)
summary(tbc)
## V1 V2 V3 V4
## Min. :0.6726 Min. :0.7811 Min. :0.7865 Min. :0.8737
## 1st Qu.:0.6851 1st Qu.:0.8087 1st Qu.:0.7954 1st Qu.:0.8919
## Median :0.6975 Median :0.8158 Median :0.8007 Median :0.8977
## Mean :0.6954 Mean :0.8130 Mean :0.8036 Mean :0.8963
## 3rd Qu.:0.7011 3rd Qu.:0.8221 3rd Qu.:0.8132 3rd Qu.:0.9035
## Max. :0.7171 Max. :0.8274 Max. :0.8203 Max. :0.9110
## V5
## Min. :0.8737
## 1st Qu.:0.8923
## Median :0.9004
## Mean :0.8984
## 3rd Qu.:0.9052
## Max. :0.9146
La méthode Ramdom Forest est celle qui obtient le meilleur taux de bon classement sur notre ensemble de validation. Passons à la prédiction.
Comme ensemble test nous avons choisi une base de données australienne nommée Food_nutrient_database.xlsx disponible sur le site Food Standards Australia New Zealand publiée en janvier 2019. Food Standards Australia New Zealand (FSANZ) est un organisme gouvernemental de la santé publique australienne. FSANZ élabore des normes alimentaires pour l’Australie et la Nouvelle-Zélande.
La base de données fournit la composition nutritionnelle ainsi que les valeurs énergétiques de 1535 aliments représentatifs de ceux qui sont le plus souvent consommés par des australiens ou utilisés en tant qu’ingrédients dans d’autres aliments.
Nous avons choisi la feuille Excel donnant tous les aliments et toutes les boissons pour 100g de portion comestible.
#data_test <- read_excel("~/_M2 Maths Appli et Stat/Semestre 10 - MSS/Projet Données Massives/PBD open data/Food_nutrient_database.xlsx",sheet = "All solids & liquids per 100g")
data_test <- read_excel("C:/Users/matic/Desktop/Projet Open Data/Data_Test_Food_nutrient_database.xlsx",sheet = "All solids & liquids per 100g")
data_test <- na.omit(data_test)
data_test <- data_test[, -1]
dimen <- dim(data_test)
Parmi les 253 variables correspondantes aux différents nutriments des aliments on a retrouvé 27 variables semblables à celles qui sont dans notre base de données initiale. Ces variables sont les suivantes :
colnames(data_test[, c(4:30)])
## [1] "Eau (g/100g)" "Protéines (g/100g)"
## [3] "Sucres (g/100g)" "Amidon (g/100g)"
## [5] "Fibres alimentaires (g/100g)" "Cendres (g/100g)"
## [7] "Alcool (g/100g)" "AG saturés (g/100g)"
## [9] "AG monoinsaturés (g/100g)" "AG polyinsaturés (g/100g)"
## [11] "Cholestérol (mg/100g)" "Calcium (mg/100g)"
## [13] "Chlorure (mg/100g)" "Cuivre (mg/100g)"
## [15] "Fer (mg/100g)" "Iode (µg/100g)"
## [17] "Magnésium (mg/100g)" "Manganèse (mg/100g)"
## [19] "Phosphore (mg/100g)" "Potassium (mg/100g)"
## [21] "Sélénium (µg/100g)" "Sodium (mg/100g)"
## [23] "Zinc (mg/100g)" "Rétinol (µg/100g)"
## [25] "BetaCarotène (µg/100g)" "Vitamine E (mg/100g)"
## [27] "Vitamine C (mg/100g)"
head(data_test)
En retirant les aliments ayant des valeurs non saisies on obtient donc un échantillon test contenant 594 aliments et 30 variables. Notre modèle Random Forest a appris uniquement sur ces 27 variables présentes dans notre échantillon d’apprentissage.
y_pred <- predict(rf, data_test[, -c(1:3)])
y_pred = as.factor(y_pred)
levels(y_pred) = c("entrées et plats composés", "fruits, légumes, légumineuses et oléagineux",
"produits céréaliers", "viandes, oeufs, poissons", "lait et produits laitiers",
"boissons", "produits sucrés", "glaces et sorbets", "matières grasses",
"aides culinaires et ingrédients divers", "aliments infantiles")
data_pred <- cbind(y_pred, data_test)
data_pred[c(3, 10, 30, 80, 200), c(1, 2)]
On affiche au hasard 5 aliments de la nouvelle table avec le groupe qui leur a été attribué. Ces 5 aliments là sont bien prédits. Mais regardons plus en détail.
plot_ly(as.data.frame(y_pred),
y = ~y_pred,
marker = list(color = "rgb(102,205,170)")) %>%
layout( title = "Histogramme correspondant au nombre d'aliments dans chaque groupe") %>%
layout(xaxis = list(title = "Nombre d'aliments"), yaxis = list(title = "Nom des groupes d'aliments"))
ind <- which(data_pred == "matières grasses")
data_pred[ind, 2]
## [1] "Mayonnaise, traditional (greater than 70% fat), commercial"
## [2] "Dairy blend, butter & edible oil spread (approximately 80% fat), sodium 600 mg/100 g"
## [3] "Margarine spread, polyunsaturated (70% fat), reduced salt (sodium 280 mg/100 g)"
## [4] "Margarine spread, monounsaturated (greater than 65% fat), reduced salt (sodium 360 mg/100 g)"
## [5] "Margarine spread, monounsaturated, reduced fat (55% fat) & salt (sodium 380 mg/100 g)"
## [6] "Margarine spread, monounsaturated, reduced fat (less than 65% fat)"
## [7] "Margarine spread, olive oil blend (65% fat), reduced salt (sodium 360mg/100 g)"
## [8] "Oil, blend of polyunsaturated vegetable oils"
## [9] "Oil, canola"
## [10] "Oil, copha"
## [11] "Oil, olive"
## [12] "Oil, peanut"
## [13] "Oil, soybean"
## [14] "Oil, sunflower"
## [15] "Dripping, beef"
## [16] "Fat, solid, vegetable oil based"
## [17] "Pork, loin chop, separable fat, raw"
## [18] "Pork, loin roast, separable fat, raw"
## [19] "Chicken, separable fat, composite, raw"
## [20] "Chicken, separable fat, composite, cooked, no added fat"
## [21] "Duck, skin & fat, raw"
On remarque qu’il n’y a pas d’aliments infantiles et de glaces et sorbets dans la nouvelle base de données. En effet, lorsque l’on regarde les aliments du groupe aliments infantiles, il contient des produits similaires à d’autres groupes, surtout comme les groupes laits et produits laitiers et produits céréaliers. De même, pour les produits du groupe glaces et sorbets qui sont souvent à base de lait et sucrés, ils vont plutôt se retrouver bien évidemment dans le groupe laits et produits laitiers ou celui de produits sucrés.
On remarque que le groupe contenant le plus d’aliments est celui de viandes, oeufs, poissons avec 223 suivi du groupe fruits, légumes, légumineuses et oléagineux avec 142. On retrouve les mêmes groupes les plus nombreux que dans notre base de données d’apprentissage.
D’autre part, en regardant les produits dans chaque groupe prédit, on voit que certains ne sont pas à leur place comme le produit “Céréales de petit-déjeuner, son de blé, pellets, vitamines B1, B2 et folate ajoutées” qui se retrouve dans le groupe “aides culinaires et ingrédients divers” au lieu d’être dans le groupe produits céréaliers. Ou encore, dans le groupe des matière grasse (affiché ci-dessus), on a “Porc, steak sur patte, graisse séparable, cru”, “Porc, côtelette, graisse séparable, crue”, “Porc, rôti de longe, graisse séparable, cru”, “Steak de porc, médaillon ou longe, gras séparable, cru”, “Poulet, graisse dissociable, composite, cru”, “Poulet, graisse séparable, composite, cuit, sans matière grasse ajoutée” et “Canard, peau et graisse, cru” or ils contiennent tous de la graisse séparable alors, d’une part, ces produits sont bien placés par rapport à leurs nutriments, d’autre part d’après leur nom ils devraient être dans le groupe viandes, poissons, oeuf. Il faudra soit modifier d’autres paramètres ou soit le faire manuellement pour que par la suite, l’algorithme apprend sur une nouvelle base un peu plus complète.
Pour conclure, on est plutôt satisfaites de notre modèle de prédiction. En effet, malgrès quelques erreurs, qui restent compréhensibles, notre modèle arrive à classer des aliments provenant d’une autre table.
Pour mettre en place notre score nutritionnel, nous avons décidé de nous inspirer du Nutri-Score élaboré par Santé Publique France.
Le calcul du Nutri-score est basé sur plusieurs nutriments (pour 100g de produit). Ceux dont la consommation excessive nuit à la santé , 0 à 10 points sont attribués à chacun :
Et ceux favorisant une bonne santé, 0 à 5 points sont attribués :
Il est calculé de façon identique pour tous les aliments, sauf pour les fromages, les matières grasses végétales ou animales, les boissons. Le score se compose de deux dimensions : les points positifs (nutriments bons) et les points négatifs (nutriments défavorables). On soustrait les bons points des mauvais et on obtient une note. La note finale du Nutri-score est donc comprise entre une valeur théorique de - 15 (le plus favorable sur le plan nutritionnel) et une valeur théorique de + 40 (le plus défavorable). Enfin, on attribue une lettre selon si c’est un solide ou un liquide grâce au tableau suivant :
Le Nutri-Score n’étant pas adapté aux aliments infantiles destinés aux enfants de 0 à 3 ans, nous avons alors retiré les aliments infantiles de notre base de données.
N’ayant pas la même valeur énergétique et le nutriment pourcentage de fruits et légumes, nous avons décidé de ne pas les utiliser pour élaborer notre score nutritionnel. Notre note finale va donc de -10 à 30 points.
Notre score a été calculé de la même façon pour tous les aliments sauf pour ceux du groupe boissons. Leur score dépend uniquement de la teneur de sucres (de 0 à 10 points).
Nous avons utilisé le tableau d’attribution des lettres du Nutri-score selon si c’est un liquide ou un solide pour notre score nutritionnel.
Ainsi nous obtenons notre base de données avec un score et une lettre pour chaque aliment.
Pour mieux visualiser notre score nutritionnel nous avons mis en place une application intéractive (shiny) disponible dansla Dropbox. En voici une capture.
Grâce à l’étude INCA 2 (Etude Individuelle Nationale des Consommations Alimentaires 2), réalisée en 2006/2007, nous avons à disposition des tables de données disponibles sur le site. data.gouv.fr. Elle nous permet de connaître le comportement et la consommation alimentaire des personnes de 3 à 79 ans vivant en France métropolitaine (hors Corse). Sur les 8 tables, nous avons décidé d’en choisir 2 par rapport à notre thématique : la table de description des individus et la table des apports journaliers en nutriment.
Nous allons analyser la table de description des individus.
Cette table regroupe les informations sur les habitudes de vie, l’état de santé, les attitudes et opinions en alimentation de 4079 individus. Elle contient 4079 observations et 368 variables que l’on peut retrouver en détail sur la Notice utilisation des données INCA 2.
#Table_indiv <- read_delim("~/_M2 Maths Appli et Stat/Semestre 10 - MSS/Projet Données Massives/PBD open data/Table_indiv.csv", ";", escape_double = FALSE, trim_ws = TRUE)
Table_indiv <- read_delim("C:/Users/matic/Desktop/Projet Open Data/Table_indiv.csv", ";", escape_double = FALSE, trim_ws = TRUE)
Table_indiv$nomen <- as.factor(Table_indiv$nomen)
Table_indiv$region <- as.factor(Table_indiv$region)
levels(Table_indiv$region) <- c("Région Parisienne", "Champagne", "Picardie", "Haute-Normandie", "Centre",
"Basse-Normandie", "Bourgogne", "Nord", "Lorraine", "Alsace", "Franche Comté",
"Pays De Loire", "Bretagne", "Poitou Charentes", "Aquitaine", "Midi-Pyrénées", "Limousin",
"Rhône-Alpes", "Auvergne", "Languedoc", "Provence Côte D'azur")
####
Table_indiv_fq <- Table_indiv[, c("nomen", "fqfec", "fqfl", "fqpl", "fqvpo", "region")]
Table_indiv_fq$fqfl <- as.factor(Table_indiv_fq$fqfl)
levels(Table_indiv_fq$fqfl) <- c("jamais", "1-2 fois/sem", "3-4 fois/sem", "5-6 fois/sem",
"1 fois/jour", "2 fois/jour", "3 fois/jour", "4 fois/jour",
"5 fois/jour", "6 fois/jour ou +", "ne sait pas", "[pas de réponse]")
Table_indiv_fq$fqfec <- as.factor(Table_indiv_fq$fqfec)
levels(Table_indiv_fq$fqfec) <- c("jamais", "1-2 fois/sem", "3-4 fois/sem", "5-6 fois/sem",
"1 fois/jour", "2 fois/jour", "3 fois/jour", "4 fois/jour ou +",
"ne sait pas", "[pas de réponse]")
Table_indiv_fq$fqpl <- as.factor(Table_indiv_fq$fqpl)
levels(Table_indiv_fq$fqpl) <- c("jamais", "1-2 fois/sem", "3-4 fois/sem", "5-6 fois/sem",
"1 fois/jour", "2 fois/jour", "3 fois/jour", "4 fois/jour ou +",
"ne sait pas", "[pas de réponse]")
Table_indiv_fq$fqvpo <- as.factor(Table_indiv_fq$fqvpo)
levels(Table_indiv_fq$fqvpo) <- c("jamais", "1-2 fois/sem", "3-4 fois/sem", "5-6 fois/sem",
"1 fois/jour", "2 fois/jour", "3 fois/jour", "4 fois/jour ou +",
"ne sait pas", "[pas de réponse]")
colnames(Table_indiv_fq) <- c("nomen", "Fréquence de consommation de pain, céréales, PDT, lég. secs",
"Fréquence de consommation de fruits, légumes",
"Fréquence de consommation de lait, pdts laitiers",
"Fréquence de consommation de viandes, volailles, poissons, oeufs", "region")
####
Table_indiv_etiq <- Table_indiv[, c("nomen", "etiqclnut", "etiqclsant", "etiqnut", "region")]
Table_indiv_etiq$etiqclnut <- as.factor(Table_indiv_etiq$etiqclnut)
levels(Table_indiv_etiq$etiqclnut) <- c("[plusieurs réponses]", "lit et influence tjrs achat",
"lit et influence parfois achat", "lit et n'influence jamais achat",
"ne lit jamais cette partie", "[pas de réponse]")
Table_indiv_etiq$etiqclsant <- as.factor(Table_indiv_etiq$etiqclsant)
levels(Table_indiv_etiq$etiqclsant) <- c("[plusieurs réponses]", "lit et influence tjrs achat",
"lit et influence parfois achat", "lit et n'influence jamais achat",
"ne lit jamais cette partie", "[pas de réponse]")
Table_indiv_etiq$etiqnut <- as.factor(Table_indiv_etiq$etiqnut)
levels(Table_indiv_etiq$etiqnut) <- c("[plusieurs réponses]", "lit et influence tjrs achat",
"lit et influence parfois achat", "lit et n'influence jamais achat",
"ne lit jamais cette partie", "[pas de réponse]")
colnames(Table_indiv_etiq) <- c("nomen", "Lit les messages nutritionnels revendiqués",
"Lit les messages décrivants effets sur la santé",
"Lit le contenu nutritionnel", "region")
Par rapport à notre thématique, nous allons prendre en compte que 9 variables qualitatives que nous avons séparé en deux tables :
et pour savoir s’il est vraiment intérressant de faire un score nutritionnel :
mj_fq <- unlist(lapply(Table_indiv_fq[, -1], function(x){length(levels(x))})) # nombre de modalite de la j-ieme variable
m_fq <- sum(mj_fq) # total du nombre de modalite
mj_etiq <- unlist(lapply(Table_indiv_etiq[, -1], function(x){length(levels(x))})) # nombre de modalite de la j-ieme variable
m_etiq <- sum(mj_etiq) # total du nombre de modalite
resume_fq <- summary(Table_indiv_fq)
resume_etiq <- summary(Table_indiv_etiq)
Table_indiv_no_na <- na.omit(Table_indiv_fq)
dimension3 <- dim(Table_indiv_no_na)
Table_indiv_no_na <- na.omit(Table_indiv)
dimension4 <- dim(Table_indiv_no_na)
Pour notre table contenant la fréquence :
Nous avons les 10 mêmes modalités pour les variables Fréquence de consommation de pain, céréales, PDT, lég. secs, Fréquence de consommation de lait, pdts laitiers et Fréquence de consommation de viandes, volailles, poissons, oeufs : jamais, 1-2 fois/sem, 3-4 fois/sem, 5-6 fois/sem, 1 fois/jour, 2 fois/jour, 3 fois/jour, 4 fois/jour ou +, ne sait pas, [pas de réponse]. Nous avons 2 modalités de plus pour la variable Fréquence de consommation de fruits, légumes : 5 fois/jour, 6 fois/jour ou +.
Nous avons 21 régions françaises dans notre table. On en déduit alors que l’on a en tout 63 modalités.
Sur nos données, sans prendre en considération les valeurs manquantes, on peut dire que la majorité des individus interrogés consomme des féculents 1 fois par jour, des fruits et des légumes 2 fois par jours, des produits laitiers 1 fois par jour et, de la viande, du poissons ou des oeufs 1 fois par jour. Beaucoup d’individus sont originaires de la région Parisienne.
Pour notre table contenant la lecture de l’étiquette :
Nous avons 6 mêmes modalités par variables sauf pour la région qui en à 21 : [plusieurs réponses], lit et influence tjrs achat, lit et influence parfois achat, lit et n’influence jamais achat, ne lit jamais cette partie, [pas de réponse].
Nous pouvons dire que, sans prendre en considération les NA, pour ceux qui lisent les messages nutritionnels revendiqués et font un choix, on en a 1805 sur 2189 individus, soit 82% des volontaires. On a 1917 qui lisent les messages décrivants les effets sur la santé, soit 88% et ils sont 1774 à lire le contenu nutritionnel, soit 81%. On en déduit que les français prennent le temps de lire les étiquettes, surtout les messages en rapport avec la santé. La majorité achètent les produits par rapport aux messages. Entre 10% et 17% ont des réponses multiples. Mais aussi, environ 2% des volontaires, pour chaque question, ne lisent pas les messages. Il n’est pas donc négligeable de faire un score nutritionnelle pour aider les clients à mieux choisir leurs aliments.
On remarque que 585 volontaires n’ont pas répondu à ces 4 questions sur la fréquence de consommation et 1890 n’ont pas répondu à la lecture de l’étiquette. Surement parce qu’ils n’ont pas eu accès à cette partie du questionnaire. Nous avons quand-même essayé de compléter par inputeMCA mais la compilation est trés lente voir infaisable sur nos propres ordinateurs pour déjà juste récupérer l’estimateur du nombre de composantes principales.
Nous avons tous besoin d’un apport énergétique suffisant pour être en forme durant la journée. Mais les besoins énergétiques sont différents en fonction des individus. Ils varient principalement par rapport à l’âge, au sexe et au degré d’activité physique.
tranches_age <- c("01-03 ans", "04-06 ans", "07-09 ans", "10-12 ans", "13-19 ans", "20-40 ans", "41-60 ans")
f <- c(4500, 6000, 7500, 8500, 9000, 9000, 9000) * 239 * 10^(-3)
h <- c(4500, 6000, 8000, 9000, 11500, 11500, 11000) * 239 * 10^(-3)
apport <- data.frame(tranches_age, f, h)
p <- plot_ly(apport, x = ~tranches_age, y = ~f, type = 'bar', name = 'femme') %>%
add_trace(y = ~h, name = 'homme') %>%
layout(yaxis = list(title = "Kcal"), barmode = 'groupe') %>%
layout(title = "Apports énergétiques quotidiens conseillés \n(pour un niveau moyen de poids et d'activité physique)")
p
D’après l’AFSSA (Agence française de sécurité sanitaire des aliments), on peut voir durant l’enfance, de 1 ans à 19 ans, que l’apport énergétique doit être croissante et doit se stabiliser à l’âge adulte, femme comme homme. Mais à l’âge de 7 ans, un écart entre les filles et les garçons commencent à se faire, soit à peu près 120 Kcal de différence. A l’âge adulte, entre 20 ans et 60 ans, il est conseillé pour les femmes de rester à environ 2150 Kcal et pour les hommes, à 2750 environ (Attention : ce sont des approximations, nous n’avons pas les données exactes mais juste un graphique).
Ainsi, par rapport à l’analyse que nous avons faite sur la variable énergétique pour chaque catégorie de produits et la fréquence de consommation de ces produits, nous avons voulu savoir si les apports énergétiques journaliers sont respectés, grâce à la table Table_indnut.
#Table_indnut <- read_delim("~/_M2 Maths Appli et Stat/Semestre 10 - MSS/Projet Données Massives/PBD open data/Table_indnut.csv", ";", escape_double = FALSE, trim_ws = TRUE)
Table_indnut <- read_delim("C:/Users/matic/Desktop/Projet Open Data/Table_indnut.csv", ";", escape_double = FALSE, trim_ws = TRUE)
Table_indnut$nomen <- as.factor(Table_indnut$nomen)
Table_indnut$sexe_ps <- as.factor(Table_indnut$sexe_ps)
levels(Table_indnut$sexe_ps) <- c("homme", "femme")
Table_indnut$ech <- as.factor(Table_indnut$ech)
levels(Table_indnut$ech) <- c("adultes", "enfants")
colnames(Table_indnut) <- c("nomen", "sexe_ps", "ech", "v2_age",
"Energie calorique totale table table CIQUAL avec polyols et acides orga. (kcal/j)",
"Protéines (en g/j)", "Glucides disponibles, y compris polyols (en g/j)",
"Lipides (en g/j) ", "Alcool (en g/j)", "Acides gras mono-insaturés (en g/j)",
"Acides gras polyinsaturés (en g/j)", "Acides gras saturés (en g/j)", "Amidon (en g/j)",
"Glucides simples (en g/j)", "Fibres (en g/j)", "Cholestérol (en mg/j)", "Eau (en g/j)",
"Calcium (en mg/j)", "Fer (en mg/j)", "Sodium (en mg/j)", "Magnésium (en mg/j)",
"Manganèse (en mg/j)", "Phosphore (en mg/j)", "Potassium (en mg/j)", "Cuivre (en mg/j)",
"Zinc (en mg/j)", "Sélénium (en µg/j)", "Iode (en µg/j)", "Rétinol (en µg/j)",
"Béta-carotène (en µg/j)", "Vitamine C (en mg/j)", "Vitamine D (en µg/j)",
"Vitamine E (en mg/j)", "Vitamine B1 ou thiamine (en mg/j)",
"Vitamine B2 ou riboflavine (en mg/j)", "Vitamine B3 ou niacine (en mg/j)",
"Vitamine B5 ou acide pantothénique (en mg/j)", "Vitamine B6 ou pyridoxine (en mg/j)",
"Vitamine B9 ou folates (en µg/j)", "Vitamine B12 ou colobamine (en µg/j)" )
#paged_table(Table_indnut)
dimension5 <- dim(Table_indnut)
On a du dans un premier temps déterminer la moyenne énergétique pour chaque sexe par Région. On a fait la même chose pour enfants/aldultes par région.
indnut <- merge(Table_indnut, Table_indiv[, c("nomen", "region")], by = "nomen")
moy_genre <- matrix(NA, 42, 38)
indnut$region <- as.factor(indnut$region)
levels(indnut$region) <- 1:21
indnut$region <- as.numeric(indnut$region)
nom_reg <- c("Île-de-France", "Champagne-Ardenne", "Picardie", "Haute-Normandie", "Centre", "Basse-Normandie",
"Bourgogne", "NordPas-de-Calais", "Lorraine", "Alsace", "Franche-Comté", "Pays De la Loire", "Bretagne",
"Poitou-Charentes", "Aquitaine", "Midi-Pyrénées", "Limousin", "Rhône-Alpes", "Auvergne",
"Languedoc-Roussillon", "Provence-Alpes-Côte d'Azur")
for(j in 0:20){
moy_genre[j*2+1, 3:38] = round(apply(indnut[which(indnut$region == j+1 & indnut$sexe_ps == "femme"), 5:40], 2, function(x){mean(x, na.rm = TRUE)} ), 2)
moy_genre[j*2+1, 1] = nom_reg[j+1]
moy_genre[j*2+1, 2] = "femme"
moy_genre[j*2+2, 3:38] = round(apply(indnut[which(indnut$region == j+1 & indnut$sexe_ps == "homme"), 5:40], 2, function(x){mean(x, na.rm = TRUE)} ), 2)
moy_genre[j*2+2, 1] = nom_reg[j+1]
moy_genre[j*2+2, 2] = "homme"
}
colnames(moy_genre) <- c("Region", "sexe_ps",
"Energie calorique totale table table CIQUAL avec polyols et acides orga. (kcal/j)",
"Protéines (en g/j)", "Glucides disponibles, y compris polyols (en g/j)",
"Lipides (en g/j) ", "Alcool (en g/j)", "Acides gras mono-insaturés (en g/j)",
"Acides gras polyinsaturés (en g/j)", "Acides gras saturés (en g/j)", "Amidon (en g/j)",
"Glucides simples (en g/j)", "Fibres (en g/j)", "Cholestérol (en mg/j)", "Eau (en g/j)",
"Calcium (en mg/j)", "Fer (en mg/j)", "Sodium (en mg/j)", "Magnésium (en mg/j)",
"Manganèse (en mg/j)", "Phosphore (en mg/j)", "Potassium (en mg/j)", "Cuivre (en mg/j)",
"Zinc (en mg/j)", "Sélénium (en µg/j)", "Iode (en µg/j)", "Rétinol (en µg/j)",
"Béta-carotène (en µg/j)", "Vitamine C (en mg/j)", "Vitamine D (en µg/j)",
"Vitamine E (en mg/j)", "Vitamine B1 ou thiamine (en mg/j)",
"Vitamine B2 ou riboflavine (en mg/j)", "Vitamine B3 ou niacine (en mg/j)",
"Vitamine B5 ou acide pantothénique (en mg/j)", "Vitamine B6 ou pyridoxine (en mg/j)",
"Vitamine B9 ou folates (en µg/j)", "Vitamine B12 ou colobamine (en µg/j)")
moy_reg_genre <- as.data.frame(moy_genre)
####
moy_ages <- matrix(NA, 42, 38)
nom_reg <- c("Île-de-France", "Champagne-Ardenne", "Picardie", "Haute-Normandie", "Centre", "Basse-Normandie",
"Bourgogne", "NordPas-de-Calais", "Lorraine", "Alsace", "Franche-Comté", "Pays De la Loire", "Bretagne",
"Poitou-Charentes", "Aquitaine", "Midi-Pyrénées", "Limousin", "Rhône-Alpes", "Auvergne",
"Languedoc-Roussillon", "Provence-Alpes-Côte d'Azur")
for(j in 0:20){
moy_ages[j*2+1, 3:38] = round(apply(indnut[which(indnut$region == j+1 & indnut$ech == "enfants"), 5:40], 2, function(x){mean(x, na.rm = TRUE)} ), 2)
moy_ages[j*2+1, 1] = nom_reg[j+1]
moy_ages[j*2+1, 2] = "enfants"
moy_ages[j*2+2, 3:38] = round(apply(indnut[which(indnut$region == j+1 & indnut$ech == "adultes"), 5:40], 2, function(x){mean(x, na.rm = TRUE)} ), 2)
moy_ages[j*2+2, 1] = nom_reg[j+1]
moy_ages[j*2+2, 2] = "adultes"
}
colnames(moy_ages) <- c("Region", "ech",
"Energie calorique totale table table CIQUAL avec polyols et acides orga. (kcal/j)",
"Protéines (en g/j)", "Glucides disponibles, y compris polyols (en g/j)",
"Lipides (en g/j) ", "Alcool (en g/j)", "Acides gras mono-insaturés (en g/j)",
"Acides gras polyinsaturés (en g/j)", "Acides gras saturés (en g/j)", "Amidon (en g/j)",
"Glucides simples (en g/j)", "Fibres (en g/j)", "Cholestérol (en mg/j)", "Eau (en g/j)",
"Calcium (en mg/j)", "Fer (en mg/j)", "Sodium (en mg/j)", "Magnésium (en mg/j)",
"Manganèse (en mg/j)", "Phosphore (en mg/j)", "Potassium (en mg/j)", "Cuivre (en mg/j)",
"Zinc (en mg/j)", "Sélénium (en µg/j)", "Iode (en µg/j)", "Rétinol (en µg/j)",
"Béta-carotène (en µg/j)", "Vitamine C (en mg/j)", "Vitamine D (en µg/j)",
"Vitamine E (en mg/j)", "Vitamine B1 ou thiamine (en mg/j)",
"Vitamine B2 ou riboflavine (en mg/j)", "Vitamine B3 ou niacine (en mg/j)",
"Vitamine B5 ou acide pantothénique (en mg/j)", "Vitamine B6 ou pyridoxine (en mg/j)",
"Vitamine B9 ou folates (en µg/j)", "Vitamine B12 ou colobamine (en µg/j)")
moy_reg_ages <- as.data.frame(moy_ages)
Pour mieux visualiser les données, nous avons utilisé une cartographie intéractive pour ces 4 modalités :
#data_REGION <- readOGR(dsn = "~/_M2 Maths Appli et Stat/Semestre 10 - MSS/Projet Données Massives/PBD open data/regions-20140306-50m-shp", layer = "regions-20140306-50m", verbose = FALSE)
data_REGION <- readOGR(dsn ="C:/Users/matic/Desktop/Projet Open Data/regions-20140306-50m-shp", layer = "regions-20140306-50m", verbose = FALSE)
proj_REGION <- sp::CRS('+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0')
contourRegion <- sp::spTransform(data_REGION, proj_REGION)
rm(list = c("data_REGION", "proj_REGION"))
#save(contourRegion, file = "~/_M2 Maths Appli et Stat/Semestre 10 - MSS/Projet Données Massives/PBD open data/contourRegion.Rdata")
save(contourRegion, file = "C:/Users/matic/Desktop/Projet Open Data/contourRegion.Rdata")
contourRegion <- contourRegion[which(contourRegion@data$nom != "Corse"
& contourRegion@data$nom != "Guadeloupe"
& contourRegion@data$nom != "Guyane"
& contourRegion@data$nom != "La Réunion"
& contourRegion@data$nom != "Martinique"
& contourRegion@data$nom != "Mayotte"),]
moy_reg_fem <- moy_reg_genre[which(moy_reg_genre$sexe_ps == "femme"), ]
contourRegion@data$femme <- moy_reg_fem$sexe_ps[match(contourRegion@data$nom , moy_reg_fem$Region)]
contourRegion@data$valeur_energetique_femme <- moy_reg_fem$`Energie calorique totale table table CIQUAL avec polyols et acides orga. (kcal/j)`[match(contourRegion@data$nom , moy_reg_fem$Region)]
contourRegion$valeur_energetique_femme <- as.numeric(as.vector(contourRegion$valeur_energetique_femme))
bins <- c(0, seq(1500, 1900, 50), Inf)
pal <- colorBin("Oranges", domain = contourRegion$nom, bins = bins)
label <- sprintf("%s, %g kcal/j", contourRegion$nom, contourRegion@data$valeur_energetique_femme) %>%
lapply(htmltools::HTML)
f <- leaflet(contourRegion) %>%
addTiles() %>%
addPolygons(weight = 2,
opacity = 1,
color = "white",
fillColor = ~pal(valeur_energetique_femme),
fillOpacity = 0.8,
highlight = highlightOptions(weight = 5,
color = "#666",
fillOpacity = 0.8,
bringToFront = TRUE),
label = label
) %>%
addLegend("bottomleft", pal = pal, values = ~valeur_energetique_femme,
title = "Moy. d'apport Energé. fem.", opacity = 0.8)
f
Cas des femmes :
On observe que la région Limousine a le plus grand apport énergétique avec 1878.54 Kcal/j pour les femmes. La Bourgonne est la plus basse avec 1503.71 Kcal/j. Si nous calculons la moyenne d’apport énergétique des femmes conseillée, alors nous obtenons 1952 Kcal/j. Les régions sont sous la moyenne conseillée. Il faudrait analyser plus en détail pour voir la tranche d’âge par exemple ou d’autres critères qui font qu’ils sont au dessous de la moyenne conseillée.
On remarque que les régions Pay de la Loire et le Nord-Pas-de-Calais n’ont aucune donnée, quelque soit la modalité. On ne pourra donc pas les traiter.
Passons aux hommes.
moy_reg_hom <- moy_reg_genre[which(moy_reg_genre$sexe_ps == "homme"), ]
contourRegion@data$homme <- moy_reg_hom$sexe_ps[match(contourRegion@data$nom , moy_reg_hom$Region)]
contourRegion@data$valeur_energetique_homme <- moy_reg_hom$`Energie calorique totale table table CIQUAL avec polyols et acides orga. (kcal/j)`[match(contourRegion@data$nom , moy_reg_hom$Region)]
contourRegion$valeur_energetique_homme <- as.numeric(as.vector(contourRegion$valeur_energetique_homme))
bins <- c(0, seq(2080, 2380, 50), Inf)
pal <- colorBin("Greens", domain = contourRegion$nom, bins = bins)
label <- sprintf("%s, %g kcal/j", contourRegion$nom, contourRegion@data$valeur_energetique_homme) %>%
lapply(htmltools::HTML)
h <- leaflet(contourRegion) %>%
addTiles() %>%
addPolygons(weight = 2,
opacity = 1,
color = "white",
fillColor = ~pal(valeur_energetique_homme),
fillOpacity = 0.8,
highlight = highlightOptions(weight = 5,
color = "#666",
fillOpacity = 0.8,
bringToFront = TRUE),
label = label) %>%
addLegend("bottomleft", pal = pal, values = ~valeur_energetique_homme,
title = "Moy. d'apport Energé. hom.", opacity = 0.8)
h
** Cas des hommes : **
On constate, homme comme femme, que le Limousin a toujours le plus grand apport énergétique avec 2338.72 Kcal/j. Le plus bas, cette fois ci, est l’Auvergne avec 2087.17 Kcal/j. Si nous comparons à la moyenne conseillée pour les hommes, soit 2270 Kcal/j alors l’apport énergétique de la basse-Normandie, l’Alsace et Midi-Pyrénées sont satisfaisantes. On remarque qu’elles sont géographiquement séparées donc il n’y a pas de lien géographique entre ces 3 régions. Les autres apports énergétiques des régions sont en dessous de 2230 Kcal/j ou en dessus de 2280 Kcal/j de cette moyenne.
Nous allons passer aux tranches d’âge : enfants ou adultes. Commençons par les enfants :
moy_reg_enf <- moy_reg_ages[which(moy_reg_ages$ech == "enfants"), ]
contourRegion@data$enfants <- moy_reg_ages$ech[match(contourRegion@data$nom , moy_reg_enf$Region)]
contourRegion@data$valeur_energetique_enfants <- moy_reg_enf$`Energie calorique totale table table CIQUAL avec polyols et acides orga. (kcal/j)`[match(contourRegion@data$nom , moy_reg_enf$Region)]
contourRegion$valeur_energetique_enfants <- as.numeric(as.vector(contourRegion$valeur_energetique_enfants))
bins <- c(0, seq(1680, 2030, 50), Inf)
pal <- colorBin("Blues", domain = contourRegion$nom, bins = bins)
label <- sprintf("%s, %g kcal/j", contourRegion$nom, contourRegion@data$valeur_energetique_enfants) %>%
lapply(htmltools::HTML)
e <- leaflet(contourRegion) %>%
addTiles() %>%
addPolygons(weight = 2,
opacity = 1,
color = "white",
fillColor = ~pal(valeur_energetique_enfants),
fillOpacity = 0.8,
highlight = highlightOptions(weight = 5,
color = "#666",
fillOpacity = 0.8,
bringToFront = TRUE),
label = label
) %>%
addLegend("bottomleft", pal = pal, values = ~valeur_energetique_enfants,
title = "Moy. d'apport Energé. enf.", opacity = 0.8)
e
** Cas des enfants : **
On remarque que le Limousin a le plus grand apport énergétique avec 2017.27 Kcal/j pour les enfants. L’apport énergétique le plus bas est la région Haut-Normandie avec 1680.53 Kcal/j. Lorsque l’on compare à la moyenne conseillée pour les enfants, soit 1957 Kcal/j, nous avons seulement Midi-Pyrénées proche de la moyenne conseillée. Il faudrait analyser par tranches d’âge pour avoir plus de précision.
Pour finir, nous allons analyser l’apport énergétiques des adultes.
moy_reg_adu <- moy_reg_ages[which(moy_reg_ages$ech == "adultes"), ]
contourRegion@data$adultes <- moy_reg_ages$ech[match(contourRegion@data$nom , moy_reg_adu$Region)]
contourRegion@data$valeur_energetique_adultes <- moy_reg_adu$`Energie calorique totale table table CIQUAL avec polyols et acides orga. (kcal/j)`[match(contourRegion@data$nom , moy_reg_adu$Region)]
contourRegion$valeur_energetique_adultes <- as.numeric(as.vector(contourRegion$valeur_energetique_adultes))
bins <- c(0, seq(1790, 2090, 50), Inf)
pal <- colorBin("Reds", domain = contourRegion$nom, bins = bins)
label <- sprintf("%s, %g kcal/j", contourRegion$nom, contourRegion@data$valeur_energetique_adultes) %>%
lapply(htmltools::HTML)
a <- leaflet(contourRegion) %>%
addTiles() %>%
addPolygons(weight = 2,
opacity = 1,
color = "white",
fillColor = ~pal(valeur_energetique_adultes),
fillOpacity = 0.8,
highlight = highlightOptions(weight = 5,
color = "#666",
fillOpacity = 0.8,
bringToFront = TRUE),
label = label
) %>%
addLegend("bottomleft", pal = pal, values = ~valeur_energetique_adultes,
title = "Moy. d'apport Energé. adu.", opacity = 0.8)
a
** Cas des adultes : **
Ainsi, on peut voir que le Limousin reste encore une fois premier avec 2075.95 Kcal/j d’apport énergétique pour les adultes. L’Auvergne est, pour la deuxième fois, dernier avec 1792.74 Kcal/j. Si nous comparons avec la moyenne conseillée 2420 Kcal/j, nous avons toutes les régions au-dessous de la moyenne.
Durant la réalisation de ce rapport nous avons rencontré différents problèmes, en effet certaines tables étaient très mal remplies (comme la table de Open Fast Food que nous n’avons pas étudié finalement). Nous avons dû régler le problème des valeurs manquantes sinon nous pouvions pas réaliser certains objectifs comme le score nutritionnel. Notre second objectif de retrouver les tables crées par l’Anses n’a pas été atteint, les méthodes d’apprentissage non supervisé sont inefficaces sur nos données. En revanche, nous avons une bonne prédiction de nouveaux aliments grâce à notre méthode d’apprentissage supervisé. Pour l’analyse des nutriments, on a pu confirmer que certains nutriments de la même famille sont corrélés.
En ce qui concerne l ’étude INCA2, les tables étaient bien remplies avec des informations supplémentaires très utiles qui nous ont permises une bonne interprétation du jeu de données.
Cependant, il serait possible de pousser davantage l’analyse du comportement alimentaire des individus et ainsi essayer de leur conseiller des produits. Peut-être serait-il intéressant, si l’Anses réalise une nouvelle étude sur la même thématique de comparer l’évolution du comportement des individus ou même les comportements dans différents Pays. Nous avons eu comme idées de questions : est-ce-que les individus ont participé au mois sans alcools ? Est-ce-que il y a eu une diminution de la consommation de viande ou de poisson suite au conseil de l’Etat ou après les affaires sanitaire ? Ou encore, en consomment-t-ils toujours, font-ils attention à l’origine de la viande ? Etc.
Il serait également intéressant de comparer nos produits avec des produits bio pour voir si ils sont vraiment meilleurs pour la santé. On pourrait s’aider de notre score nutritionnel. Par ailleurs, il serait possible d’améliorer notre score en prennant en compte les pesticides, les colorants ou même les conservateurs contenus dans certains produits et perfectionner également notre application shiny en calculant le score d’un produit que l’on saisit sois-même, qui n’est pas présent dans notre jeu de données.
Sites Web :
Table de composition nutritionnelle des aliments Ciqual. Etalab. data.gouv.fr [en ligne]. Mission Etalab DINSIC, créée le 8 juillet 2013, mise à jour le 6 février 2018 [consulté le 28 janvier 2019]. Disponible sur : https://www.data.gouv.fr/fr/datasets/table-de-composition-nutritionnelle-des-aliments-ciqual/ ;
Données de consommations et habitudes alimentaires de l’étude INCA 2. Etalab. data.gouv.fr [en ligne]. Mission Etalab DINSIC, créée le 24 septembre 2014, mise à jour le 16 mars 2016 [consulté le 9 février 2019]. Disponible sur : https://www.data.gouv.fr/fr/datasets/donnees-de-consommations-et-habitudes-alimentaires-de-letude-inca-2-3/ ;
Contours des régions françaises sur OpenStreetMap. Etalab. data.gouv.fr [en ligne]. Mission Etalab DINSIC, créée le 20 décembre 2013, mise à jour 2 janvier 2018 [consulté le 12 février 2019]. Disponible sur : https://www.data.gouv.fr/fr/datasets/contours-des-regions-francaises-sur-openstreetmap/ ;
Download Excel files (Australian Food Composition Database - Release 1). FSANZ. Food standards Australia & New Zealand [en ligne]. FSANZ, 2011-2013 [consulté le 4 février 2019]. Disponible sur : http://www.foodstandards.gov.au/science/monitoringnutrients/afcd/Pages/downloadableexcelfiles.aspx ;
Documents PDF :
SANTE PUBLIQUE FRANCE. Questions-Réponses sur le nutri-score. [document électronique]. Santé Publique France, 11 décembre 2018, https://www.santepubliquefrance.fr/Media/Files/NUTRISCORE/Questions_reponses ;
MANGER BOUGER.FR. Bien dans mon assiette. [document électronique]. Manger Bouger.fr, 2011, https://www.mangerbouger.fr/pro/IMG/pdf/livret_civ.pdf.
SANTE PBLIQUE FRANCE. Nutri-Score. [document électronique]. Santé Publique France, février 2018, https://www.santepubliquefrance.fr/Media/Files/CP-DP/2018/1502_DP_NUTRISCORE