CoolFace
Apppublic

darlingoscanoa/retail_planogram_optimization

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py139 linesDownload Raw Back to root
1import gradio as gr
2import pandas as pd
3import numpy as np
4from sklearn.ensemble import RandomForestRegressor
5import matplotlib.pyplot as plt
6from datetime import datetime, timedelta
7
8# Función para generar datos sintéticos
9def generate_shoe_data(start_date, end_date):
10    date_range = pd.date_range(start=start_date, end=end_date)
11    data = []
12    categories = ['Athletic', 'Casual', 'Formal', 'Boots', 'Sandals']
13    locations = ['Entrance', 'Left Aisle', 'Right Aisle', 'Back', 'Try-on Area', 'Clearance']
14    
15    for date in date_range:
16        is_weekend = date.dayofweek >= 5
17        num_sales = np.random.randint(90, 110) if is_weekend else np.random.randint(45, 55)
18        
19        for _ in range(num_sales):
20            category = np.random.choice(categories, p=[0.3, 0.25, 0.2, 0.15, 0.1])
21            location = np.random.choice(locations)
22            price = np.random.uniform(30, 200)
23            size = np.random.randint(5, 13)
24            
25            data.append({
26                'Date': date,
27                'Category': category,
28                'Location': location,
29                'Price': price,
30                'Size': size
31            })
32    
33    return pd.DataFrame(data)
34
35# Clase PlanogramOptimizer
36class PlanogramOptimizer:
37    def __init__(self):
38        self.model = RandomForestRegressor(n_estimators=100, random_state=42)
39        self.locations = ['Entrance', 'Left Aisle', 'Right Aisle', 'Back', 'Try-on Area', 'Clearance']
40        
41    def train(self, sales_data):
42        # Group the data and create a DataFrame with the count
43        grouped_data = sales_data.groupby(['Date', 'Category', 'Location']).size().reset_index(name='Sales')
44        
45        # Create X using the grouped data
46        X = pd.get_dummies(grouped_data[['Category', 'Location']])
47        
48        # Use the 'Sales' column from the grouped data as y
49        y = grouped_data['Sales']
50        
51        self.model.fit(X, y)
52        
53    def optimize(self, categories):
54        test_data = []
55        for category in categories:
56            for location in self.locations:
57                test_data.append({'Category': category, 'Location': location})
58        
59        X_test = pd.get_dummies(pd.DataFrame(test_data))
60        predictions = self.model.predict(X_test)
61        
62        optimized_planogram = {}
63        for i, category in enumerate(categories):
64            category_predictions = predictions[i*len(self.locations):(i+1)*len(self.locations)]
65            best_location = self.locations[np.argmax(category_predictions)]
66            optimized_planogram[category] = best_location
67        
68        return optimized_planogram
69
70# Generar datos para 2023
71df = generate_shoe_data(start_date='2023-01-01', end_date='2023-12-31')
72df['Month'] = df['Date'].dt.month
73
74# Inicializar y entrenar el modelo
75optimizer = PlanogramOptimizer()
76optimizer.train(df)
77
78# Función para crear la visualización del planograma
79def create_planogram_visual(optimized_planogram):
80    fig, ax = plt.subplots(figsize=(12, 8))
81    locations = optimizer.locations
82    categories = list(optimized_planogram.keys())
83    colors = plt.cm.Set3(np.linspace(0, 1, len(categories)))
84    
85    store_layout = {
86        'Entrance': (0, 0, 2, 1),
87        'Left Aisle': (0, 1, 1, 3),
88        'Right Aisle': (3, 1, 1, 3),
89        'Back': (1, 4, 2, 1),
90        'Try-on Area': (1, 1, 2, 2),
91        'Clearance': (1, 3, 2, 1)
92    }
93    
94    for location, (x, y, w, h) in store_layout.items():
95        ax.add_patch(plt.Rectangle((x, y), w, h, fill=False, edgecolor='black'))
96        ax.text(x + w/2, y + h/2, location, ha='center', va='center')
97    
98    for category, location in optimized_planogram.items():
99        x, y, w, h = store_layout[location]
100        color = colors[categories.index(category)]
101        ax.add_patch(plt.Rectangle((x, y), w, h, fill=True, alpha=0.5, color=color))
102        ax.text(x + w/2, y + h/2, category, ha='center', va='center', fontweight='bold')
103    
104    ax.set_xlim(0, 4)
105    ax.set_ylim(0, 5)
106    ax.set_aspect('equal')
107    ax.axis('off')
108    ax.set_title('Optimized Planogram for January 2024')
109    
110    return fig
111
112# Función para optimizar el planograma
113def optimize_planogram(categories):
114    category_list = [c.strip() for c in categories.split(',')]
115    optimized = optimizer.optimize(category_list)
116    
117    result = "Optimized Planogram for January 2024:\n\n"
118    for category, location in optimized.items():
119        result += f"{category}: {location}\n"
120    
121    fig = create_planogram_visual(optimized)
122    return result.strip(), fig
123
124# Crear la interfaz de Gradio
125iface = gr.Interface(
126    fn=optimize_planogram,
127    inputs=[
128        gr.Textbox(label="Categories (comma-separated)", value="Athletic,Casual,Formal,Boots,Sandals"),
129    ],
130    outputs=[
131        gr.Textbox(label="Optimization Results"),
132        gr.Plot(label="Planogram Visualization")
133    ],
134    title="Shoe Store Planogram Optimizer",
135    description="Optimize product placement based on synthetic sales data for a shoe store."
136)
137
138# Lanzar la aplicación
139iface.launch()