Spaces:
Sleeping
Sleeping
Upload 2 files
Browse files- app.py +402 -0
- requirements.txt +7 -0
app.py
ADDED
@@ -0,0 +1,402 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import pandas as pd
|
3 |
+
import spacy
|
4 |
+
from textblob import TextBlob
|
5 |
+
from transformers import pipeline
|
6 |
+
import torch
|
7 |
+
from io import BytesIO
|
8 |
+
import numpy as np
|
9 |
+
|
10 |
+
# Cargar modelos
|
11 |
+
print("⏳ Cargando modelos...")
|
12 |
+
|
13 |
+
# 1. Cargar modelo de spaCy para español
|
14 |
+
try:
|
15 |
+
nlp = spacy.load("es_core_news_sm")
|
16 |
+
print("✅ Modelo spaCy cargado correctamente")
|
17 |
+
except OSError:
|
18 |
+
print("❌ Modelo spaCy no encontrado. Usando análisis básico...")
|
19 |
+
nlp = None
|
20 |
+
|
21 |
+
# 2. Cargar múltiples modelos de sentimiento
|
22 |
+
models = {}
|
23 |
+
|
24 |
+
# Modelo multilingüe principal
|
25 |
+
try:
|
26 |
+
models['multilingual'] = pipeline(
|
27 |
+
"text-classification",
|
28 |
+
model="tabularisai/multilingual-sentiment-analysis"
|
29 |
+
)
|
30 |
+
print("✅ Modelo multilingüe cargado")
|
31 |
+
except Exception as e:
|
32 |
+
print(f"❌ Error con modelo multilingüe: {e}")
|
33 |
+
models['multilingual'] = None
|
34 |
+
|
35 |
+
# Modelo BERT para sentimiento detallado
|
36 |
+
try:
|
37 |
+
models['bert'] = pipeline(
|
38 |
+
"sentiment-analysis",
|
39 |
+
model="nlptown/bert-base-multilingual-uncased-sentiment",
|
40 |
+
tokenizer="nlptown/bert-base-multilingual-uncased-sentiment"
|
41 |
+
)
|
42 |
+
print("✅ Modelo BERT cargado")
|
43 |
+
except Exception as e:
|
44 |
+
print(f"❌ Error con modelo BERT: {e}")
|
45 |
+
models['bert'] = None
|
46 |
+
|
47 |
+
# Diccionario léxico mejorado para español
|
48 |
+
palabras_positivas = {
|
49 |
+
'bueno', 'excelente', 'fantástico', 'maravilloso', 'perfecto', 'genial',
|
50 |
+
'increíble', 'amo', 'encanta', 'feliz', 'contento', 'satisfecho', 'agradable',
|
51 |
+
'recomiendo', 'magnífico', 'extraordinario', 'asombroso', 'increíble', 'estupendo',
|
52 |
+
'fabril', 'perfectamente', 'óptimo', 'superior', 'mejor', 'inmejorable', 'ideal'
|
53 |
+
}
|
54 |
+
|
55 |
+
palabras_negativas = {
|
56 |
+
'malo', 'terrible', 'horrible', 'pésimo', 'odio', 'decepcionado', 'fatal',
|
57 |
+
'triste', 'enojado', 'frustrado', 'pobre', 'deficiente', 'desastroso',
|
58 |
+
'insatisfecho', 'decepcionante', 'horroroso', 'desastroso', 'pésimo', 'malísimo',
|
59 |
+
'inútil', 'defectuoso', 'deplorable', 'lamentable', 'desagradable', 'terrible'
|
60 |
+
}
|
61 |
+
|
62 |
+
def analizar_sentimiento_multimodelo(texto):
|
63 |
+
"""Combina múltiples métodos para análisis más preciso"""
|
64 |
+
resultados = {}
|
65 |
+
|
66 |
+
# Método 1: Modelo multilingüe principal
|
67 |
+
if models['multilingual']:
|
68 |
+
try:
|
69 |
+
resultado = models['multilingual'](texto)[0]
|
70 |
+
resultados['multilingual'] = {
|
71 |
+
'label': resultado['label'],
|
72 |
+
'score': resultado['score'],
|
73 |
+
'normalized_score': resultado['score'] if resultado['label'] == 'POSITIVE' else -resultado['score']
|
74 |
+
}
|
75 |
+
except Exception as e:
|
76 |
+
resultados['multilingual'] = {'error': str(e)}
|
77 |
+
|
78 |
+
# Método 2: Modelo BERT con estrellas
|
79 |
+
if models['bert']:
|
80 |
+
try:
|
81 |
+
resultado = models['bert'](texto)[0]
|
82 |
+
# Convertir estrellas a puntuación -1 a 1
|
83 |
+
star_mapping = {
|
84 |
+
'1 star': -1.0, '2 stars': -0.5, '3 stars': 0.0,
|
85 |
+
'4 stars': 0.5, '5 stars': 1.0
|
86 |
+
}
|
87 |
+
normalized_score = star_mapping.get(resultado['label'], 0.0)
|
88 |
+
resultados['bert'] = {
|
89 |
+
'label': resultado['label'],
|
90 |
+
'score': resultado['score'],
|
91 |
+
'normalized_score': normalized_score
|
92 |
+
}
|
93 |
+
except Exception as e:
|
94 |
+
resultados['bert'] = {'error': str(e)}
|
95 |
+
|
96 |
+
# Método 3: Análisis léxico mejorado
|
97 |
+
if nlp:
|
98 |
+
try:
|
99 |
+
doc = nlp(texto.lower())
|
100 |
+
palabras = [token.lemma_ for token in doc if token.is_alpha and len(token.text) > 2]
|
101 |
+
|
102 |
+
positivas = sum(1 for palabra in palabras if palabra in palabras_positivas)
|
103 |
+
negativas = sum(1 for palabra in palabras if palabra in palabras_negativas)
|
104 |
+
|
105 |
+
total_relevantes = len(palabras)
|
106 |
+
if total_relevantes > 0:
|
107 |
+
polaridad = (positivas - negativas) / total_relevantes
|
108 |
+
# Normalizar a -1 a 1
|
109 |
+
polaridad = max(-1.0, min(1.0, polaridad * 5))
|
110 |
+
else:
|
111 |
+
polaridad = 0.0
|
112 |
+
|
113 |
+
resultados['lexico'] = {
|
114 |
+
'positivas': positivas,
|
115 |
+
'negativas': negativas,
|
116 |
+
'total_palabras': total_relevantes,
|
117 |
+
'normalized_score': polaridad
|
118 |
+
}
|
119 |
+
except Exception as e:
|
120 |
+
resultados['lexico'] = {'error': str(e)}
|
121 |
+
|
122 |
+
# Método 4: TextBlob (para inglés y español básico)
|
123 |
+
try:
|
124 |
+
blob = TextBlob(texto)
|
125 |
+
polaridad = blob.sentiment.polarity
|
126 |
+
resultados['textblob'] = {
|
127 |
+
'polarity': polaridad,
|
128 |
+
'subjectivity': blob.sentiment.subjectivity,
|
129 |
+
'normalized_score': polaridad
|
130 |
+
}
|
131 |
+
except Exception as e:
|
132 |
+
resultados['textblob'] = {'error': str(e)}
|
133 |
+
|
134 |
+
return resultados
|
135 |
+
|
136 |
+
def determinar_sentimiento_final(resultados):
|
137 |
+
"""Combina resultados de todos los métodos"""
|
138 |
+
scores = []
|
139 |
+
pesos = {'multilingual': 0.4, 'bert': 0.3, 'lexico': 0.2, 'textblob': 0.1}
|
140 |
+
|
141 |
+
for metodo, peso in pesos.items():
|
142 |
+
if metodo in resultados and 'normalized_score' in resultados[metodo]:
|
143 |
+
scores.append(resultados[metodo]['normalized_score'] * peso)
|
144 |
+
|
145 |
+
if scores:
|
146 |
+
score_final = sum(scores)
|
147 |
+
|
148 |
+
if score_final > 0.2:
|
149 |
+
return "😊 POSITIVO", score_final, "green"
|
150 |
+
elif score_final < -0.2:
|
151 |
+
return "😠 NEGATIVO", score_final, "red"
|
152 |
+
else:
|
153 |
+
return "😐 NEUTRO", score_final, "gray"
|
154 |
+
else:
|
155 |
+
return "❓ INDETERMINADO", 0.0, "orange"
|
156 |
+
|
157 |
+
def analizar_lingüistica(texto):
|
158 |
+
"""Análisis lingüístico con spaCy"""
|
159 |
+
if not nlp:
|
160 |
+
return {"error": "Modelo spaCy no disponible"}
|
161 |
+
|
162 |
+
doc = nlp(texto)
|
163 |
+
|
164 |
+
analisis = {
|
165 |
+
'estadisticas': {
|
166 |
+
'total_tokens': len(doc),
|
167 |
+
'total_palabras': len([token for token in doc if token.is_alpha]),
|
168 |
+
'total_oraciones': len(list(doc.sents)),
|
169 |
+
'total_entidades': len(doc.ents)
|
170 |
+
},
|
171 |
+
'tokens': [],
|
172 |
+
'entidades': [],
|
173 |
+
'oraciones': [sent.text for sent in doc.sents]
|
174 |
+
}
|
175 |
+
|
176 |
+
# Análisis de tokens
|
177 |
+
for token in doc[:20]: # Mostrar solo primeros 20 tokens
|
178 |
+
analisis['tokens'].append({
|
179 |
+
'texto': token.text,
|
180 |
+
'lemma': token.lemma_,
|
181 |
+
'POS': token.pos_,
|
182 |
+
'explicacion': spacy.explain(token.pos_) or ''
|
183 |
+
})
|
184 |
+
|
185 |
+
# Entidades nombradas
|
186 |
+
for ent in doc.ents[:10]: # Mostrar solo primeras 10 entidades
|
187 |
+
analisis['entidades'].append({
|
188 |
+
'texto': ent.text,
|
189 |
+
'tipo': ent.label_,
|
190 |
+
'explicacion': spacy.explain(ent.label_) or ''
|
191 |
+
})
|
192 |
+
|
193 |
+
return analisis
|
194 |
+
|
195 |
+
def analizar_texto_completo(texto):
|
196 |
+
"""Función principal que combina todo el análisis"""
|
197 |
+
if not texto.strip():
|
198 |
+
return "❌ Por favor ingresa un texto para analizar", "", ""
|
199 |
+
|
200 |
+
# Análisis de sentimiento
|
201 |
+
resultados = analizar_sentimiento_multimodelo(texto)
|
202 |
+
sentimiento_final, score_final, color = determinar_sentimiento_final(resultados)
|
203 |
+
|
204 |
+
# Análisis lingüístico
|
205 |
+
analisis_ling = analizar_lingüistica(texto)
|
206 |
+
|
207 |
+
# Crear resumen de resultados
|
208 |
+
resumen_html = f"""
|
209 |
+
<div style='background-color: {color}20; padding: 20px; border-radius: 10px; border-left: 5px solid {color};'>
|
210 |
+
<h2 style='margin: 0; color: {color};'>{sentimiento_final}</h2>
|
211 |
+
<p style='margin: 5px 0;'><strong>Puntuación final:</strong> {score_final:.3f}</p>
|
212 |
+
<p style='margin: 5px 0;'><strong>Longitud del texto:</strong> {len(texto)} caracteres</p>
|
213 |
+
</div>
|
214 |
+
"""
|
215 |
+
|
216 |
+
# Detalles por método
|
217 |
+
detalles_html = "<h3>📊 Resultados por Método:</h3>"
|
218 |
+
for metodo, resultado in resultados.items():
|
219 |
+
detalles_html += f"<div style='margin-bottom: 15px;'>"
|
220 |
+
detalles_html += f"<strong>{metodo.upper()}:</strong><br>"
|
221 |
+
|
222 |
+
if 'error' in resultado:
|
223 |
+
detalles_html += f"<span style='color: red;'>Error: {resultado['error']}</span>"
|
224 |
+
else:
|
225 |
+
if 'label' in resultado:
|
226 |
+
detalles_html += f"Etiqueta: {resultado['label']}<br>"
|
227 |
+
if 'score' in resultado:
|
228 |
+
detalles_html += f"Confianza: {resultado['score']:.3f}<br>"
|
229 |
+
if 'normalized_score' in resultado:
|
230 |
+
detalles_html += f"Puntuación: {resultado['normalized_score']:.3f}<br>"
|
231 |
+
if 'positivas' in resultado:
|
232 |
+
detalles_html += f"Palabras positivas: {resultado['positivas']}<br>"
|
233 |
+
detalles_html += f"Palabras negativas: {resultado['negativas']}<br>"
|
234 |
+
|
235 |
+
detalles_html += "</div>"
|
236 |
+
|
237 |
+
# Análisis lingüístico
|
238 |
+
ling_html = "<h3>📝 Análisis Lingüístico:</h3>"
|
239 |
+
if 'error' in analisis_ling:
|
240 |
+
ling_html += f"<p style='color: red;'>{analisis_ling['error']}</p>"
|
241 |
+
else:
|
242 |
+
stats = analisis_ling['estadisticas']
|
243 |
+
ling_html += f"""
|
244 |
+
<p><strong>Estadísticas:</strong></p>
|
245 |
+
<ul>
|
246 |
+
<li>Total de tokens: {stats['total_tokens']}</li>
|
247 |
+
<li>Palabras: {stats['total_palabras']}</li>
|
248 |
+
<li>Oraciones: {stats['total_oraciones']}</li>
|
249 |
+
<li>Entidades: {stats['total_entidades']}</li>
|
250 |
+
</ul>
|
251 |
+
"""
|
252 |
+
|
253 |
+
if analisis_ling['entidades']:
|
254 |
+
ling_html += "<p><strong>Entidades detectadas:</strong></p>"
|
255 |
+
for ent in analisis_ling['entidades']:
|
256 |
+
ling_html += f"• {ent['texto']} ({ent['tipo']})<br>"
|
257 |
+
|
258 |
+
return resumen_html, detalles_html, ling_html
|
259 |
+
|
260 |
+
def analizar_archivo_excel(archivo):
|
261 |
+
"""Analizar archivo Excel con textos"""
|
262 |
+
try:
|
263 |
+
df = pd.read_excel(archivo)
|
264 |
+
|
265 |
+
# Buscar columnas con texto
|
266 |
+
columnas_texto = []
|
267 |
+
for col in df.columns:
|
268 |
+
if df[col].dtype == 'object':
|
269 |
+
# Verificar si contiene texto
|
270 |
+
muestras = df[col].dropna()[:5]
|
271 |
+
if any(isinstance(x, str) and len(str(x).strip()) > 10 for x in muestras):
|
272 |
+
columnas_texto.append(col)
|
273 |
+
|
274 |
+
if not columnas_texto:
|
275 |
+
return pd.DataFrame({"Resultado": ["❌ No se encontraron columnas con texto suficiente para analizar"]})
|
276 |
+
|
277 |
+
resultados = []
|
278 |
+
for col in columnas_texto[:2]: # Analizar máximo 2 columnas
|
279 |
+
for idx, texto in enumerate(df[col].dropna()[:50]): # Máximo 50 filas por columna
|
280 |
+
if isinstance(texto, str) and len(texto.strip()) > 5:
|
281 |
+
resultado_sentimiento = analizar_sentimiento_multimodelo(texto)
|
282 |
+
sentimiento, score, _ = determinar_sentimiento_final(resultado_sentimiento)
|
283 |
+
|
284 |
+
resultados.append({
|
285 |
+
'Columna': col,
|
286 |
+
'Fila': idx + 1,
|
287 |
+
'Texto': texto[:100] + '...' if len(texto) > 100 else texto,
|
288 |
+
'Sentimiento': sentimiento,
|
289 |
+
'Puntuación': f"{score:.3f}",
|
290 |
+
'Longitud': len(texto)
|
291 |
+
})
|
292 |
+
|
293 |
+
if not resultados:
|
294 |
+
return pd.DataFrame({"Resultado": ["❌ No se pudieron analizar los textos del archivo"]})
|
295 |
+
|
296 |
+
df_resultados = pd.DataFrame(resultados)
|
297 |
+
return df_resultados
|
298 |
+
|
299 |
+
except Exception as e:
|
300 |
+
return pd.DataFrame({"Error": [f"❌ Error al procesar el archivo: {str(e)}"]})
|
301 |
+
|
302 |
+
# Interfaz Gradio simplificada
|
303 |
+
with gr.Blocks(theme="soft", title="Análisis Completo de Texto") as demo:
|
304 |
+
gr.Markdown("""
|
305 |
+
# 🎯 Análisis Completo de Texto - Multimodelo
|
306 |
+
|
307 |
+
**Combina análisis lingüístico + múltiples métodos de sentimiento para máxima precisión**
|
308 |
+
""")
|
309 |
+
|
310 |
+
with gr.Tab("📝 Análisis de Texto Individual"):
|
311 |
+
with gr.Row():
|
312 |
+
with gr.Column():
|
313 |
+
texto_input = gr.Textbox(
|
314 |
+
label="Ingresa tu texto",
|
315 |
+
placeholder="Escribe aquí tu texto en español, inglés, francés o portugués...",
|
316 |
+
lines=5
|
317 |
+
)
|
318 |
+
analizar_btn = gr.Button("🔍 Analizar Texto", variant="primary")
|
319 |
+
|
320 |
+
gr.Markdown("### Ejemplos rápidos:")
|
321 |
+
ejemplos = gr.Examples(
|
322 |
+
examples=[
|
323 |
+
["Me encanta este producto! Es excelente y superó mis expectativas completamente."],
|
324 |
+
["No estoy para nada satisfecho, la calidad es pésima y el servicio terrible."],
|
325 |
+
["El producto cumple su función básica, pero podría mejorar en algunos aspectos."],
|
326 |
+
["I love this amazing product! It works perfectly and the quality is outstanding."],
|
327 |
+
["C'est un produit fantastique, je le recommande vivement à tous mes amis."],
|
328 |
+
["Este serviço é muito bom, atendimento excelente e qualidade superior."]
|
329 |
+
],
|
330 |
+
inputs=texto_input
|
331 |
+
)
|
332 |
+
|
333 |
+
with gr.Column():
|
334 |
+
resultado_resumen = gr.HTML(label="🎯 Resultado Principal")
|
335 |
+
resultado_detalles = gr.HTML(label="📊 Detalles por Método")
|
336 |
+
resultado_linguistica = gr.HTML(label="📝 Análisis Lingüístico")
|
337 |
+
|
338 |
+
with gr.Tab("📊 Análisis de Archivos Excel"):
|
339 |
+
with gr.Row():
|
340 |
+
with gr.Column():
|
341 |
+
archivo_input = gr.File(
|
342 |
+
label="Sube tu archivo Excel",
|
343 |
+
file_types=[".xlsx", ".xls"]
|
344 |
+
)
|
345 |
+
analizar_excel_btn = gr.Button("📈 Analizar Archivo", variant="primary")
|
346 |
+
|
347 |
+
gr.Markdown("""
|
348 |
+
**Formato esperado:**
|
349 |
+
- Archivo Excel (.xlsx o .xls)
|
350 |
+
- Columnas con texto (reseñas, comentarios, etc.)
|
351 |
+
- Mínimo 5-10 palabras por texto para mejor análisis
|
352 |
+
""")
|
353 |
+
|
354 |
+
with gr.Column():
|
355 |
+
resultado_excel = gr.Dataframe(label="Resultados del Análisis")
|
356 |
+
|
357 |
+
with gr.Tab("ℹ️ Información del Sistema"):
|
358 |
+
gr.Markdown("""
|
359 |
+
## 🔧 Métodos de Análisis Utilizados
|
360 |
+
|
361 |
+
### 🤖 Modelos de Machine Learning
|
362 |
+
- **Multilingual Sentiment**: Modelo especializado en múltiples idiomas
|
363 |
+
- **BERT Multilingual**: Modelo transformer con clasificación por estrellas (1-5)
|
364 |
+
|
365 |
+
### 📚 Análisis Léxico
|
366 |
+
- Diccionario de palabras positivas/negativas en español
|
367 |
+
- Lematización y análisis morfológico
|
368 |
+
|
369 |
+
### 📊 TextBlob
|
370 |
+
- Análisis tradicional de sentimientos
|
371 |
+
- Compatible con múltiples idiomas
|
372 |
+
|
373 |
+
### 📝 Análisis Lingüístico (spaCy)
|
374 |
+
- Tokenización y POS tagging
|
375 |
+
- Reconocimiento de entidades
|
376 |
+
- Análisis de dependencias
|
377 |
+
|
378 |
+
## 🎯 Combinación Inteligente
|
379 |
+
Los resultados se combinan usando pesos ponderados para mayor precisión
|
380 |
+
""")
|
381 |
+
|
382 |
+
# Conectar eventos
|
383 |
+
analizar_btn.click(
|
384 |
+
fn=analizar_texto_completo,
|
385 |
+
inputs=texto_input,
|
386 |
+
outputs=[resultado_resumen, resultado_detalles, resultado_linguistica]
|
387 |
+
)
|
388 |
+
|
389 |
+
texto_input.submit(
|
390 |
+
fn=analizar_texto_completo,
|
391 |
+
inputs=texto_input,
|
392 |
+
outputs=[resultado_resumen, resultado_detalles, resultado_linguistica]
|
393 |
+
)
|
394 |
+
|
395 |
+
analizar_excel_btn.click(
|
396 |
+
fn=analizar_archivo_excel,
|
397 |
+
inputs=archivo_input,
|
398 |
+
outputs=resultado_excel
|
399 |
+
)
|
400 |
+
|
401 |
+
if __name__ == "__main__":
|
402 |
+
demo.launch()
|
requirements.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio>=4.0.0
|
2 |
+
transformers>=4.20.0
|
3 |
+
torch>=1.9.0
|
4 |
+
spacy>=3.0.0
|
5 |
+
textblob>=0.17.1
|
6 |
+
pandas>=1.3.0
|
7 |
+
numpy>=1.21.0
|