dataforgoodfr / 12_zero_dechet_sauvage

MIT License
4 stars 1 forks source link

nettoyage et augmentation des données #2

Open KyllianBeguin opened 6 months ago

KyllianBeguin commented 6 months ago

❓ Contexte

Après avoir exploré nos données, nous avons dressé un ensemble de constats concernant la qualité des données. De ces constats, il faut mettre en place un flux de nettoyage et d'augmentation des données, ainsi que les charger dans une base qui servira d'entrant pour l'application de visualisation.

🧐 Objectifs

  1. Nettoyer les données
  2. Augmenter les données
  3. Les charger dans une base mariadb

💪 ToDo

florianeduccini commented 6 months ago

### Première passe de nettoyage et augmentation des données

Un nouveau fichier excel tenant compte de toutes ces modifications a été enregistré sous le nom data_zds_enriched.xlsx

KyllianBeguin commented 6 months ago

En re-regardant le jeu de données, y a un truc qui me fait peur : y a pas mal de colonnes...
Est-ce que l'on pourrait dépivoter tout ça ?

Exemple

Avant ID_EVENEMENT SACS_VOLUME_METAL NB_DECHET_GROUPE_AUTRES OBJETS EN MÉTAL
1 101 76
2 202 98
3 303 NaN
Après ID_EVENEMENT RELEVE_ITEM RELEVE_VALEUR
1 SACS_VOLUME_METAL 101
2 SACS_VOLUME_METAL 202
3 SACS_VOLUME_METAL 303
1 NB_DECHET_GROUPE_AUTRES OBJETS EN MÉTAL 76
2 NB_DECHET_GROUPE_AUTRES OBJETS EN MÉTAL 98
3 NB_DECHET_GROUPE_AUTRES OBJETS EN MÉTAL NaN

👉 En faisant cela, on gagnerait en efficacité pour la création des filtres

On pourrait même couper l'information contenue dans RELEVE_ITEM, dans deux colonnes, pour avoir une catégorie mère, par exemple : ID_EVENEMENT RELEVE_CATEGORY RELEVE_ITEM RELEVE_VALEUR
1 SACS_VOLUME METAL 101
1 NB_DECHET_GROUPE_AUTRES OBJETS EN MÉTAL 76
tgazagnes commented 5 months ago

Je suis d'accord, pour faciliter les graphiques et les filtres il faudrait retravailler la base pour avoir a minima les colonnes suivantes :

florianeduccini commented 5 months ago

Hello, Pour simplifier la base et éviter d'avoir une table avec 1412 colonnes comme c'est le cas actuellement nous pourrions au moins séparer la base en deux :

Cette seconde base aurait les colonnes suivantes :

L'intérêt de cette modélisation est qu'on pourrait supprimer pas mal d'information car on ne garderait que les lignes pour lesquelles le nb de déchets est non nul. De plus les colonnes nb_déchets ne vont pas être utilisé pour tous les onglets on pourrait donc travailler avec une base beaucoup plus légère.

On pourrait aller plus loin effectivement et remettre en long les colonnes de types "sac", "volume" et "poids" mais à mon sens travailler avec une base d'une centaine de colonnes reste gérable, je n'irais pas complexifier la modélisation pour ça. On peut en discuter si les avis divergent sur ce point :)

florianeduccini commented 5 months ago

Hello, Je viens de push un nouveau commit il contient :

Le chargement de ces 2 nouvelles tables prend 3 secondes versus plus de 2 minutes pour l'ancienne table.

KyllianBeguin commented 5 months ago

Le chargement de ces 2 nouvelles tables prend 3 secondes versus plus de 2 minutes pour l'ancienne table.

Belle progression ! Merci @florianeduccini 💪

tgazagnes commented 5 months ago

Merci Floriane ! Petite question de git noob : quelle est la meilleure pratique selon vous pour récupérer ces bases sur la branche 1-exploration : on merge et on re-fork, ou on fait un git fetch spécifique ?

KyllianBeguin commented 5 months ago

git pull :) @tgazagnes

KyllianBeguin commented 5 months ago

