Tracy André commited on
Commit
abe61e5
·
1 Parent(s): aa9c0ca
Files changed (2) hide show
  1. app.py +112 -38
  2. requirements.txt +2 -1
app.py CHANGED
@@ -12,7 +12,7 @@ from plotly.subplots import make_subplots
12
  import warnings
13
  from datasets import load_dataset
14
  import pandas as pd
15
- from huggingface_hub import HfApi
16
  import urllib.parse
17
  warnings.filterwarnings('ignore')
18
 
@@ -31,61 +31,135 @@ class AgricultureAnalyzer:
31
 
32
  def load_data(self):
33
  """Charge les données du dataset Hugging Face"""
 
 
 
 
 
 
 
34
  try:
35
- print("🔄 Chargement des données depuis Hugging Face...")
36
- print(f"📋 Dataset ID: {dataset_id}")
37
- print(f"📋 Token disponible: {'Oui' if hf_token else 'Non'}")
38
-
39
- # Tentative de chargement direct
40
  dataset = load_dataset(
41
- dataset_id,
42
- split="train",
43
- token=hf_token
 
44
  )
45
-
46
  print(f"📊 Dataset chargé: {len(dataset)} exemples")
47
-
48
- # Conversion en pandas avec gestion d'erreur
49
  try:
50
  self.df = dataset.to_pandas()
51
  print("✅ Conversion to_pandas() réussie")
52
  except Exception as pandas_error:
53
  print(f"❌ Erreur to_pandas(): {pandas_error}")
54
  print("🔄 Tentative de conversion manuelle...")
55
-
56
- # Conversion manuelle
57
  data_list = []
58
  for i, item in enumerate(dataset):
59
  data_list.append(item)
60
- if i < 5: # Afficher les 5 premiers pour debug
61
  print(f"📋 Exemple {i}: {list(item.keys())}")
62
-
63
  self.df = pd.DataFrame(data_list)
64
  print(f"✅ Conversion manuelle réussie: {len(self.df)} lignes")
65
-
66
- print(f"📊 Données chargées: {len(self.df)} lignes")
67
- print(f"📊 Colonnes disponibles: {list(self.df.columns)}")
68
-
69
- # Nettoyage et validation
70
- required_columns = ["numparcell", "surfparc", "millesime"]
71
- missing_cols = [col for col in required_columns if col not in self.df.columns]
72
-
73
- if missing_cols:
74
- print(f"❌ Colonnes manquantes: {missing_cols}")
75
- self.df = None
76
- return f"❌ Colonnes manquantes: {missing_cols}"
77
-
78
- # Nettoyage
79
- initial_len = len(self.df)
80
- self.df = self.df.dropna(subset=required_columns)
81
-
82
- print(f"📊 Avant nettoyage: {initial_len} lignes")
83
- print(f"📊 Après nettoyage: {len(self.df)} lignes")
84
  except Exception as e:
85
  print(f"❌ Erreur lors du chargement depuis Hugging Face: {str(e)}")
