AIdeaText commited on
Commit
0898727
·
verified ·
1 Parent(s): 17dfe1b

Update modules/text_analysis/discourse_analysis.py

Browse files
modules/text_analysis/discourse_analysis.py CHANGED
@@ -8,30 +8,31 @@ import matplotlib.pyplot as plt
8
  import pandas as pd
9
  import numpy as np
10
  import logging
 
 
 
 
 
11
 
 
12
  logger = logging.getLogger(__name__)
13
 
 
14
  from .semantic_analysis import (
15
  create_concept_graph,
16
  visualize_concept_graph,
17
  identify_key_concepts
18
  )
19
 
 
20
  from .stopwords import (
21
  get_custom_stopwords,
22
  process_text,
23
  get_stopwords_for_spacy
24
  )
25
 
26
- #####################
27
- # Define colors for grammatical categories
28
- POS_COLORS = {
29
- 'ADJ': '#FFA07A', 'ADP': '#98FB98', 'ADV': '#87CEFA', 'AUX': '#DDA0DD',
30
- 'CCONJ': '#F0E68C', 'DET': '#FFB6C1', 'INTJ': '#FF6347', 'NOUN': '#90EE90',
31
- 'NUM': '#FAFAD2', 'PART': '#D3D3D3', 'PRON': '#FFA500', 'PROPN': '#20B2AA',
32
- 'SCONJ': '#DEB887', 'SYM': '#7B68EE', 'VERB': '#FF69B4', 'X': '#A9A9A9',
33
- }
34
 
 
35
  POS_TRANSLATIONS = {
36
  'es': {
37
  'ADJ': 'Adjetivo', 'ADP': 'Preposición', 'ADV': 'Adverbio', 'AUX': 'Auxiliar',
@@ -53,6 +54,13 @@ POS_TRANSLATIONS = {
53
  'NOUN': 'Nom', 'NUM': 'Nombre', 'PART': 'Particule', 'PRON': 'Pronom',
54
  'PROPN': 'Nom Propre', 'SCONJ': 'Conjonction de Subordination', 'SYM': 'Symbole',
55
  'VERB': 'Verbe', 'X': 'Autre',
 
 
 
 
 
 
 
56
  }
57
  }
58
 
@@ -77,10 +85,29 @@ ENTITY_LABELS = {
77
  "Inventions": "lightgreen",
78
  "Dates": "lightyellow",
79
  "Concepts": "lightpink"
 
 
 
 
 
 
 
80
  }
81
  }
82
 
 
83
 
 
 
 
 
 
 
 
 
 
 
 
84
  #################
85
  def compare_semantic_analysis(text1, text2, nlp, lang):
86
  """
@@ -161,9 +188,17 @@ def create_concept_table(key_concepts):
161
 
162
 
163
  ##########################################################
 
164
  def perform_discourse_analysis(text1, text2, nlp, lang):
165
  """
166
  Realiza el análisis completo del discurso
 
 
 
 
 
 
 
