GMARTINEZMILLA commited on
Commit
19c2f0c
1 Parent(s): 9dbd8d6

feat: Updated version management and retroalimentacion

Browse files
Files changed (2) hide show
  1. app.py +2 -2
  2. utils.py +134 -7
app.py CHANGED
@@ -90,7 +90,7 @@ nombres_proveedores['codigo'] = nombres_proveedores['codigo'].astype(str)
90
  euros_proveedor['CLIENTE'] = euros_proveedor['CLIENTE'].astype(str)
91
  customer_clusters['cliente_id'] = customer_clusters['cliente_id'].astype(str) # Ensure customer IDs are strings
92
  fieles_df = pd.read_csv("clientes_relevantes.csv")
93
- cestas = pd.read_csv("cestas.csv")
94
  productos = pd.read_csv("productos.csv")
95
  df_agg_2024['cliente_id'] = df_agg_2024['cliente_id'].astype(str)
96
  marca_id_mapping = load('marca_id_mapping.joblib')
@@ -868,7 +868,7 @@ elif page == "🕵️ Análisis de Cliente":
868
  # Customer Recommendations Page
869
  elif page == "💡 Recomendación de Artículos":
870
  # Carga de CSV necesarios cestas y productos
871
- cestas = pd.read_csv('cestas.csv')
872
  productos = pd.read_csv('productos.csv')
873
 
874
  # Estilo principal de la página
 
90
  euros_proveedor['CLIENTE'] = euros_proveedor['CLIENTE'].astype(str)
91
  customer_clusters['cliente_id'] = customer_clusters['cliente_id'].astype(str) # Ensure customer IDs are strings
92
  fieles_df = pd.read_csv("clientes_relevantes.csv")
93
+ cestas = pd.read_csv("cestas_su.csv")
94
  productos = pd.read_csv("productos.csv")
95
  df_agg_2024['cliente_id'] = df_agg_2024['cliente_id'].astype(str)
96
  marca_id_mapping = load('marca_id_mapping.joblib')
 
868
  # Customer Recommendations Page
869
  elif page == "💡 Recomendación de Artículos":
870
  # Carga de CSV necesarios cestas y productos
871
+ cestas = pd.read_csv('cestas_su.csv')
872
  productos = pd.read_csv('productos.csv')
873
 
874
  # Estilo principal de la página
utils.py CHANGED
@@ -1,20 +1,66 @@
1
  import pandas as pd
2
  import numpy as np
3
  import warnings
 
 
 
4
  warnings.filterwarnings('ignore')
5
- from sklearn.feature_extraction.text import TfidfVectorizer
6
  from sklearn.metrics.pairwise import cosine_similarity
7
  from joblib import dump, load
8
  from sklearn.preprocessing import normalize
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
-
13
- def recomienda_tf(new_basket,cestas,productos):
14
  # Cargar la matriz TF y el modelo
15
- tf_matrix = load('tf_matrix.joblib')
16
-
17
- count = load('count_vectorizer.joblib')
18
  # Convertir la nueva cesta en formato TF (Term Frequency)
19
  new_basket_str = ' '.join(new_basket)
20
  new_basket_vector = count.transform([new_basket_str])
@@ -60,4 +106,85 @@ def recomienda_tf(new_basket,cestas,productos):
60
  })
61
  recommendations_df = pd.DataFrame(recommendations_data)
62
 
63
- return recommendations_df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import pandas as pd
2
  import numpy as np
3
  import warnings
4
+ import glob
5
+ import os
6
+ import re
7
  warnings.filterwarnings('ignore')
8
+ from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
9
  from sklearn.metrics.pairwise import cosine_similarity
10
  from joblib import dump, load
11
  from sklearn.preprocessing import normalize
12
 
13
+ def get_latest_version(base_filename):
14
+ """
15
+ Obtiene la última versión del archivo guardado.
16
+ Args:
17
+ base_filename (str): Nombre base del archivo (sin versión)
18
+ Returns:
19
+ str: Nombre del archivo con la versión más reciente
20
+ """
21
+ # Buscar todos los archivos que coincidan con el patrón
22
+ pattern = f"{base_filename}_*.joblib"
23
+ matching_files = glob.glob(pattern)
24
+
25
+ if not matching_files:
26
+ return f"{base_filename}_0001.joblib"
27
+
28
+ # Extraer los números de versión y encontrar el máximo
29
+ versions = []
30
+ for file in matching_files:
31
+ match = re.search(r'_(\d{4})\.joblib$', file)
32
+ if match:
33
+ versions.append(int(match.group(1)))
34
+
35
+ if versions:
36
+ latest_version = max(versions)
37
+ return f"{base_filename}_{latest_version:04d}.joblib"
38
+
39
+ return f"{base_filename}_0001.joblib"
40
 
41
+ def get_next_version(base_filename):
42
+ """
43
+ Genera el nombre del archivo para la siguiente versión.
44
+ Args:
45
+ base_filename (str): Nombre base del archivo (sin versión)
46
+ Returns:
47
+ str: Nombre del archivo con la siguiente versión
48
+ """
49
+ latest_file = get_latest_version(base_filename)
50
+ match = re.search(r'_(\d{4})\.joblib$', latest_file)
51
+ if match:
52
+ current_version = int(match.group(1))
53
+ next_version = current_version + 1
54
+ else:
55
+ next_version = 1
56
+
57
+ return f"{base_filename}_{next_version:04d}.joblib"
58
 
