Spaces:
Sleeping
Sleeping
File size: 8,777 Bytes
858332b 19c2f0c |
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
import pandas as pd
import numpy as np
import warnings
import glob
import os
import re
warnings.filterwarnings('ignore')
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from joblib import dump, load
from sklearn.preprocessing import normalize
def get_latest_version(base_filename):
"""
Obtiene la última versión del archivo guardado.
Args:
base_filename (str): Nombre base del archivo (sin versión)
Returns:
str: Nombre del archivo con la versión más reciente
"""
# Buscar todos los archivos que coincidan con el patrón
pattern = f"{base_filename}_*.joblib"
matching_files = glob.glob(pattern)
if not matching_files:
return f"{base_filename}_0001.joblib"
# Extraer los números de versión y encontrar el máximo
versions = []
for file in matching_files:
match = re.search(r'_(\d{4})\.joblib$', file)
if match:
versions.append(int(match.group(1)))
if versions:
latest_version = max(versions)
return f"{base_filename}_{latest_version:04d}.joblib"
return f"{base_filename}_0001.joblib"
def get_next_version(base_filename):
"""
Genera el nombre del archivo para la siguiente versión.
Args:
base_filename (str): Nombre base del archivo (sin versión)
Returns:
str: Nombre del archivo con la siguiente versión
"""
latest_file = get_latest_version(base_filename)
match = re.search(r'_(\d{4})\.joblib$', latest_file)
if match:
current_version = int(match.group(1))
next_version = current_version + 1
else:
next_version = 1
return f"{base_filename}_{next_version:04d}.joblib"
def recomienda_tf(new_basket, cestas, productos):
# Cargar la matriz TF y el modelo
tf_matrix = load(get_latest_version('tf_matrix'))
count = load(get_latest_version('count_vectorizer'))
# Convertir la nueva cesta en formato TF (Term Frequency)
new_basket_str = ' '.join(new_basket)
new_basket_vector = count.transform([new_basket_str])
new_basket_tf = normalize(new_basket_vector, norm='l1') # Normalizamos la matriz count de la cesta actual
# Comparar la nueva cesta con las anteriores
similarities = cosine_similarity(new_basket_tf, tf_matrix)
# Obtener los índices de las cestas más similares
similar_indices = similarities.argsort()[0][-4:] # Las 4 más similares
# Crear un diccionario para contar las recomendaciones
recommendations_count = {}
total_similarity = 0
# Recomendar productos de cestas similares
for idx in similar_indices:
sim_score = similarities[0][idx]
total_similarity += sim_score # Suma de las similitudes
products = cestas.iloc[idx]['Cestas'].split()
# Usar un conjunto para evitar contar productos múltiples veces en la misma cesta
unique_products = set(products) # Usar un conjunto para obtener productos únicos
# Con esto evitamos que la importancia crezca por las unidades
for product in unique_products:
if product.strip() not in new_basket: # Evitar recomendar lo que ya está en la cesta
recommendations_count[product.strip()] = recommendations_count.get(product.strip(), 0) + sim_score
# 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.
# Calcular la probabilidad relativa de cada producto recomendado
recommendations_with_prob = []
if total_similarity > 0: # Verificar que total_similarity no sea cero
recommendations_with_prob = [(product, score / total_similarity) for product, score in recommendations_count.items()]
else:
print("No se encontraron similitudes suficientes para calcular probabilidades.")
recommendations_with_prob.sort(key=lambda x: x[1], reverse=True) # Ordenar por puntuación
# Crear un nuevo DataFrame para almacenar las recomendaciones
recommendations_data = []
for product, score in recommendations_with_prob:
# Buscar la descripción en el DataFrame de productos
description = productos.loc[productos['ARTICULO'] == product, 'DESCRIPCION']
if not description.empty:
recommendations_data.append({
'ARTICULO': product,
'DESCRIPCION': description.values[0], # Obtener el primer valor encontrado
'RELEVANCIA': score
})
recommendations_df = pd.DataFrame(recommendations_data)
return recommendations_df
def retroalimentacion(cestas, cesta_nueva):
# Pasamos de lista a cadena de texto
cesta_unida = ' '.join(cesta_nueva)
# Añadimos la cesta nueva al histórico de cestas. Primero comprobamos si la cesta nueva ya está
if not cestas['Cestas'].isin([cesta_unida]).any():
# Añadir la nueva cesta si no existe
cestas.loc[len(cestas)] = cesta_unida
print("Cesta añadida.")
# Reescribimos la nueva cesta
cestas.to_csv('cesta_su.csv')
else:
print("La cesta ya existe en el DataFrame.")
# Vectorizamos de nuevo el df de cestas
count_vectorizer = CountVectorizer()
count_vectorizer.fit(cestas['Cestas'])
count_matrix = count_vectorizer.transform(cestas['Cestas'])
tf_matrix = normalize(count_matrix, norm='l1')
# Guardar con nueva versión
count_vectorizer_file = get_next_version('count_vectorizer')
tf_matrix_file = get_next_version('tf_matrix')
dump(count_vectorizer, count_vectorizer_file)
dump(tf_matrix, tf_matrix_file)
return None
# def recomienda_tf(new_basket,cestas,productos):
# # Cargar la matriz TF y el modelo
# tf_matrix = load('tf_matrix.joblib')
# count = load('count_vectorizer.joblib')
# # Convertir la nueva cesta en formato TF (Term Frequency)
# new_basket_str = ' '.join(new_basket)
# new_basket_vector = count.transform([new_basket_str])
# new_basket_tf = normalize(new_basket_vector, norm='l1') # Normalizamos la matriz count de la cesta actual
# # Comparar la nueva cesta con las anteriores
# similarities = cosine_similarity(new_basket_tf, tf_matrix)
# # Obtener los índices de las cestas más similares
# similar_indices = similarities.argsort()[0][-4:] # Las 4 más similares
# # Crear un diccionario para contar las recomendaciones
# recommendations_count = {}
# total_similarity = 0
# # Recomendar productos de cestas similares
# for idx in similar_indices:
# sim_score = similarities[0][idx]
# total_similarity += sim_score # Suma de las similitudes
# products = cestas.iloc[idx]['Cestas'].split()
# # Usar un conjunto para evitar contar productos múltiples veces en la misma cesta
# unique_products = set(products) # Usar un conjunto para obtener productos únicos
# # Con esto evitamos que la importancia crezca por las unidades
# for product in unique_products:
# if product.strip() not in new_basket: # Evitar recomendar lo que ya está en la cesta
# recommendations_count[product.strip()] = recommendations_count.get(product.strip(), 0) + sim_score
# # 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.
# # Calcular la probabilidad relativa de cada producto recomendado
# recommendations_with_prob = []
# if total_similarity > 0: # Verificar que total_similarity no sea cero
# recommendations_with_prob = [(product, score / total_similarity) for product, score in recommendations_count.items()]
# else:
# print("No se encontraron similitudes suficientes para calcular probabilidades.")
# recommendations_with_prob.sort(key=lambda x: x[1], reverse=True) # Ordenar por puntuación
# # Crear un nuevo DataFrame para almacenar las recomendaciones
# recommendations_data = []
# for product, score in recommendations_with_prob:
# # Buscar la descripción en el DataFrame de productos
# description = productos.loc[productos['ARTICULO'] == product, 'DESCRIPCION']
# if not description.empty:
# recommendations_data.append({
# 'ARTICULO': product,
# 'DESCRIPCION': description.values[0], # Obtener el primer valor encontrado
# 'RELEVANCIA': score
# })
# recommendations_df = pd.DataFrame(recommendations_data)
# return recommendations_df |