Update app.py
Browse files
app.py
CHANGED
@@ -1,64 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
-
from
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
minimum=0.1,
|
54 |
-
maximum=1.0,
|
55 |
-
value=0.95,
|
56 |
-
step=0.05,
|
57 |
-
label="Top-p (nucleus sampling)",
|
58 |
-
),
|
59 |
-
],
|
60 |
)
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
-
|
64 |
-
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
# Instalar las dependencias necesarias
|
4 |
+
os.system("pip install -U sentence-transformers chromadb pandas gradio numpy scipy")
|
5 |
+
|
6 |
+
# Importar librerías necesarias
|
7 |
+
from sentence_transformers import SentenceTransformer, util
|
8 |
+
import pandas as pd
|
9 |
+
import chromadb
|
10 |
+
from chromadb.utils import embedding_functions
|
11 |
import gradio as gr
|
12 |
+
from scipy.spatial.distance import cosine
|
13 |
+
|
14 |
+
# Verificar si el archivo CSV existe
|
15 |
+
file_path = './tramites_servicios_catalago.csv'
|
16 |
+
|
17 |
+
if not os.path.exists(file_path):
|
18 |
+
raise FileNotFoundError(f"El archivo {file_path} no se encuentra en el directorio del Space. ¡Asegúrate de subirlo!")
|
19 |
+
|
20 |
+
# Cargar la base de datos de trámites y servicios
|
21 |
+
df = pd.read_csv(file_path, encoding='latin-1')
|
22 |
+
|
23 |
+
# Crear una columna combinada para los embeddings
|
24 |
+
df['text'] = df.apply(
|
25 |
+
lambda x: (
|
26 |
+
f"Nombre del trámite: {x['nombre_tramite']}, "
|
27 |
+
f"Descripción: {x['descripcion']}, "
|
28 |
+
f"Dependencia: {x['dependencia']}, "
|
29 |
+
f"Nivel de gobierno: {x['nivel_gobierno']}, "
|
30 |
+
f"Trámite o servicio: {x['tramite_servicio']}, "
|
31 |
+
f"Tipo: {x['tipo']}, "
|
32 |
+
f"Homoclave: {x['homoclave']}, "
|
33 |
+
f"URL: {x['url']}"
|
34 |
+
), axis=1
|
35 |
+
)
|
36 |
+
|
37 |
+
# Cargar modelo de embeddings
|
38 |
+
print("Cargando el modelo de embeddings...")
|
39 |
+
model = SentenceTransformer("jinaai/jina-embeddings-v2-base-es", trust_remote_code=True)
|
40 |
+
|
41 |
+
# Generar embeddings
|
42 |
+
print("Generando embeddings...")
|
43 |
+
df['embeddings'] = model.encode(df['text'], batch_size=64, show_progress_bar=True).tolist()
|
44 |
+
|
45 |
+
# Crear identificadores únicos
|
46 |
+
df['ids'] = df.index.astype(str)
|
47 |
+
|
48 |
+
# Configurar cliente de ChromaDB persistente
|
49 |
+
print("Configurando la base de datos ChromaDB...")
|
50 |
+
client_persistent = chromadb.PersistentClient(path='./data_embeddings')
|
51 |
+
embedding_function = embedding_functions.SentenceTransformerEmbeddingFunction(model_name="jinaai/jina-embeddings-v2-base-es")
|
52 |
+
|
53 |
+
db = client_persistent.get_or_create_collection(name='tramites_servicios_db', embedding_function=embedding_function)
|
54 |
+
|
55 |
+
# Agregar datos a la colección
|
56 |
+
print("Agregando datos a la colección de ChromaDB...")
|
57 |
+
db.add(
|
58 |
+
ids=df['ids'].tolist(),
|
59 |
+
embeddings=df['embeddings'].tolist(),
|
60 |
+
documents=df['text'].tolist(),
|
61 |
+
metadatas=df[['nombre_tramite', 'descripcion', 'dependencia', 'nivel_gobierno',
|
62 |
+
'tramite_servicio', 'tipo', 'homoclave', 'url']].to_dict('records')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
)
|
64 |
|
65 |
+
# Función para realizar consultas
|
66 |
+
def obtener_recomendaciones(preferencias, top_k=3):
|
67 |
+
# Convertir preferencias en embeddings
|
68 |
+
consulta_embedding = model.encode(preferencias, show_progress_bar=False)
|
69 |
+
|
70 |
+
# Realizar consulta en ChromaDB
|
71 |
+
results = db.query(query_embeddings=[consulta_embedding], n_results=top_k)
|
72 |
+
|
73 |
+
# Verificar si hay resultados
|
74 |
+
if not results or not results["metadatas"] or not results["metadatas"][0]:
|
75 |
+
return []
|
76 |
+
|
77 |
+
recomendaciones = []
|
78 |
+
for idx, metadata in enumerate(results["metadatas"][0]):
|
79 |
+
dist = results["distances"][0][idx]
|
80 |
+
metadata['distancia_euclidiana'] = dist
|
81 |
+
recomendaciones.append(metadata)
|
82 |
+
|
83 |
+
return recomendaciones
|
84 |
+
|
85 |
+
# Función para procesar resultados y generar una tabla
|
86 |
+
def procesar_recomendaciones(preferencias):
|
87 |
+
recomendaciones = obtener_recomendaciones(preferencias)
|
88 |
+
|
89 |
+
if not recomendaciones:
|
90 |
+
return pd.DataFrame([{"Mensaje": "No se encontraron resultados para las preferencias proporcionadas."}])
|
91 |
+
|
92 |
+
# Crear una tabla con las recomendaciones
|
93 |
+
resultados = []
|
94 |
+
for idx, tramite in enumerate(recomendaciones, 1):
|
95 |
+
resultados.append({
|
96 |
+
"#": idx,
|
97 |
+
"Nombre del Trámite": tramite.get('nombre_tramite', 'Desconocido'),
|
98 |
+
"Descripción": tramite.get('descripcion', 'No disponible'),
|
99 |
+
"Dependencia": tramite.get('dependencia', 'No disponible'),
|
100 |
+
"Nivel de Gobierno": tramite.get('nivel_gobierno', 'No disponible'),
|
101 |
+
"Tipo": tramite.get('tipo', 'No disponible'),
|
102 |
+
"Homoclave": tramite.get('homoclave', 'No disponible'),
|
103 |
+
"URL": tramite.get('url', 'No disponible'),
|
104 |
+
"Distancia Euclidiana": tramite.get('distancia_euclidiana', 'N/A')
|
105 |
+
})
|
106 |
+
|
107 |
+
# Convertir los resultados a un DataFrame
|
108 |
+
return pd.DataFrame(resultados)
|
109 |
+
|
110 |
+
# Interfaz de Gradio con formato de tabla
|
111 |
+
def interfaz(preferencias):
|
112 |
+
tabla_resultados = procesar_recomendaciones(preferencias)
|
113 |
+
return tabla_resultados
|
114 |
+
|
115 |
+
# Configurar la interfaz de Gradio
|
116 |
+
ui = gr.Interface(
|
117 |
+
fn=interfaz,
|
118 |
+
inputs=gr.Textbox(
|
119 |
+
label="Preferencias",
|
120 |
+
placeholder="Escribe tus preferencias, e.g., consulta de actas, trámite de licencias"
|
121 |
+
),
|
122 |
+
outputs=gr.Dataframe(
|
123 |
+
label="Resultados de Búsqueda",
|
124 |
+
headers=["#", "Nombre del Trámite", "Descripción", "Dependencia", "Nivel de Gobierno", "Tipo", "Homoclave", "URL", "Distancia Euclidiana"]
|
125 |
+
),
|
126 |
+
title="Buscador de Trámites y Servicios con Búsqueda Semántica",
|
127 |
+
description="Introduce tus preferencias para obtener resultados relevantes basados en similitud semántica."
|
128 |
+
)
|
129 |
|
130 |
+
# Ejecutar la aplicación
|
131 |
+
print("Iniciando la aplicación en Hugging Face Spaces...")
|
132 |
+
ui.launch(server_name="0.0.0.0", server_port=7860)
|