import pandas as pd from sentence_transformers import SentenceTransformer from sklearn.cluster import DBSCAN from sklearn.metrics.pairwise import cosine_similarity import numpy as np import gradio as gr import io # Cargar el modelo de embeddings modelo = SentenceTransformer('all-MiniLM-L6-v2') # Función para realizar el clustering de las frases def obtener_categorias_dinamicas(frases, umbral_similitud=0.5): # Codificar las frases en vectores (embeddings) embeddings = modelo.encode(frases) # Realizar clustering con DBSCAN (puedes cambiar el modelo de clustering si lo prefieres) clustering = DBSCAN(eps=0.5, min_samples=2, metric='cosine').fit(embeddings) # Asignar una categoría para cada frase según el cluster al que pertenece etiquetas = clustering.labels_ # Agrupar las frases según sus etiquetas (clusters) categorias = {} for i, etiqueta in enumerate(etiquetas): if etiqueta == -1: categoria = "Sin grupo" # Las que no tienen un grupo asignado (ruido) else: categoria = f"Categoría {etiqueta + 1}" if categoria not in categorias: categorias[categoria] = [] categorias[categoria].append(frases[i]) # Ahora, se asigna cada frase a las categorías con similitud suficiente categorias_frases = [] for frase in frases: # Calcular la similitud con todas las categorías frase_embedding = modelo.encode([frase]) # Listar las categorías que tienen una alta similitud con la frase categorias_relevantes = [] for categoria, frases_grupo in categorias.items(): # Obtener la media de los embeddings del grupo grupo_embeddings = modelo.encode(frases_grupo) centro_grupo = np.mean(grupo_embeddings, axis=0) # Calcular la similitud entre la frase y el centro del grupo similitud = cosine_similarity(frase_embedding, [centro_grupo])[0][0] # Si la similitud supera el umbral, asignamos la categoría if similitud > umbral_similitud: categorias_relevantes.append(categoria) # Si no hay categorías relevantes, asignamos "Sin grupo" if not categorias_relevantes: categorias_relevantes.append("Sin grupo") categorias_frases.append(";".join(categorias_relevantes)) # Crear un DataFrame para mostrar el resultado resultados = pd.DataFrame({ 'Frase': frases, 'Categorías': categorias_frases }) # Guardar los resultados en un archivo Excel en memoria (para devolverlo en Gradio) output = io.BytesIO() # Buffer en memoria para escribir el archivo Excel resultados.to_excel(output, index=False, encoding='utf-8') output.seek(0) # Volver al principio del archivo para que Gradio pueda leerlo return output # Función para cargar y procesar el archivo Excel def procesar_excel(archivo): df = pd.read_excel(archivo) # Asumir que el archivo tiene una columna llamada "Frase" frases = df['Frase'].tolist() return obtener_categorias_dinamicas(frases) # Crear la interfaz de Gradio iface = gr.Interface( fn=procesar_excel, inputs=gr.File(label="Cargar archivo Excel con frases"), outputs=gr.File(label="Descargar archivo Excel codificado") # Cambiar el output a archivo ) iface.launch()