Añadida variable de entrada de la función recomienda_tf

#1
Files changed (1) hide show
  1. utils.py +189 -189
utils.py CHANGED
@@ -1,190 +1,190 @@
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])
67
- new_basket_tf = normalize(new_basket_vector, norm='l1') # Normalizamos la matriz count de la cesta actual
68
- # Comparar la nueva cesta con las anteriores
69
- similarities = cosine_similarity(new_basket_tf, tf_matrix)
70
- # Obtener los índices de las cestas más similares
71
- similar_indices = similarities.argsort()[0][-4:] # Las 4 más similares
72
- # Crear un diccionario para contar las recomendaciones
73
- recommendations_count = {}
74
- total_similarity = 0
75
- # Recomendar productos de cestas similares
76
- for idx in similar_indices:
77
- sim_score = similarities[0][idx]
78
- total_similarity += sim_score # Suma de las similitudes
79
- products = cestas.iloc[idx]['Cestas'].split()
80
- # Usar un conjunto para evitar contar productos múltiples veces en la misma cesta
81
- unique_products = set(products) # Usar un conjunto para obtener productos únicos
82
- # Con esto evitamos que la importancia crezca por las unidades
83
- for product in unique_products:
84
- if product.strip() not in new_basket: # Evitar recomendar lo que ya está en la cesta
85
- recommendations_count[product.strip()] = recommendations_count.get(product.strip(), 0) + sim_score
86
- # 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.
87
- # Calcular la probabilidad relativa de cada producto recomendado
88
- recommendations_with_prob = []
89
- if total_similarity > 0: # Verificar que total_similarity no sea cero
90
- recommendations_with_prob = [(product, score / total_similarity) for product, score in recommendations_count.items()]
91
- else:
92
- print("No se encontraron similitudes suficientes para calcular probabilidades.")
93
-
94
- recommendations_with_prob.sort(key=lambda x: x[1], reverse=True) # Ordenar por puntuación
95
- # Crear un nuevo DataFrame para almacenar las recomendaciones
96
- recommendations_data = []
97
-
98
- for product, score in recommendations_with_prob:
99
- # Buscar la descripción en el DataFrame de productos
100
- description = productos.loc[productos['ARTICULO'] == product, 'DESCRIPCION']
101
- if not description.empty:
102
- recommendations_data.append({
103
- 'ARTICULO': product,
104
- 'DESCRIPCION': description.values[0], # Obtener el primer valor encontrado
105
- 'RELEVANCIA': score
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
 
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, productos):
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])
67
+ new_basket_tf = normalize(new_basket_vector, norm='l1') # Normalizamos la matriz count de la cesta actual
68
+ # Comparar la nueva cesta con las anteriores
69
+ similarities = cosine_similarity(new_basket_tf, tf_matrix)
70
+ # Obtener los índices de las cestas más similares
71
+ similar_indices = similarities.argsort()[0][-4:] # Las 4 más similares
72
+ # Crear un diccionario para contar las recomendaciones
73
+ recommendations_count = {}
74
+ total_similarity = 0
75
+ # Recomendar productos de cestas similares
76
+ for idx in similar_indices:
77
+ sim_score = similarities[0][idx]
78
+ total_similarity += sim_score # Suma de las similitudes
79
+ products = cestas.iloc[idx]['Cestas'].split()
80
+ # Usar un conjunto para evitar contar productos múltiples veces en la misma cesta
81
+ unique_products = set(products) # Usar un conjunto para obtener productos únicos
82
+ # Con esto evitamos que la importancia crezca por las unidades
83
+ for product in unique_products:
84
+ if product.strip() not in new_basket: # Evitar recomendar lo que ya está en la cesta
85
+ recommendations_count[product.strip()] = recommendations_count.get(product.strip(), 0) + sim_score
86
+ # 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.
87
+ # Calcular la probabilidad relativa de cada producto recomendado
88
+ recommendations_with_prob = []
89
+ if total_similarity > 0: # Verificar que total_similarity no sea cero
90
+ recommendations_with_prob = [(product, score / total_similarity) for product, score in recommendations_count.items()]
91
+ else:
92
+ print("No se encontraron similitudes suficientes para calcular probabilidades.")
93
+
94
+ recommendations_with_prob.sort(key=lambda x: x[1], reverse=True) # Ordenar por puntuación
95
+ # Crear un nuevo DataFrame para almacenar las recomendaciones
96
+ recommendations_data = []
97
+
98
+ for product, score in recommendations_with_prob:
99
+ # Buscar la descripción en el DataFrame de productos
100
+ description = productos.loc[productos['ARTICULO'] == product, 'DESCRIPCION']
101
+ if not description.empty:
102
+ recommendations_data.append({
103
+ 'ARTICULO': product,
104
+ 'DESCRIPCION': description.values[0], # Obtener el primer valor encontrado
105
+ 'RELEVANCIA': score
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