devenirfantasma commited on
Commit
b6eb924
·
verified ·
1 Parent(s): 72422db

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -24
app.py CHANGED
@@ -48,20 +48,20 @@ class ComparadorSentimientos:
48
 
49
  def _cargar_modelos(self):
50
  """Carga ambos modelos una sola vez al inicio."""
51
- print("🚀 Cargando modelos de análisis de sentimiento...")
52
 
53
  for nombre, modelo_path in MODELOS.items():
54
- print(f" 📥 Cargando {nombre}: {modelo_path}")
55
  try:
56
  self.modelos[nombre] = pipeline(
57
  "sentiment-analysis", model=modelo_path, return_all_scores=False
58
  )
59
- print(f" {nombre} cargado exitosamente")
60
  except Exception as e:
61
- print(f" Error cargando {nombre}: {str(e)}")
62
  self.modelos[nombre] = None
63
 
64
- print("🎉 Modelos cargados!\n")
65
 
66
  def extraer_texto_web(self, url: str) -> str:
67
  """
@@ -85,7 +85,7 @@ class ComparadorSentimientos:
85
  return "❌ URL inválida"
86
 
87
  try:
88
- print(f"🌐 Extrayendo texto de: {url}")
89
 
90
  # Headers para evitar bloqueos
91
  headers = {
@@ -115,21 +115,77 @@ class ComparadorSentimientos:
115
  if len(texto_limpio) > 5000:
116
  texto_limpio = texto_limpio[:5000] + "..."
117
 
118
- print(f"Texto extraído: {len(texto_limpio)} caracteres")
119
  return texto_limpio
120
 
121
  except requests.exceptions.Timeout:
122
- return " Timeout: La página tardó demasiado en responder"
123
  except requests.exceptions.ConnectionError:
124
- return " Error de conexión: Verifica la URL"
125
  except requests.exceptions.HTTPError as e:
126
- return f" Error HTTP: {e}"
127
  except Exception as e:
128
- return f" Error inesperado: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  def analizar_texto(self, texto: str) -> Dict[str, Dict[str, float]]:
131
  """
132
- Analiza el sentimiento usando ambos modelos.
133
 
134
  Args:
135
  texto: Texto a analizar
@@ -146,6 +202,12 @@ class ComparadorSentimientos:
146
 
147
  resultados = {}
148
 
 
 
 
 
 
 
149
  for nombre_modelo, modelo in self.modelos.items():
150
  if modelo is None:
151
  resultados[nombre_modelo] = {"Error": 1.0}
@@ -153,17 +215,49 @@ class ComparadorSentimientos:
153
 
154
  try:
155
  inicio = time.time()
