File size: 3,429 Bytes
9e46923
 
feca434
9e46923
feca434
 
7bbf29e
9e46923
feca434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9e46923
feca434
9e46923
feca434
 
 
 
 
 
 
 
 
9e46923
feca434
 
 
 
 
 
 
 
 
 
 
 
 
9e46923
feca434
 
 
 
 
 
 
 
 
 
 
 
7bbf29e
 
 
 
 
 
feca434
 
 
 
 
 
 
 
 
9e46923
feca434
 
7bbf29e
9e46923
 
feca434
1
2
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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()