59
+ def recomienda_tf(new_basket, cestas):
 
60
  # Cargar la matriz TF y el modelo
61
+ tf_matrix = load(get_latest_version('tf_matrix'))
62
+ count = load(get_latest_version('count_vectorizer'))
63
+
64
  # Convertir la nueva cesta en formato TF (Term Frequency)
65
  new_basket_str = ' '.join(new_basket)
66
  new_basket_vector = count.transform([new_basket_str])
 
106
  })
107
  recommendations_df = pd.DataFrame(recommendations_data)
108
 
109
+ return recommendations_df
110
+
111
+ def retroalimentacion(cestas, cesta_nueva):
112
+ # Pasamos de lista a cadena de texto
113
+ cesta_unida = ' '.join(cesta_nueva)
114
+ # Añadimos la cesta nueva al histórico de cestas. Primero comprobamos si la cesta nueva ya está
115
+ if not cestas['Cestas'].isin([cesta_unida]).any():
116
+ # Añadir la nueva cesta si no existe
117
+ cestas.loc[len(cestas)] = cesta_unida
118
+ print("Cesta añadida.")
119
+ # Reescribimos la nueva cesta
120
+ cestas.to_csv('cesta_su.csv')
121
+ else:
122
+ print("La cesta ya existe en el DataFrame.")
123
+
124
+ # Vectorizamos de nuevo el df de cestas
125
+ count_vectorizer = CountVectorizer()
126
+ count_vectorizer.fit(cestas['Cestas'])
127
+ count_matrix = count_vectorizer.transform(cestas['Cestas'])
128
+ tf_matrix = normalize(count_matrix, norm='l1')
129
+
130
+ # Guardar con nueva versión
131
+ count_vectorizer_file = get_next_version('count_vectorizer')
132
+ tf_matrix_file = get_next_version('tf_matrix')
133
+
134
+ dump(count_vectorizer, count_vectorizer_file)
135
+ dump(tf_matrix, tf_matrix_file)
136
+
137
+
138
+ return None
139
+
140
+ # def recomienda_tf(new_basket,cestas,productos):
141
+ # # Cargar la matriz TF y el modelo
142
+ # tf_matrix = load('tf_matrix.joblib')
143
+
144
+ # count = load('count_vectorizer.joblib')
145
+ # # Convertir la nueva cesta en formato TF (Term Frequency)
146
+ # new_basket_str = ' '.join(new_basket)
147
+ # new_basket_vector = count.transform([new_basket_str])
148
+ # new_basket_tf = normalize(new_basket_vector, norm='l1') # Normalizamos la matriz count de la cesta actual
149
+ # # Comparar la nueva cesta con las anteriores
150
+ # similarities = cosine_similarity(new_basket_tf, tf_matrix)
151
+ # # Obtener los índices de las cestas más similares
152
+ # similar_indices = similarities.argsort()[0][-4:] # Las 4 más similares
153
+ # # Crear un diccionario para contar las recomendaciones
154
+ # recommendations_count = {}
155
+ # total_similarity = 0
156
+ # # Recomendar productos de cestas similares
157
+ # for idx in similar_indices:
158
+ # sim_score = similarities[0][idx]
159
+ # total_similarity += sim_score # Suma de las similitudes
160
+ # products = cestas.iloc[idx]['Cestas'].split()
161
+ # # Usar un conjunto para evitar contar productos múltiples veces en la misma cesta
162
+ # unique_products = set(products) # Usar un conjunto para obtener productos únicos
163
+ # # Con esto evitamos que la importancia crezca por las unidades
164
+ # for product in unique_products:
165
+ # if product.strip() not in new_basket: # Evitar recomendar lo que ya está en la cesta
166
+ # recommendations_count[product.strip()] = recommendations_count.get(product.strip(), 0) + sim_score
167
+ # # Almacena el conteo de la relevancia de cada producto basado en cuántas veces aparece en las cestas similares, ponderado por la similitud de cada cesta.
168
+ # # Calcular la probabilidad relativa de cada producto recomendado
169
+ # recommendations_with_prob = []
170
+ # if total_similarity > 0: # Verificar que total_similarity no sea cero
171
+ # recommendations_with_prob = [(product, score / total_similarity) for product, score in recommendations_count.items()]
172
+ # else:
173
+ # print("No se encontraron similitudes suficientes para calcular probabilidades.")
174
+
175
+ # recommendations_with_prob.sort(key=lambda x: x[1], reverse=True) # Ordenar por puntuación
176
+ # # Crear un nuevo DataFrame para almacenar las recomendaciones
177
+ # recommendations_data = []
178
+
179
+ # for product, score in recommendations_with_prob:
180
+ # # Buscar la descripción en el DataFrame de productos
181
+ # description = productos.loc[productos['ARTICULO'] == product, 'DESCRIPCION']
182
+ # if not description.empty:
183
+ # recommendations_data.append({
184
+ # 'ARTICULO': product,
185
+ # 'DESCRIPCION': description.values[0], # Obtener el primer valor encontrado
186
+ # 'RELEVANCIA': score
187
+ # })
188
+ # recommendations_df = pd.DataFrame(recommendations_data)
189
+
190
+ # return recommendations_df