86
  print(f"❌ Type d'erreur: {type(e).__name__}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  self.df = None
88
- return f"❌ Erreur lors du chargement du dataset : {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
 
91
  def analyze_data(self):
@@ -414,7 +488,7 @@ def create_interface():
414
  """)
415
 
416
  with gr.TabItem("🌾 Recommandations"):
417
- gr.Markdown(analyzer.get_low_risk_recommendations())
418
 
419
  gr.Markdown("""
420
  ## 💡 Conseils pour la gestion des adventices
@@ -485,7 +559,7 @@ def create_interface():
485
 
486
  refresh_btn.click(
487
  refresh_data,
488
- outputs=[stats_output, culture_plot, risk_dist_plot, risk_plot]
489
  )
490
 
491
  return demo
 
12
  import warnings
13
  from datasets import load_dataset
14
  import pandas as pd
15
+ from huggingface_hub import HfApi, hf_hub_download
16
  import urllib.parse
17
  warnings.filterwarnings('ignore')
18
 
 
31
 
32
  def load_data(self):
33
  """Charge les données du dataset Hugging Face"""
34
+ print("🔄 Chargement des données depuis Hugging Face...")
35
+ print(f"📋 Dataset ID: {dataset_id}")
36
+ print(f"📋 Token disponible: {'Oui' if hf_token else 'Non'}")
37
+
38
+ self.df = None
39
+
40
+ # 1) Tentative de chargement direct via datasets.load_dataset
41
  try:
 
 
 
 
 
42
  dataset = load_dataset(
43
+ dataset_id,
44
+ split="train",
45
+ token=hf_token,
46
+ trust_remote_code=True,
47
  )
 
48
  print(f"📊 Dataset chargé: {len(dataset)} exemples")
49
+
 
50
  try:
51
  self.df = dataset.to_pandas()
52
  print("✅ Conversion to_pandas() réussie")
53
  except Exception as pandas_error:
54
  print(f"❌ Erreur to_pandas(): {pandas_error}")
55
  print("🔄 Tentative de conversion manuelle...")
 
 
56
  data_list = []
57
  for i, item in enumerate(dataset):
58
  data_list.append(item)
59
+ if i < 5:
60
  print(f"📋 Exemple {i}: {list(item.keys())}")
 
61
  self.df = pd.DataFrame(data_list)
62
  print(f"✅ Conversion manuelle réussie: {len(self.df)} lignes")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  except Exception as e:
64
  print(f"❌ Erreur lors du chargement depuis Hugging Face: {str(e)}")
65
  print(f"❌ Type d'erreur: {type(e).__name__}")
66
+ # 2) Fallback: récupérer directement les fichiers du repo (csv/parquet/tsv/json)
67
+ fallback_msg = self._fallback_load_from_repo_files()
68
+ if self.df is None:
69
+ return f"❌ Erreur lors du chargement du dataset : {str(e)} | Fallback: {fallback_msg}"
70
+
71
+ # Si on n'a toujours pas de dataframe, arrêter
72
+ if self.df is None:
73
+ return "❌ Impossible de charger les données"
74
+
75
+ print(f"📊 Données chargées: {len(self.df)} lignes")
76
+ print(f"📊 Colonnes disponibles: {list(self.df.columns)}")
77
+
78
+ # Nettoyage et validation
79
+ required_columns = ["numparcell", "surfparc", "millesime"]
80
+ missing_cols = [col for col in required_columns if col not in self.df.columns]
81
+
82
+ if missing_cols:
83
+ print(f"❌ Colonnes manquantes: {missing_cols}")
84
  self.df = None
85
+ return f"❌ Colonnes manquantes: {missing_cols}"
86
+
87
+ # Nettoyage
88
+ initial_len = len(self.df)
89
+ self.df = self.df.dropna(subset=required_columns)
90
+
91
+ print(f"📊 Avant nettoyage: {initial_len} lignes")
92
+ print(f"📊 Après nettoyage: {len(self.df)} lignes")
93
+
94
+ def _fallback_load_from_repo_files(self):
95
+ """Fallback pour charger les données en téléchargeant directement les fichiers du repo HF."""
96
+ try:
97
+ print("🔄 Tentative de chargement alternatif via fichiers du dépôt Hugging Face...")
98
+ api = HfApi()
99
+ files = api.list_repo_files(repo_id=dataset_id, repo_type="dataset", token=hf_token)
100
+ if not files:
101
+ print("❌ Aucun fichier dans le dépôt")
102
+ return "Aucun fichier trouvé dans le dép��t."
103
+
104
+ data_files = [
105
+ f for f in files if f.lower().endswith((".parquet", ".csv", ".tsv", ".json"))
106
+ ]
107
+ if not data_files:
108
+ print("❌ Aucun fichier de données exploitable (csv/tsv/parquet/json)")
109
+ return "Aucun fichier exploitable (csv/tsv/parquet/json)."
110
+
111
+ # Priorité: parquet > csv > tsv > json
112
+ for ext in [".parquet", ".csv", ".tsv", ".json"]:
113
+ selected = [f for f in data_files if f.lower().endswith(ext)]
114
+ if selected:
115
+ chosen_ext = ext
116
+ selected_files = selected
117
+ break
118
+
119
+ print(f"📂 Fichiers détectés ({chosen_ext}): {selected_files[:5]}{' ...' if len(selected_files) > 5 else ''}")
120
+
121
+ local_paths = []
122
+ for f in selected_files:
123
+ local_path = hf_hub_download(
124
+ repo_id=dataset_id,
125
+ repo_type="dataset",
126
+ filename=f,
127
+ token=hf_token,
128
+ )
129
+ local_paths.append(local_path)
130
+
131
+ frames = []
132
+ if chosen_ext == ".parquet":
133
+ for p in local_paths:
134
+ frames.append(pd.read_parquet(p))
135
+ elif chosen_ext == ".csv":
136
+ for p in local_paths:
137
+ frames.append(pd.read_csv(p))
138
+ elif chosen_ext == ".tsv":
139
+ for p in local_paths:
140
+ frames.append(pd.read_csv(p, sep="\t"))
141
+ elif chosen_ext == ".json":
142
+ for p in local_paths:
143
+ try:
144
+ frames.append(pd.read_json(p, lines=True))
145
+ except Exception:
146
+ frames.append(pd.read_json(p))
147
+
148
+ self.df = pd.concat(frames, ignore_index=True) if len(frames) > 1 else frames[0]
149
+ print(f"✅ Fallback réussi: {len(self.df)} lignes chargées depuis les fichiers du dépôt")
150
+ return None
151
+ except Exception as e:
152
+ print(f"❌ Fallback échoué: {e}")
153
+ # Dernier recours: fichier local d'exemple
154
+ sample_path = os.path.join(os.path.dirname(__file__), "sample_data.csv")
155
+ if os.path.exists(sample_path):
156
+ try:
157
+ self.df = pd.read_csv(sample_path)
158
+ print(f"✅ Chargement du fichier local 'sample_data.csv' ({len(self.df)} lignes)")
159
+ return "Chargement via fichier local de secours."
160
+ except Exception as e2:
161
+ print(f"❌ Échec du chargement du fichier local: {e2}")
162
+ return f"Fallback échoué: {e}"
163
 
164
 
165
  def analyze_data(self):
 
488
  """)
489
 
490
  with gr.TabItem("🌾 Recommandations"):
491
+ reco_output = gr.Markdown(analyzer.get_low_risk_recommendations())
492
 
493
  gr.Markdown("""
494
  ## 💡 Conseils pour la gestion des adventices
 
559
 
560
  refresh_btn.click(
561
  refresh_data,
562
+ outputs=[stats_output, culture_plot, risk_dist_plot, risk_plot, reco_output]
563
  )
564
 
565
  return demo
requirements.txt CHANGED
@@ -7,4 +7,5 @@ plotly>=5.0.0
7
  scipy>=1.7.0
8
  scikit-learn>=1.0.0
9
  datasets>=2.0.0
10
- huggingface_hub>=0.16.0
 
 
7
  scipy>=1.7.0
8
  scikit-learn>=1.0.0
9
  datasets>=2.0.0
10
+ huggingface_hub>=0.16.0
11
+ pyarrow>=14.0.0