156
- resultado = modelo(texto)[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  tiempo = time.time() - inicio
158
 
159
  # Convertir etiqueta a español
160
- etiqueta_original = resultado["label"]
161
- etiqueta_es = ETIQUETAS_ES.get(etiqueta_original, etiqueta_original)
162
 
163
  resultados[nombre_modelo] = {
164
- etiqueta_es: round(resultado["score"], 4),
165
  "_tiempo": round(tiempo, 3),
166
- "_confianza": round(resultado["score"], 4),
 
 
167
  }
168
 
169
  except Exception as e:
@@ -193,28 +287,32 @@ def analizar_sentimiento(texto: str) -> Tuple[str, str]:
193
  beto_text = ""
194
 
195
  if "error" in resultados:
196
- robertuito_text = f" {resultados['error']}"
197
- beto_text = f" {resultados['error']}"
198
  else:
199
  # RoBERTuito
200
  robertuito = resultados.get("RoBERTuito", {"Error": 1.0})
201
  if "Error" in robertuito:
202
- robertuito_text = " Error en RoBERTuito"
203
  else:
204
  etiqueta = list(robertuito.keys())[0]
205
  confianza = robertuito[etiqueta]
206
  tiempo = robertuito.get("_tiempo", 0)
207
- robertuito_text = f"🎯 {etiqueta}: {confianza:.1%} ({tiempo:.2f}s)"
 
 
208
 
209
  # BETO
210
  beto = resultados.get("BETO", {"Error": 1.0})
211
  if "Error" in beto:
212
- beto_text = " Error en BETO"
213
  else:
214
  etiqueta = list(beto.keys())[0]
215
  confianza = beto[etiqueta]
216
  tiempo = beto.get("_tiempo", 0)
217
- beto_text = f"🎯 {etiqueta}: {confianza:.1%} ({tiempo:.2f}s)"
 
 
218
 
219
  return robertuito_text, beto_text
220
 
@@ -484,7 +582,7 @@ with gr.Blocks(
484
 
485
  # Punto de entrada
486
  if __name__ == "__main__":
487
- print("🚀 Iniciando aplicación de comparación de modelos...")
488
  demo.launch(
489
  server_name="0.0.0.0", # Para Hugging Face Spaces
490
  server_port=7860,
 
48
 
49
  def _cargar_modelos(self):
50
  """Carga ambos modelos una sola vez al inicio."""
51
+ print("Cargando modelos de analisis de sentimiento...")
52
 
53
  for nombre, modelo_path in MODELOS.items():
54
+ print(f" Cargando {nombre}: {modelo_path}")
55
  try:
56
  self.modelos[nombre] = pipeline(
57
  "sentiment-analysis", model=modelo_path, return_all_scores=False
58
  )
59
+ print(f" {nombre} cargado exitosamente")
60
  except Exception as e:
61
+ print(f" Error cargando {nombre}: {str(e)}")
62
  self.modelos[nombre] = None
63
 
64
+ print("Modelos cargados!\n")
65
 
66
  def extraer_texto_web(self, url: str) -> str:
67
  """
 
85
  return "❌ URL inválida"
86
 
87
  try:
88
+ print(f"Extrayendo texto de: {url}")
89
 
90
  # Headers para evitar bloqueos
91
  headers = {
 
115
  if len(texto_limpio) > 5000:
116
  texto_limpio = texto_limpio[:5000] + "..."
117
 
118
+ print(f"Texto extraido: {len(texto_limpio)} caracteres")
119
  return texto_limpio
120
 
121
  except requests.exceptions.Timeout:
122
+ return "ERROR: Timeout - La pagina tardo demasiado en responder"
123
  except requests.exceptions.ConnectionError:
124
+ return "ERROR: Error de conexion - Verifica la URL"
125
  except requests.exceptions.HTTPError as e:
126
+ return f"ERROR: Error HTTP: {e}"
127
  except Exception as e:
128
+ return f"ERROR: Error inesperado: {str(e)}"
129
+
130
+ def _chunk_text(self, texto: str, max_tokens: int = 400) -> list:
131
+ """
132
+ Divide texto largo en chunks más pequeños.
133
+
134
+ Args:
135
+ texto: Texto a dividir
136
+ max_tokens: Máximo tokens por chunk (aproximado)
137
+
138
+ Returns:
139
+ Lista de chunks de texto
140
+ """
141
+ # Aproximación: ~4 caracteres por token
142
+ max_chars = max_tokens * 4
143
+
144
+ if len(texto) <= max_chars:
145
+ return [texto]
146
+
147
+ # Dividir por oraciones para mantener contexto
148
+ oraciones = texto.split(".")
149
+ chunks = []
150
+ chunk_actual = ""
151
+
152
+ for oracion in oraciones:
153
+ oracion = oracion.strip() + "."
154
+
155
+ # Si agregar esta oración supera el límite, guardar chunk actual
156
+ if len(chunk_actual) + len(oracion) > max_chars and chunk_actual:
157
+ chunks.append(chunk_actual.strip())
158
+ chunk_actual = oracion
159
+ else:
160
+ chunk_actual += oracion
161
+
162
+ # Agregar último chunk
163
+ if chunk_actual:
164
+ chunks.append(chunk_actual.strip())
165
+
166
+ return chunks
167
+
168
+ def _analizar_chunk(self, modelo, chunk: str) -> Optional[Dict]:
169
+ """
170
+ Analiza un chunk individual de texto.
171
+
172
+ Args:
173
+ modelo: Pipeline de transformers
174
+ chunk: Chunk de texto a analizar
175
+
176
+ Returns:
177
+ Resultado del análisis o None si hay error
178
+ """
179
+ try:
180
+ resultado = modelo(chunk)[0]
181
+ return {"label": resultado["label"], "score": resultado["score"]}
182
+ except Exception as e:
183
+ print(f"Error analizando chunk: {str(e)}")
184
+ return None
185
 
186
  def analizar_texto(self, texto: str) -> Dict[str, Dict[str, float]]:
187
  """
188
+ Analiza el sentimiento usando ambos modelos con chunking para textos largos.
189
 
190
  Args:
191
  texto: Texto a analizar
 
202
 
203
  resultados = {}
204
 
205
+ # Límites de tokens para cada modelo
206
+ limites_tokens = {
207
+ "RoBERTuito": 400, # Más conservador que 512
208
+ "BETO": 100, # Más conservador que 128
209
+ }
210
+
211
  for nombre_modelo, modelo in self.modelos.items():
212
  if modelo is None:
213
  resultados[nombre_modelo] = {"Error": 1.0}
 
215
 
216
  try:
217
  inicio = time.time()
218
+
219
+ # Dividir texto en chunks según límite del modelo
220
+ chunks = self._chunk_text(texto, limites_tokens[nombre_modelo])
221
+
222
+ print(f"Procesando {len(chunks)} chunks con {nombre_modelo}")
223
+
224
+ # Analizar cada chunk
225
+ resultados_chunks = []
226
+ for i, chunk in enumerate(chunks):
227
+ resultado = self._analizar_chunk(modelo, chunk)
228
+ if resultado:
229
+ resultados_chunks.append(resultado)
230
+
231
+ if not resultados_chunks:
232
+ resultados[nombre_modelo] = {
233
+ "Error": 1.0,
234
+ "_error": "No se pudo procesar ningún chunk",
235
+ }
236
+ continue
237
+
238
+ # Combinar resultados (votación mayoritaria + promedio de confianza)
239
+ votos = {"POS": 0, "NEG": 0, "NEU": 0}
240
+ suma_confianza = 0
241
+
242
+ for resultado in resultados_chunks:
243
+ votos[resultado["label"]] += 1
244
+ suma_confianza += resultado["score"]
245
+
246
+ # Determinar etiqueta ganadora
247
+ etiqueta_ganadora = max(votos, key=votos.get)
248
+ confianza_promedio = suma_confianza / len(resultados_chunks)
249
+
250
  tiempo = time.time() - inicio
251
 
252
  # Convertir etiqueta a español
253
+ etiqueta_es = ETIQUETAS_ES.get(etiqueta_ganadora, etiqueta_ganadora)
 
254
 
255
  resultados[nombre_modelo] = {
256
+ etiqueta_es: round(confianza_promedio, 4),
257
  "_tiempo": round(tiempo, 3),
258
+ "_confianza": round(confianza_promedio, 4),
259
+ "_chunks_procesados": len(resultados_chunks),
260
+ "_total_chunks": len(chunks),
261
  }
262
 
263
  except Exception as e:
 
287
  beto_text = ""
288
 
289
  if "error" in resultados:
290
+ robertuito_text = f"ERROR: {resultados['error']}"
291
+ beto_text = f"ERROR: {resultados['error']}"
292
  else:
293
  # RoBERTuito
294
  robertuito = resultados.get("RoBERTuito", {"Error": 1.0})
295
  if "Error" in robertuito:
296
+ robertuito_text = "ERROR en RoBERTuito"
297
  else:
298
  etiqueta = list(robertuito.keys())[0]
299
  confianza = robertuito[etiqueta]
300
  tiempo = robertuito.get("_tiempo", 0)
301
+ chunks = robertuito.get("_chunks_procesados", 1)
302
+ total_chunks = robertuito.get("_total_chunks", 1)
303
+ robertuito_text = f"-> {etiqueta}: {confianza:.1%} ({tiempo:.2f}s, {chunks}/{total_chunks} chunks)"
304
 
305
  # BETO
306
  beto = resultados.get("BETO", {"Error": 1.0})
307
  if "Error" in beto:
308
+ beto_text = "ERROR en BETO"
309
  else:
310
  etiqueta = list(beto.keys())[0]
311
  confianza = beto[etiqueta]
312
  tiempo = beto.get("_tiempo", 0)
313
+ chunks = beto.get("_chunks_procesados", 1)
314
+ total_chunks = beto.get("_total_chunks", 1)
315
+ beto_text = f"-> {etiqueta}: {confianza:.1%} ({tiempo:.2f}s, {chunks}/{total_chunks} chunks)"
316
 
317
  return robertuito_text, beto_text
318
 
 
582
 
583
  # Punto de entrada
584
  if __name__ == "__main__":
585
+ print("Iniciando aplicacion de comparacion de modelos...")
586
  demo.launch(
587
  server_name="0.0.0.0", # Para Hugging Face Spaces
588
  server_port=7860,