Préambule
L'objectif de ce sujet est de procurer une expérience dans la collecte, le nettoyage et la manipulation de jeux de données pour alimenter une base de données. Cela nécessite de charger différents ensembles de données dans une base de données, effectuer des tâches de manipulation de données et créer des visualisations pour analyser les données, afin de tirer des informations et de fournir des interprétations significatives. La visualisation des données se fait au travers d'une application web relativement basique, où un utilisateur enregistré peut voir des graphiques s'afficher, en fonction de critères de filtrage qu'il peut modifier.
Une extension possible est d'appliquer des tâches d'apprentissage automatique en utilisant les données collectées pour effectuer des tâches de classification et/ou de régression.
1°/ Contexte
Le cadre général du sujet de type 2 est de créer une application web qui propose aux utilisateurs de visualiser des graphiques crées à partir du croisement de jeux de données de différents types, provenant d'autres sites et/ou fichiers, BdD etc. Ces graphiques ont pour but de donner de l'information "enrichie" aux utilisateurs, soit pour s'informer, soit pour de l'analyse et prise de décision. Un exemple actuel de ce type de site est celui qui permet de calculer et visualiser les émissions CO2 d'entreprises en croisant leurs données de volumes de matières premières/production/transport/... avec des données issues de recherches scientifiques qui donnent le CO2 émit pour tel ou tel type d'activité/production. Un autre exemple pourrait être un croisement entre des données météorologiques, d'offre d'hébergement, et de prix d'activités, afin de décider du meilleur endroit pour passer ses vacances à un date donnée.
L'application web en elle-même n'est que la partie "émergée" du sujet puisqu'il nécessite de récupérer au préalable des données, de les nettoyer/agréger/... puis les importer dans une BdD. Cette BdD n'est accessible qu'au travers d'un serveur de type API REST que le site web peut interroger, via des routes, afin de récupérer les données de la BdD . Les données permettent également de créer des graphiques (par exemple via des scripts python) qui seront affichés par défaut dans le site web, par exemple dans la page d'accueil. Seuls les utilisateurs enregistrés pourront accéder à la partie du site permettant de visualiser des graphiques créés à la demande, selon les filtres de l'utilisateur.
Globalement, les fonctionnalités attendues pour l'application sont :
- un utilisateur public a accès à la page d'accueil du site et une page pour s'inscrire/authentifier. La page d'accueil sert juste de vitrine pour expliquer le service proposé par le site, notamment en affichant des graphiques créés aux préalable.
- un utilisateur enregistré et logué a accès à sa page de profil (pour changer ses informations/mot de passe/...) ainsi que différentes pages permettant de produire différentes types de graphiques, avec la possibilité de spécifier des critères de filtrage sur les données qui vont servir à créer les graphiques. Les données sont issues de l'API mais les graphiques sont créés directement dans le navigateur.
- un utilisateur administrateur a accès à une page de gestion des utilisateurs, ainsi qu'une page permettant de modifier le contenu de la page d'accueil, et une page permettant de lancer la génération des graphiques utilisés dans la page d'accueil.
Cette application doit être réalisée selon des principes de conception actuels du Web, à savoir avec une partie visuelle côté navigateur (front-end) écrite en Javascript grâce au framework vuejs, une partie base de données implémentée grâce à un serveur de type MySQL, une partie serveur (back-end) écrite en nodejs, qui fait l'interface entre le navigateur et la BdD, sous la forme d'une API REST et qui sert également à envoyer le code javascript créé en vuejs au navigateur (=comme un serveur web).
Cette organisation permet au navigateur, au travers des interactions de l'utilisateur avec l'interface graphique de l'application, d'envoyer des requêtes au serveur API. En fonction du type de requête et des données associées (en principe des objets JSON) le serveur API va exécuter certaines instructions permettant de mettre à jour la BdD, et/ou d'en extraire des informations pour produire de nouvelles données envoyées au navigateur. Ce dernier les utilise pour mettre à jour l'interface graphique.
La structure de l'interface graphique et de la BdD ainsi que les requêtes possibles à l'API sont à déduire du cahier des charges donné en section 2.
Outre l'application web, il y a un travail préalable de récupération des données auprès de sites sources, d'écriture de scripts (par exemple en python) afin de nettoyer/restructurer ces données, mais également pour produire quelques graphiques pour la page d'accueil de l'application web.
IMPORTANT ! Certaines tâches demandées en S3 demandent des connaissances qui ne seront jamais abordées en cours, ou alors seulement en 2ème moitié de S3, voire en S4. Une SAÉ étant une situation d'apprentissage, il est normal que vous deviez vous former de façon autonome. |
2°/ Cahier des charges
2.1°/ Collecte de données
- Identifier les sources pertinentes pour vos ensembles de données en fonction du contexte de votre application web.
- Utiliser des fichiers, ou bien des techniques de web scraping pour collecter des ensembles de données à partir de pages web. Il faut collecter au moins deux ensembles de données provenant de sources fiables.
Remarques :
- Les ensembles de données peuvent être dans différents formats (par exemple, CSV, Excel, JSON, XML).
- Ces ensembles collectés doivent être suffisamment volumineux (plusieurs centaines/milliers de "lignes") pour pouvoir appliquer différentes tâches de manipulation et d'analyse de données.
- Ces ensembles doivent pouvoir être "croisés" car certains de leur champs représentent le même type d'information. Il faut cependant que le croisement reste pertinent. Par exemple, utiliser un jeu de données indiquant la température de l'air heure par heure dans des stations météo, et un autre jeu de données qui indique l'heure de passage de chaque véhicule à des péages, est valable car les deux jeux contiennent une information temporelle et que l'on peut trouver la station météo la plus proche de chaque péage. En revanche, croiser la fréquentation journalière de mouettes sur des plages, avec celles du nombre de personnes en arrêt maladie chaque semaine, n'est pas pertinent, malgré les informations de type temporel qui sont partagées.
2.2°/ Nettoyage des données
Utiliser Python pour nettoyer les données avant de les charger dans la base de données, avec comme tâches :
- Supprimer les lignes en doublon des ensembles de données.
- Gérer les valeurs manquantes des ensembles de données.
- Normaliser les champs de texte (par exemple, convertir tout le texte en minuscules).
- Corriger les données incohérentes.
- Normaliser les données (si nécessaire).
- Supprimer les valeurs aberrantes des ensembles de données.
- Convertir les types de données si besoin (par exemple, texte en nombre).
2.3°/ Évaluer la qualité des données :
Pour valider les données nettoyées et s'assurer que les problèmes de qualité ont été résolus, il faut évaluer la qualité des ensembles de données en effectuant les tâches suivantes :
- Vérifier l'exhaustivité des données (data completeness) : par exemple, vérifier que tous les champs requis sont présents dans les ensembles de données.
- Vérifier la cohérence des données (data consistency) : par exemple, vérifier que les données dans différents champs sont cohérentes.
- Vérifier l'exactitude des données (data accuracy) : par exemple, comparer les données à des sources externes pour vérifier l'exactitude.
2.4°/ Création de la BdD
- Les données collectées doivent être transformées et stockées dans une base de données relationnel telle que MySQL.
- Il faut donc définir un modèle de BdD pour stocker ces données. Ce modèle doit contenir des tables distinctes pour chaque ensemble de données, avec des types appropriés pour chaque champ/colonne en vue de leur récupération par l'application web au travers de l'API. Dans le même registre, il doit établir des relations appropriées entre les tables en vue des croisement possible pour en extraire de l'information.
- Ce modèle doit également contenir les tables nécessaires à la gestion des utilisateurs, et aussi des textes/images qui sont utilisés dans la page d'accueil de l'application web.
- Il faut écrire un script SQL permettant de créer la BdD et ses tables, ainsi qu'un script python/js/shell/... (au choix) permettant de remplir les tables.
2.5°/ Création de l'application Web
ATTENTION ! Comme dit en introduction, cette application web doit être du type SPA, créée grâce à vuejs. Il n'y a donc techniquement qu'une seule page html qui est utilisée. Cependant, par commodité de langage, le terme page est utilisé dans la suite pour décrire le fait que le contenu de la fenêtre du navigateur va changer en fonction des actions de l'utilisateur, comme si on changeait effectivement de "page". |
2.5.1°/ la page d'accueil
- Créer des scripts python + modules, permettant de générer au moins 3 types de graphiques (par exemple, matplotlib, seaborn, plotly) grâce aux données de la BdD. Chaque script génère un graphique de type différent, selon les besoins applicatifs. Cela peut être par exemple un nuage de points, un histogramme, un diagramme à barres, etc.
- Ces graphiques doivent être "emblématiques" de ce que l'utilisateur pourra visualiser une fois qu'il sera logué. Ce sont donc des graphiques "publicitaires".
- Ces graphiques seront stockés sur le serveur API, qui fait également office de serveur Web. Ainsi, le navigateur pourra y accéder pour les afficher.
- La page d'accueil comporte globalement :
- un menu/bouton permettant d'accéder à une page d'authentification
- un texte présentant le site,
- un carrousel avec des images,
- Le carrousel contient les graphiques mentionnés ci-dessus.
- Pour le S3, l'URL des graphiques du carrousel ainsi que le texte de présentation peuvent être statiques.
- Pour le S4, ces URL et le texte doivent être stockés en BdD, afin que l'administrateur puisse les modifier via la page d'administration.
2.5.2°/ Authentification
- L'authentification doit se faire sur la base d'un couple login/mot de passe qui est saisi via un formulaire dans le front-end.
- Comme en S3, il n'y a pas de connexion à l'API demandée, la vérification de l'existence de ce couple doit se faire via la source de données locale.
- Si le couple est correct, cette vérification doit renvoyer les informations utilisateur (notamment son rôle) plus un identifiant "de session" (tiré aléatoirement), le tout étant sont stocké dans la mémoire locale du navigateur (soit dans un local storage, soit en mémoire applicative)
- Du côté API, une route doit permettre de recevoir un couple, de faire la même vérification et de renvoyer les informations utilisateur s'il existe.
- Pour le S4, le principe reste le même excepté que le front-end envoie réellement une requête à l'API et que celle-ci renvoie d'autres informations permettant de sécuriser les requêtes futures (jwt, id de session, ...)
2.5.4°/ Sécurisation des accès à l'API
- Les bases d'une sécurisation des accès à une API reposent sur l'envoi à chaque requête vers l'API d'une information permettant à cette dernière de vérifier si l'utilisateur front-end est authentifié ou non, et selon le cas d'autoriser ou non le traitement de la requête.
- Cette information peut être envoyée via l'URL, le corps de la requête, les headers, des cookies, etc.
- Pour le S3, un principe de sécurisation "à moitié fonctionnel" est le minimum demandé, sachant qu'il doit tenir compte de la contrainte du front-end et de l'API non connectés, mais qu'il soit facilement remplaçable par une sécurisation forte. Par exemple :
- Côté front-end :
- chaque fonction qui mime l'envoi d'une requête à l'API en allant chercher les données dans la source locale doit commencer par vérifier si l'utilisateur est authentifié et quels sont ces droits.
- cette vérification se base sur les informations reçues lors de l'authentification et stockées localement.
- si les droits sont adéquats, la fonction renvoie les données demandées, sinon une erreur.
- Côté API :
- on suppose que le front-end envoie l'identifiant de session obtenu lors de l'authentification, via la partie query de l'URL, par exemple : https://monapi.org/presta/1234?session=12abc45-953-cfb12
- on crée un middleware qui doit être appelé avant chaque fonction de contrôle qui nécessite des droits pour être exécutée.
- ce middleware se contente de vérifier si la variable session existe dans l'URL et dans ce cas, permet d'appeler le contrôleur. Sinon, il renvoie une erreur.
- Côté front-end :
- Pour le S4, il est demandé d'implémenter une méthode sécurisée (session, jwt, ...) comme vu en cours, ce qui nécessite des ajustements mineurs sur le front-end mais bien plus de travail côté API et BdD pour mettre en place le stockage des jwt/session et les contrôleurs qui vont les utiliser pour vérifier la validité d'un accès.
2.5.5°/ Les fonctionnalités utilisateur enregistré
Quand un utilisateur enregistré se logue, le menu doit changer pour permettre à l'utilisateur d'accéder à différentes fonctionnalités du site, c.a.d. visualiser différents types d'informations.
Ce menu doit au moins comporter :
- un item pour accéder à son profil utilisateur,
- un item pour se déloguer,
- un item pour afficher la page d'analyse descriptive
- des items pour visualiser un graphique créé dynamiquement.
Pour la page d'analyse descriptive, l'objectif est de récupérer des mesures statistiques (moyenne, médiane, mode, écart-type, ...). L'utilisateur doit pouvoir spécifier sur quel type de données (= table en BdD) et quelle donnée particulière (= champ de la table), il veut faire l'analyse. Ensuite, pour lancer cette analyse, il existe deux options :
- l'API fait l'analyse et renvoie les résultats au navigateur,
- l'API renvoie les enregistrements en BdD et c'est le navigateur qui calcule les mesures statistiques.
Dans les deux cas, cela doit être écrit en JS, mais rien n'empêche de trouver sur le web des modules JS qui font ce type de calcul.
NB : dans le rapport final, il faudra fournir une brève explication de chaque type d'analyse et du résultat attendu par rapport aux données utilisées.
Pour les pages de visualisation de données, l'objectif est de produire un ou plusieurs graphiques en fonction de filtres paramétrés par l'utilisateur. Ces graphiques peuvent être de tout type mais la contrainte est de les générer dans le navigateur, grâce à du JS ou bien du python. Avec du javascript, il faut forcément utiliser des modules disponibles sur le web pour se faciliter la tâche. Ces modules proposent plus ou moins de types de graphiques et sont plus ou moins interfacé avec vuejs. Pour le plus complet, mais malheureusement, le plus complexe à utiliser, on peut citer D3.js qui permet de créer quasi n'importe quel graphique, mais en le "dessinant". Il existe pas mal de tutoriels pour l'utiliser conjointement avec vuejs.
Quel que soit le module utilisé, le principe de fonctionnement de ces pages est le suivant :
- l'utilisateur peut modifier des filtres, présentés sous la forme de liste déroulante, champ de saisie, case à cocher, etc.
- il clique sur un bouton pour lancer la génération du graphique,
- cette génération est initiée en envoyant une requête à l'API vers une route dédiée, la requête contenant toutes les valeurs des filtres,
- l'API va interroger la BdD pour obtenir des données en fonction des filtres, puis renvoie ces données au navigateur,
- les données reçues par le navigateur servent à produire le graphique et l'afficher.
Il est également possible d'utiliser python, mais dans ce cas, l'API va exécuter un script python qui va lui-même récupérer les données puis générer une image en fonction des paramètres utilisateur. Une fois l'image créée et stockée, l'API peut renvoyer au front-end l'URL de cette image pour que le navigateur puisse la charger et l'afficher.
Pour le S3, il est demandé au minimum :
- la page d'analyse descriptive,
- 2 pages de visualisation, avec dans chacune au moins 2 critères de filtrage et 1 graphique affiché.
Pour le S4, il est demandé au minimum :
- 2 pages de visualisation supplémentaires, dont une contient au moins 3 critères de filtrage et 2 graphiques affichés.
- la page de profil avec la possibilité de changer son login/mot de passe.
2.5.6°/ Les fonctionnalités administrateur
Une fois logué, le menu doit changer pour permettre à l'administrateur d'accéder à des fonctionnalités qui lui sont propres
Ce menu doit au moins comporter :
- un item pour se déloguer,
- un item pour afficher la page des utilisateurs enregistrés
- un item pour afficher la page de modification du texte de la page d'accueil et des URLs des graphiques du carrousel.
La page des utilisateurs permet de les lister mais également de les supprimer, ou bien de modifier leur informations (par exemple, dans une boite de dialogue)
La page de modification du texte de la page d'accueil doit permettre d'éditer ce texte et d'enregistrer les modification en BdD.
Pour modifier les URLs des graphiques, il est demandé au minimum d'avoir des champs de saisie pour éditer l'URL de chaque graphique, mais aussi un moyen d'ajouter une nouvelle URL, ou d'en supprimer une. Une solution plus évoluée consiste à obtenir auprès de l'API la liste des graphiques disponibles au niveau du serveur et choisir lesquels on veut afficher dans le carrousel.
Pour le S3, il est demandé au minimum de :
- pouvoir lister les utilisateurs et de les supprimer,
- pouvoir modifier le texte d'accueil,
- pouvoir modifier les URLs des images du carrousel
Pour le S4, il est demandé au minimum de :
- pouvoir modifier les informations utilisateur,
- ajouter des URLs d'images
- modifier le texte de l'accueil via un éditeur wysiwyg intégrable dans une page web, tel que TinyMCE
2.6°/ Création de l'API
L'API doit être implémentée en nodejs + express afin de créer les routes et les contrôleurs nécessaires pour traiter toutes les requêtes possibles venant de l'application web. Cela implique notamment des routes pour :
- gérer l'inscription et l'authentification des utilisateurs (via login/mot de passe)
- récupérer/modifier le texte de la page d'accueil, et les URLs des images du carrousel,
- générer les résultats de l'analyse descriptive,
- générer les résultats de l'analyse exploratoire,
- générer les données nécessaires pour créer les graphiques dynamiquement.
- ...
Comme indiqué dans l'article Organisation de la SAÉ, avant même de coder la moindre route, il faut d'abord définir le format de ces routes (type de requête http, structure des données envoyées par le navigateur, ...) mais également le format JSON des réponses de chaque contrôleur. C'est la condition nécessaire pour pouvoir commencer l'implémentation de l'application web et de l'API en parallèle.
3°/ Pour aller plus loin
Pour les étudiants qui souhaitent se mettre davantage au défi, les tâches supplémentaires suivantes peuvent être ajoutées :
- Appliquer au moins un algorithme d'apprentissage automatique à la base de données pour des tâches de régression ou de classification (par exemple, arbre de décision, forêt aléatoire, XGBoost) :
- Entraîner l'algorithme en utilisant une partie de la base de données et le tester sur une autre partie.
- Evaluer les performances de l'algorithme et fournir une brève explication des résultats obtenus.
- Appliquer au moins une technique d'apprentissage profond, telle que les réseaux neuronaux convolutifs ou les réseaux neuronaux récurrents, aux données sélectionnées.
Ces tâches ne sont pas en lien direct avec l'application Web : ces apprentissages sont lancés directement sur la machine qui fait office de serveur API/BdD, par exemple en utilisant des scripts python. En revanche, les résultats de ces apprentissages peuvent très bien prendre la forme de graphiques qui sont intégrés à la page d'accueil de l'application web, ou bien être simplement de nouvelles données intégrées dans de nouvelles tables de la BdD, ce qui permet ensuite de les visualiser dans l'application.