darlingoscanoa/retail_planogram_optimization
0
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()