Bonne nouvelle, on va avoir une base de données ! Ce qui veut dire que dès qu'on aura l'accès, on pousse les données dessus et plus sur le git. Il faudra également penser à la manière de capter les données entrantes : récupération sur un Sharepoint, un bucket ?

florianeduccini commented 5 months ago

Sait-on où on va déployer l'app ? (Pour savoir si on peut garder le process d'etl avant chargement dans la base de données en python ou s'il va falloir tout traduire en SQL). Et sinon oui j'imagine qu'il faudra aller déposer les données sur un Sharepoint ou un bucket OU prévoir une page du dashboard "ingestion de données" qui ne soient dispo que pour les admins pour qu'ils puissent insérer de nouveaux fichiers?

KyllianBeguin commented 5 months ago

L'app étant conteneurisée, la question ne se pose pas. On peut la déployer sur une VM hébergée chez Scaleway je pense.

Pour le process d'ETL, on peut le packager dans la VM et l'orchestrer comme on veut, genre avec un job CRON, ou un airflow. Bonne idée le dépôt de fichier. On peut de ce fait imaginer de lancer l'ETL lors du chargement du fichier, histoire de ne pas lancer le flux quand les données ne sont pas maj

KyllianBeguin commented 5 months ago

On déménage 🚚🚚

Je vais organiser le repo + mettre en place un outil de Data Engineering
Évitez de toucher à code en attendant 🙏

Mendi33 commented 5 months ago

Hello. Pour l'onglet ACTIONS, j'ai besoin du fichier _export_events14032024.xlsx (dispo sur le sharepoint)

J'ai déjà fait le nettoyage :

Questions : Est-ce je met mon script à la suite dans cleaning.py ou je créer le mien ?

KyllianBeguin commented 5 months ago

Hello @Mendi33 ! Je t'invite à pousser ton code dans un fichier dédié et isolé de cleaning.py Je t'ai ouvert les droits pour pouvoir pousser sur cette branche 👍🏻

KyllianBeguin commented 5 months ago

Je viens de tester la migration du code dans un pipeline Mage, sauf que ça ne se passe pas hyper bien pour la partie jeux de données géographiques 😅 L'erreur est à ce niveau :

gdf_data_zds = gpd.GeoDataFrame(data, geometry=geometry, crs=data_2.crs)
______________________
DriverSupportError: ESRI Shapefile does not support datetime fields

Je vais pousser mon code histoire que vous puissiez tester de votre côté. J'ai l'impression que l'erreur viens de Mage

Je verrai plus tard pour cette erreur

linh-dinh-1012 commented 5 months ago

Bonjour,

Je voulais signaler une petite coquille dans le fichier data_zds_enriched.csv. Sur la ligne où ID_RELEVE == 404, le LIEU_VILLE est indiqué comme Monaco.. J'ai vérifié les coordonnées GPS fournies et elles correspondent effectivement à Monaco, et non à la France.

tgazagnes commented 5 months ago

Hello, Pour les besoins d'ergonomie dans les filtres géographiques, j'ai créé deux nouvelles colonnes qui concatenent le numéro INSEE et le nom de l'entité géographique (ex : 13 - Bouches du Rhône). C'est plus facile de s'y retrouver lorsqu'on cherche parmi les 100 départements. Si on valide le besoin pour tous les onglets, ça vaut le coup de l'ajouter dans les transfo amont ?

df_other["DEP_CODE_NOM"] = df_other["DEP"] + " - " + df_other["DEPARTEMENT"]

df_other["COMMUNE_CODE_NOM"] = df_other["INSEE_COM"] + " - " + df_other["commune"]

Mendi33 commented 5 months ago

Re, Concernant l'ajout des colonnes EPCI, Bassin de vie, ... dans nos 3 fichiers (data_zds, events et structures). Je me demandai s'il ne serait pas plus judicieux de faire une seule fonction pour le faire dans nos 3 fichiers ?

@florianeduccini il faudrait renommer les colonnes de coordonnées GPS comme dans le fichier data_ZDS mais je ne sais pas s'il y a d'autres colonnes à prendre en compte ?

florianeduccini commented 5 months ago

