jcmachicao commited on
Commit
89f7231
·
verified ·
1 Parent(s): 04404c7

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +179 -0
app.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spacy
2
+ import json
3
+ import re
4
+ from typing import Dict, List, Set
5
+
6
+ class ProcesadorAutodiagnostico:
7
+ def __init__(self):
8
+ # Cargar modelo spaCy en español
9
+ self.nlp = spacy.load("es_core_news_sm")
10
+
11
+ # Patrones de dominio específico
12
+ self.DOMINIOS = {
13
+ "legal": {
14
+ "términos": ["contrato", "legal", "documento", "cláusula", "gestión documental"],
15
+ "procesos": ["firma", "revisión", "archivo", "clasificación"],
16
+ "roles": ["abogado", "notario", "asesor legal"]
17
+ },
18
+ "ia": {
19
+ "términos": ["GPT", "inteligencia artificial", "IA", "machine learning", "automatización"],
20
+ "herramientas": ["chat", "procesamiento", "clasificación", "análisis"],
21
+ "conceptos": ["modelo", "entrenamiento", "dataset", "algoritmo"]
22
+ },
23
+ "negocio": {
24
+ "términos": ["empresa", "negocio", "emprendimiento", "startup"],
25
+ "procesos": ["constitución", "asociación", "implementación"],
26
+ "roles": ["profesional", "técnico", "consultor"]
27
+ }
28
+ }
29
+
30
+ # Patrones para identificar entrampes
31
+ self.PATRONES_ENTRAMPE = {
32
+ "duda": r"(?i)(duda|pregunta|cómo|qué|cuál|donde|cuándo|por qué)",
33
+ "necesidad": r"(?i)(necesito|requiero|busco|quiero)",
34
+ "problema": r"(?i)(problema|dificultad|obstáculo|limitación)",
35
+ "preocupación": r"(?i)(preocupa|inquieta|temo|desconfío)"
36
+ }
37
+
38
+ def extraer_ubicacion(self, doc) -> Dict[str, str]:
39
+ """Extrae información de ubicación del texto"""
40
+ ubicacion = {"ciudad": "", "pais": ""}
41
+ for ent in doc.ents:
42
+ if ent.label_ in ["GPE", "LOC"]:
43
+ # Asumimos que la última palabra es el país si hay más de una
44
+ palabras = ent.text.split()
45
+ if len(palabras) > 1:
46
+ ubicacion["ciudad"] = " ".join(palabras[:-1])
47
+ ubicacion["pais"] = palabras[-1]
48
+ else:
49
+ ubicacion["pais"] = ent.text
50
+ return ubicacion
51
+
52
+ def identificar_dominio_principal(self, texto: str) -> str:
53
+ """Identifica el dominio principal del texto basado en la frecuencia de términos"""
54
+ conteo_dominios = {dominio: 0 for dominio in self.DOMINIOS}
55
+
56
+ texto_lower = texto.lower()
57
+ for dominio, categorias in self.DOMINIOS.items():
58
+ for categoria, términos in categorias.items():
59
+ for término in términos:
60
+ conteo_dominios[dominio] += texto_lower.count(término.lower())
61
+
62
+ return max(conteo_dominios.items(), key=lambda x: x[1])[0]
63
+
64
+ def extraer_terminos_tecnicos(self, texto: str) -> Dict[str, List[str]]:
65
+ """Extrae términos técnicos clasificados por tipo"""
66
+ términos = {
67
+ "desconocidos": set(),
68
+ "dudosos": set(),
69
+ "mencionados": set()
70
+ }
71
+
72
+ # Buscar términos en el texto
73
+ texto_lower = texto.lower()
74
+ for dominio, categorias in self.DOMINIOS.items():
75
+ for término in categorias["términos"]:
76
+ if término.lower() in texto_lower:
77
+ # Si el término aparece cerca de palabras de duda
78
+ for patron in self.PATRONES_ENTRAMPE["duda"]:
79
+ if re.search(f"{patron}.*?{término}|{término}.*?{patron}", texto_lower, re.IGNORECASE):
80
+ términos["dudosos"].add(término)
81
+ break
82
+ else:
83
+ términos["mencionados"].add(término)
84
+
85
+ return {k: list(v) for k, v in términos.items()}
86
+
87
+ def identificar_entrampes(self, doc) -> Dict[str, List[str]]:
88
+ """Identifica diferentes tipos de entrampes en el texto"""
89
+ entrampes = {
90
+ "tecnicos": [],
91
+ "implementacion": [],
92
+ "organizacionales": []
93
+ }
94
+
95
+ for sent in doc.sents:
96
+ sent_text = sent.text
97
+
98
+ # Clasificar el tipo de entrampe
99
+ if any(term in sent_text.lower() for term in self.DOMINIOS["ia"]["términos"]):
100
+ if re.search(self.PATRONES_ENTRAMPE["duda"], sent_text):
101
+ entrampes["tecnicos"].append(sent_text)
102
+ elif any(term in sent_text.lower() for term in self.DOMINIOS["negocio"]["procesos"]):
103
+ if re.search(self.PATRONES_ENTRAMPE["problema"], sent_text):
104
+ entrampes["implementacion"].append(sent_text)
105
+ elif any(term in sent_text.lower() for term in self.DOMINIOS["negocio"]["términos"]):
106
+ if re.search(self.PATRONES_ENTRAMPE["preocupación"], sent_text):
107
+ entrampes["organizacionales"].append(sent_text)
108
+
109
+ return entrampes
110
+
111
+ def extraer_objetivos(self, doc) -> Dict[str, List[str]]:
112
+ """Extrae objetivos explícitos e implícitos del texto"""
113
+ objetivos = {
114
+ "corto_plazo": [],
115
+ "esperados_microtaller": []
116
+ }
117
+
118
+ for sent in doc.sents:
119
+ sent_text = sent.text
120
+
121
+ # Objetivos explícitos
122
+ if re.search(self.PATRONES_ENTRAMPE["necesidad"], sent_text):
123
+ objetivos["corto_plazo"].append(sent_text)
124
+
125
+ # Objetivos implícitos relacionados con el microtaller
126
+ if "microtaller" in sent_text.lower() or "taller" in sent_text.lower():
127
+ objetivos["esperados_microtaller"].append(sent_text)
128
+
129
+ return objetivos
130
+
131
+ def procesar_texto(self, texto: str) -> Dict:
132
+ """Procesa el texto completo y genera el autodiagnóstico"""
133
+ doc = self.nlp(texto)
134
+
135
+ # Identificar dominio principal
136
+ dominio = self.identificar_dominio_principal(texto)
137
+
138
+ # Extraer ubicación
139
+ ubicacion = self.extraer_ubicacion(doc)
140
+
141
+ # Procesar el texto
142
+ terminos = self.extraer_terminos_tecnicos(texto)
143
+ entrampes = self.identificar_entrampes(doc)
144
+ objetivos = self.extraer_objetivos(doc)
145
+
146
+ # Construir el autodiagnóstico
147
+ autodiagnostico = {
148
+ "datos_generales": {
149
+ "nombre": "",
150
+ "sector": dominio,
151
+ "ubicacion": ubicacion,
152
+ "fecha": ""
153
+ },
154
+ "reto": {
155
+ "descripcion": texto[:500],
156
+ "contexto": f"Sector {dominio.capitalize()} en {ubicacion['ciudad']}, {ubicacion['pais']}" if ubicacion['ciudad'] else "",
157
+ "alcance": ""
158
+ },
159
+ "conocimientos_cogtech": {
160
+ "terminos_desconocidos": terminos["desconocidos"],
161
+ "conceptos_dudosos": terminos["dudosos"],
162
+ "areas_desconfianza": []
163
+ },
164
+ "dominio_actual": {
165
+ "aspectos_dominados": terminos["mencionados"],
166
+ "experiencia_previa": [],
167
+ "recursos_disponibles": []
168
+ },
169
+ "entrampes": entrampes,
170
+ "objetivos": objetivos
171
+ }
172
+
173
+ return autodiagnostico
174
+
175
+ # Uso en la interfaz Gradio
176
+ def procesar_con_gradio(texto_input: str) -> str:
177
+ procesador = ProcesadorAutodiagnostico()
178
+ resultado = procesador.procesar_texto(texto_input)
179
+ return json.dumps(resultado, indent=2, ensure_ascii=False)