167
  """
168
  try:
169
  logger.info("Iniciando análisis del discurso...")
@@ -174,98 +209,59 @@ def perform_discourse_analysis(text1, text2, nlp, lang):
174
 
175
  if not nlp:
176
  raise ValueError("Modelo de lenguaje no inicializado")
177
-
178
- # Realizar análisis comparativo
179
- try:
180
- fig1, fig2, key_concepts1, key_concepts2 = compare_semantic_analysis(
181
- text1, text2, nlp, lang
182
- )
183
- except Exception as e:
184
- logger.error(f"Error en el análisis comparativo: {str(e)}")
185
- raise
186
-
187
- # Crear tablas de resultados
188
- try:
189
- table1 = create_concept_table(key_concepts1)
190
- table2 = create_concept_table(key_concepts2)
191
- except Exception as e:
192
- logger.error(f"Error creando tablas de conceptos: {str(e)}")
193
- raise
194
-
195
- result = {
196
- 'graph1': fig1,
197
- 'graph2': fig2,
198
- 'key_concepts1': key_concepts1,
199
- 'key_concepts2': key_concepts2,
200
- 'table1': table1,
201
- 'table2': table2,
202
- 'success': True
203
- }
204
 
205
- logger.info("Análisis del discurso completado exitosamente")
206
- return result
207
-
208
- except Exception as e:
209
- logger.error(f"Error en perform_discourse_analysis: {str(e)}")
210
- return {
211
- 'success': False,
212
- 'error': str(e)
213
- }
214
- finally:
215
- plt.close('all') # Asegurar limpieza en todos los casos
216
-
217
- #################################################################
218
- def create_concept_table(key_concepts):
219
- """
220
- Crea una tabla de conceptos clave con sus frecuencias
221
- Args:
222
- key_concepts: Lista de tuplas (concepto, frecuencia)
223
- Returns:
224
- pandas.DataFrame: Tabla formateada de conceptos
225
- """
226
- try:
227
- df = pd.DataFrame(key_concepts, columns=['Concepto', 'Frecuencia'])
228
- df['Frecuencia'] = df['Frecuencia'].round(2)
229
- return df
230
- except Exception as e:
231
- logger.error(f"Error en create_concept_table: {str(e)}")
232
- raise
233
-
234
- #################
235
- def perform_discourse_analysis(text1, text2, nlp, lang):
236
- """
237
- Realiza el análisis completo del discurso
238
- Args:
239
- text1: Primer texto a analizar
240
- text2: Segundo texto a analizar
241
- nlp: Modelo de spaCy cargado
242
- lang: Código de idioma
243
- Returns:
244
- dict: Resultados del análisis
245
- """
246
- try:
247
  # Realizar análisis comparativo
248
  fig1, fig2, key_concepts1, key_concepts2 = compare_semantic_analysis(
249
  text1, text2, nlp, lang
250
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
  # Crear tablas de resultados
253
  table1 = create_concept_table(key_concepts1)
254
  table2 = create_concept_table(key_concepts2)
255
 
256
- return {
257
- 'graph1': fig1,
258
- 'graph2': fig2,
 
 
 
 
 
259
  'key_concepts1': key_concepts1,
260
  'key_concepts2': key_concepts2,
261
  'table1': table1,
262
  'table2': table2,
263
  'success': True
264
  }
 
 
 
265
 
266
  except Exception as e:
267
  logger.error(f"Error en perform_discourse_analysis: {str(e)}")
 
 
268
  return {
269
  'success': False,
270
  'error': str(e)
271
- }
 
 
 
 
 
 
8
  import pandas as pd
9
  import numpy as np
10
  import logging
11
+ import io
12
+ import base64
13
+ from collections import Counter, defaultdict
14
+ import logging
15
+
16
 
17
+ logging.basicConfig(level=logging.INFO)
18
  logger = logging.getLogger(__name__)
19
 
20
+
21
  from .semantic_analysis import (
22
  create_concept_graph,
23
  visualize_concept_graph,
24
  identify_key_concepts
25
  )
26
 
27
+
28
  from .stopwords import (
29
  get_custom_stopwords,
30
  process_text,
31
  get_stopwords_for_spacy
32
  )
33
 
 
 
 
 
 
 
 
 
34
 
35
+ #####################
36
  POS_TRANSLATIONS = {
37
  'es': {
38
  'ADJ': 'Adjetivo', 'ADP': 'Preposición', 'ADV': 'Adverbio', 'AUX': 'Auxiliar',
 
54
  'NOUN': 'Nom', 'NUM': 'Nombre', 'PART': 'Particule', 'PRON': 'Pronom',
55
  'PROPN': 'Nom Propre', 'SCONJ': 'Conjonction de Subordination', 'SYM': 'Symbole',
56
  'VERB': 'Verbe', 'X': 'Autre',
57
+ },
58
+ 'pt': {
59
+ 'ADJ': 'Adjetivo', 'ADP': 'Preposição', 'ADV': 'Advérbio', 'AUX': 'Auxiliar',
60
+ 'CCONJ': 'Conjunção Coordenativa', 'DET': 'Determinante', 'INTJ': 'Interjeição',
61
+ 'NOUN': 'Substantivo', 'NUM': 'Número', 'PART': 'Partícula', 'PRON': 'Pronome',
62
+ 'PROPN': 'Nome Próprio', 'SCONJ': 'Conjunção Subordinativa', 'SYM': 'Símbolo',
63
+ 'VERB': 'Verbo', 'X': 'Outro',
64
  }
65
  }
66
 
 
85
  "Inventions": "lightgreen",
86
  "Dates": "lightyellow",
87
  "Concepts": "lightpink"
88
+ },
89
+ 'pt': {
90
+ "Pessoas": "lightblue",
91
+ "Lugares": "lightcoral",
92
+ "Invenções": "lightgreen",
93
+ "Datas": "lightyellow",
94
+ "Conceitos": "lightpink"
95
  }
96
  }
97
 
98
+ #################
99
 
100
+ def fig_to_bytes(fig, dpi=100):
101
+ """Convierte una figura de matplotlib a bytes."""
102
+ try:
103
+ buf = io.BytesIO()
104
+ fig.savefig(buf, format='png', dpi=dpi, bbox_inches='tight') # Sin compression
105
+ buf.seek(0)
106
+ return buf.getvalue()
107
+ except Exception as e:
108
+ logger.error(f"Error en fig_to_bytes: {str(e)}")
109
+ return None
110
+
111
  #################
112
  def compare_semantic_analysis(text1, text2, nlp, lang):
113
  """
 