Hello @Mendi33, Si complètement ! J'attends de set up mon ordi avec mage et j'utiliserai la même brique pour les 4 pipelines :)

florianeduccini commented 5 months ago

Rajout de la partie pipeline de données pour la table structure. L'export vers la bdd ne fonctionne pas encore pour cause erreur étrange lors de l'export. @KyllianBeguin peux-tu checker?

KyllianBeguin commented 4 months ago

J'ai regardé ton pipeline @florianeduccini mais j'ai un truc que je n'arrive pas à comprendre. J'ai eu des erreurs que j'ai fix, mais sur le filtre distance, le block me retourne une liste vide.

KyllianBeguin commented 4 months ago

J'ai corrigé quelques coquilles dans des blocks 157e576aaa9f349b7fa4d2e0509d61090fd7504e : le nom de la colonne GPS_X est changé 2 fois, alors que la GPS_Y 0. Donc GPS_Y → latitude f5d737a97a9ded9b435587c7a9b4c42761725721 : maj des tableaux en entrés pour garder une cohérence avec l'autre pipeline cleaning. La doc est également maj pour spécifier l'ordre des tableaux

KyllianBeguin commented 4 months ago

Il semblerait qu'une colonne ne passe pas dans l'export.

Les types de colonnes 👇 ``` COLONNE TYPE ID_STRUCT int64 NOM_structure object SOUS_TYPE object TYPE object ADRESSE object CODE_POSTA float64 DEPT object REGION object DATE_INSCR object ACTION_RAM int64 A1S_NB_SPO int64 CARACT_ACT int64 CARACT_NB_ int64 CARACT_N_1 int64 CARACT_N_2 int64 CARACT_N_3 int64 longitude float64 latitude float64 index_righ int64 ID object COMMUNE object NOM_M object INSEE_COM object STATUT object POPULATION int64 INSEE_CAN object INSEE_ARR object INSEE_DEP object INSEE_REG object SIREN_EPCI object dep object reg int64 epci object nature_epc object libepci object departemen object region object ```

En fait, on dirait qu'il essaye de charger un truc qui est dataframe...

KyllianBeguin commented 4 months ago

J'ai testé d'exporter les colonnes une à une et ça fonctionne.

Le code pour reproduire le résultat 👇 ```python @data_exporter def export_data_to_mysql(df: DataFrame, **kwargs) -> None: """ Template for exporting data to a MySQL database. Specify your configuration settings in 'io_config.yaml'. Docs: https://docs.mage.ai/design/data-loading#mysql """ table_name = "data_structures" # Specify the name of the table to export data to config_path = path.join(get_repo_path(), "io_config.yaml") config_profile = "default" import pandas as pd from time import sleep for col in df.columns: print(col) with MySQL.with_config(ConfigFileLoader(config_path, config_profile)) as loader: loader.export( pd.DataFrame({col: df[col]}), None, table_name, index=False, # Specifies whether to include index in exported table if_exists="replace", # Specify resolution policy if table name already exists ) sleep(1) print(" ") ```

En regardant le Dataframe, j'ai constaté :

Vu que tu es dessus @florianeduccini, est-ce que tu gères ces observations ? Ou est-ce que j'interviens ?

florianeduccini commented 4 months ago

@KyllianBeguin : je regarde ça et je te dis dès que j'arrive à exporter :)

KyllianBeguin commented 4 months ago

To do : Exploration_visualisation/data/export_events_14032024.xlsx:

florianeduccini commented 4 months ago

@KyllianBeguin : on est d'accord que sur ta TODO c'est lorsqu'on intègrera le cleaning de l'export d'events dans mage?

florianeduccini commented 4 months ago

Hello, Je viens de prendre en compte les modifications sur la pipeline de cleaning des structures. Je n'ai gardé que les colonnes nécessaires. L'export fonctionne bien. Je n'ai par contre pas pu tester de relancer la pipeline de cleaning des ramassages parce que le code tourne pendant des heures sur Mage sans me donner d'erreurs...

KyllianBeguin commented 4 months ago

Je n'ai par contre pas pu tester de relancer la pipeline de cleaning des ramassages parce que le code tourne pendant des heures sur Mage sans me donner d'erreurs...

Est-ce sur tout le pipeline ? Ou juste sur un block ?

@KyllianBeguin : on est d'accord que sur ta TODO c'est lorsqu'on intègrera le cleaning de l'export d'events dans mage?

Exactement ! Le cleaning de l'export est dans le backlog, on anticipe juste les traitement à appliquer 😃

florianeduccini commented 4 months ago

Je n'ai par contre pas pu tester de relancer la pipeline de cleaning des ramassages parce que le code tourne pendant des heures sur Mage sans me donner d'erreurs...

Est-ce sur tout le pipeline ? Ou juste sur un block ?

Les deux, j'ai lancé au global puis juste un block qui aurait du mettre 10 secondes à tourner et au bout de 10 minutes j'ai du couper.

KyllianBeguin commented 4 months ago

Ok, pcq y les blocks qui traitent les données géographiques sont longs à se lancer ^^

KyllianBeguin commented 4 months ago

Histoire d'anticiper la migration des sources de données de l'appli, je vous propose de faire le listing des sources actuelle et le mapping vers les table de la bdd.
Cela nous permettra aussi d'avoir une idée de ce qui doit faire tourner l'appli


SCRIPT-STAGING FILE-BRANCH FILE-PATH FILE-NAME
🏠 2 /Exploration_visualisation/data/ data_zds_enriched.csv
🏠 4 /Exploration_visualisation/data/ structures_export_cleaned.csv
🏠 2 /Exploration_visualisation/data/ data_releve_nb_dechet.csv
👊 2 /Exploration_visualisation/data/ export_events_cleaned.csv
🔎 1 /Exploration_visualisation/data/ dict_dechet_groupe_materiau.csv
🔥 2 /Exploration_visualisation/data/ data_releve_nb_dechet.csv
🔥 2 /Exploration_visualisation/data/ data_zds_enriched.csv
🔥 1 /Exploration_visualisation/data/ regions-avec-outre-mer.geojson
🔥 1 /Exploration_visualisation/data/ departements-avec-outre-mer.geojson
🔥 1 /Exploration_visualisation/data/ communes-avec-outre-mer.geojson
🔥 1 /Exploration_visualisation/data/ communes-avec-outre-mer.geojson
🔥 1 /Exploration_visualisation/data/ releves_corrects_surf_lineaire.xlsx
🔥 1 /Exploration_visualisation/data/ export_structures_29022024.xlsx
🔭 - - -

Les scripts sont ceux du staging : 🏠 home.py 👊 actions.py 🔎 data.py 🔥 hotspots.py 🔭 structures.py

KyllianBeguin commented 4 months ago

Vu dans la PR #20 : Il faudra faire migrer la fonction process_data dans le flux pour alléger l'appli

KyllianBeguin commented 3 months ago
Pour s'assurer que tous les fichiers sont bien migrés, je vous propose ce tableau : FILE-NAME PIPELINE-NAME TABLE-NAME IS-COMPLETE
structures_export_cleaned.csv
export_events_cleaned.csv
dict_dechet_groupe_materiau.csv
data_releve_nb_dechet.csv cleaning (data_enriched, nb_dechets)
data_zds_enriched.csv cleaning (data_enriched, nb_dechets)
regions-avec-outre-mer.geojson
departements-avec-outre-mer.geojson
communes-avec-outre-mer.geojson
releves_corrects_surf_lineaire.xlsx
export_structures_29022024.xlsx
florianeduccini commented 3 months ago

Hey ! Super oui on sera plus au clair :) Tu es sûr qu'il faille structures_export_cleaned ET export_structures_29022024? Et sinon je suis en train d'essayer de mettre les données géographiques en base, ça remplacera régions_avec_outre_er, departements_xx et communes_xx

KyllianBeguin commented 3 months ago

Tu es sûr qu'il faille structures_export_cleaned ET export_structures_29022024?

J'ai repris le tableau de référencement des jeux de données présents dans l'appli, qui comprends les deux fichiers.
En les laissant, on va pouvoir plus facilement changer les deux fichiers dans l'appli en mettant la même table d'export structure :)