188
 
189
 
190
  ##########################################################
191
+
192
  def perform_discourse_analysis(text1, text2, nlp, lang):
193
  """
194
  Realiza el análisis completo del discurso
195
+ Args:
196
+ text1: Primer texto a analizar
197
+ text2: Segundo texto a analizar
198
+ nlp: Modelo de spaCy cargado
199
+ lang: Código de idioma
200
+ Returns:
201
+ dict: Resultados del análisis con gráficos convertidos a bytes
202
  """
203
  try:
204
  logger.info("Iniciando análisis del discurso...")
 
209
 
210
  if not nlp:
211
  raise ValueError("Modelo de lenguaje no inicializado")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  # Realizar análisis comparativo
214
  fig1, fig2, key_concepts1, key_concepts2 = compare_semantic_analysis(
215
  text1, text2, nlp, lang
216
  )
217
+
218
+ logger.info("Análisis comparativo completado, convirtiendo figuras a bytes...")
219
+
220
+ # Convertir figuras a bytes para almacenamiento
221
+ graph1_bytes = fig_to_bytes(fig1)
222
+ graph2_bytes = fig_to_bytes(fig2)
223
+
224
+ logger.info(f"Figura 1 convertida a {len(graph1_bytes) if graph1_bytes else 0} bytes")
225
+ logger.info(f"Figura 2 convertida a {len(graph2_bytes) if graph2_bytes else 0} bytes")
226
+
227
+ # Verificar que las conversiones fueron exitosas antes de continuar
228
+ if not graph1_bytes or not graph2_bytes:
229
+ logger.error("Error al convertir figuras a bytes - obteniendo 0 bytes")
230
+ # Opción 1: Devolver error
231
+ raise ValueError("No se pudieron convertir las figuras a bytes")
232
 
233
  # Crear tablas de resultados
234
  table1 = create_concept_table(key_concepts1)
235
  table2 = create_concept_table(key_concepts2)
236
 
237
+ # Cerrar figuras para liberar memoria
238
+ plt.close(fig1)
239
+ plt.close(fig2)
240
+
241
+ result = {
242
+ 'graph1': graph1_bytes, # Bytes en lugar de figura
243
+ 'graph2': graph2_bytes, # Bytes en lugar de figura
244
+ 'combined_graph': None, # No hay gráfico combinado por ahora
245
  'key_concepts1': key_concepts1,
246
  'key_concepts2': key_concepts2,
247
  'table1': table1,
248
  'table2': table2,
249
  'success': True
250
  }
251
+
252
+ logger.info("Análisis del discurso completado y listo para almacenamiento")
253
+ return result
254
 
255
  except Exception as e:
256
  logger.error(f"Error en perform_discourse_analysis: {str(e)}")
257
+ # Asegurar limpieza de recursos
258
+ plt.close('all')
259
  return {
260
  'success': False,
261
  'error': str(e)
262
+ }
263
+ finally:
264
+ # Asegurar limpieza en todos los casos
265
+ plt.close('all')
266
+
267
+ #################################################################