Spaces:
Sleeping
Sleeping
File size: 9,731 Bytes
2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 2df54e5 e8a8147 | 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 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | """
Main application entry point for Hugging Face Spaces.
"""
import gradio as gr
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from datetime import datetime, timedelta
# Simple in-memory data storage
class AppState:
def __init__(self):
self.data = None
self.forecast = None
app_state = AppState()
def load_sample_data(dataset_name):
"""Load or generate sample data."""
try:
# Generate synthetic data
dates = pd.date_range(start='2023-01-01', periods=365, freq='D')
if "Retail" in dataset_name:
# Retail pattern with weekly seasonality
base = 100
trend = np.linspace(0, 20, 365)
seasonal = 20 * np.sin(2 * np.pi * np.arange(365) / 7)
noise = np.random.normal(0, 5, 365)
values = base + trend + seasonal + noise
elif "Walmart" in dataset_name:
# Walmart M5 style
base = 150
trend = np.linspace(0, 30, 365)
weekly = 40 * np.sin(2 * np.pi * np.arange(365) / 7)
noise = np.random.normal(0, 10, 365)
values = base + trend + weekly + noise
else:
# Synthetic random walk
values = 100 + np.cumsum(np.random.randn(365) * 5)
values = np.maximum(values, 10) # Keep positive
data = pd.DataFrame({
'date': dates,
'value': values
})
app_state.data = data
# Create stats
stats = f"""
📊 Dataset Statistics:
• Total Rows: {len(data)}
• Date Range: {data['date'].min().date()} to {data['date'].max().date()}
• Mean Value: {data['value'].mean():.2f}
• Std Dev: {data['value'].std():.2f}
• Min Value: {data['value'].min():.2f}
• Max Value: {data['value'].max():.2f}
"""
# Create plot
fig = go.Figure()
fig.add_trace(go.Scatter(
x=data['date'],
y=data['value'],
mode='lines',
name='Historical Data',
line=dict(color='blue', width=2)
))
fig.update_layout(
title="Time Series Data",
xaxis_title="Date",
yaxis_title="Value",
template='plotly_white',
height=400
)
return data.head(100), stats, fig, "✅ Data loaded successfully!"
except Exception as e:
return None, f"❌ Error: {str(e)}", None, "Failed to load data"
def simple_forecast(horizon):
"""Generate simple moving average forecast."""
try:
if app_state.data is None:
return None, "❌ Please load data first!", "Please load data in Data Upload tab"
data = app_state.data
# Simple moving average forecast
window = min(30, len(data) // 2)
ma = data['value'].tail(window).mean()
std = data['value'].tail(window).std()
# Generate future dates
last_date = data['date'].iloc[-1]
future_dates = pd.date_range(start=last_date + timedelta(days=1), periods=horizon, freq='D')
# Simple forecast
forecast_values = np.ones(horizon) * ma
lower = forecast_values - 1.96 * std
upper = forecast_values + 1.96 * std
forecast_df = pd.DataFrame({
'date': future_dates,
'forecast': forecast_values,
'lower_bound': lower,
'upper_bound': upper
})
app_state.forecast = forecast_df
# Create plot
fig = go.Figure()
# Historical
fig.add_trace(go.Scatter(
x=data['date'],
y=data['value'],
mode='lines',
name='Historical',
line=dict(color='blue', width=2)
))
# Forecast
fig.add_trace(go.Scatter(
x=forecast_df['date'],
y=forecast_df['forecast'],
mode='lines',
name='Forecast',
line=dict(color='red', width=2, dash='dash')
))
# Confidence interval
fig.add_trace(go.Scatter(
x=forecast_df['date'].tolist() + forecast_df['date'].tolist()[::-1],
y=forecast_df['upper_bound'].tolist() + forecast_df['lower_bound'].tolist()[::-1],
fill='toself',
fillcolor='rgba(255,0,0,0.2)',
line=dict(color='rgba(255,255,255,0)'),
name='95% Confidence',
showlegend=True
))
fig.update_layout(
title=f"{horizon}-Day Forecast",
xaxis_title="Date",
yaxis_title="Value",
template='plotly_white',
height=400
)
info = f"""
📈 Forecast Information:
• Model: Moving Average (Simple)
• Horizon: {horizon} days
• Mean Forecast: {forecast_values.mean():.2f}
• Confidence Level: 95%
"""
return fig, info, "✅ Forecast generated successfully!"
except Exception as e:
return None, f"❌ Error: {str(e)}", "Forecast generation failed"
def calculate_eoq():
"""Calculate Economic Order Quantity."""
try:
if app_state.forecast is None:
return "❌ Please generate forecast first!", ""
# Simple EOQ calculation
annual_demand = app_state.forecast['forecast'].sum() * (365 / len(app_state.forecast))
ordering_cost = 100.0
holding_cost = 10.0 * 0.20
# EOQ formula
eoq = np.sqrt(2 * annual_demand * ordering_cost / holding_cost)
num_orders = annual_demand / eoq
total_cost = (num_orders * ordering_cost) + ((eoq / 2) * holding_cost)
results = f"""
📦 Inventory Optimization Results (EOQ Model):
• Optimal Order Quantity: {eoq:.2f} units
• Number of Orders per Year: {num_orders:.2f}
• Order Cycle Time: {365 / num_orders:.1f} days
• Total Annual Cost: ${total_cost:.2f}
- Ordering Cost: ${num_orders * ordering_cost:.2f}
- Holding Cost: ${(eoq / 2) * holding_cost:.2f}
• Annual Demand: {annual_demand:.2f} units
"""
recommendations = f"""
💡 Recommendations:
• Place an order of {eoq:.0f} units every {365 / num_orders:.0f} days
• Maintain safety stock of {eoq * 0.2:.0f} units
• Monitor demand patterns for adjustments
"""
return results, recommendations
except Exception as e:
return f"❌ Error: {str(e)}", ""
# Create Gradio interface
with gr.Blocks(title="ForecastIQ Pro", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🎯 ForecastIQ Pro
**AI-Powered Demand Forecasting & Inventory Optimization**
""")
with gr.Tabs():
# Tab 1: Data Upload
with gr.Tab("📁 Data Upload"):
with gr.Row():
with gr.Column():
dataset_selector = gr.Radio(
choices=["Sample: Retail Sales", "Sample: Walmart M5", "Sample: Synthetic"],
label="Select Dataset",
value="Sample: Retail Sales"
)
load_btn = gr.Button("Load Data", variant="primary")
status_text = gr.Textbox(label="Status", lines=1)
with gr.Column():
data_stats = gr.Textbox(label="Statistics", lines=8)
data_preview = gr.Dataframe(label="Data Preview")
data_plot = gr.Plot(label="Time Series Visualization")
load_btn.click(
load_sample_data,
inputs=[dataset_selector],
outputs=[data_preview, data_stats, data_plot, status_text]
)
# Tab 2: Forecasting
with gr.Tab("🔮 Forecasting"):
with gr.Row():
with gr.Column():
horizon_slider = gr.Slider(
minimum=7,
maximum=90,
value=30,
step=1,
label="Forecast Horizon (days)"
)
forecast_btn = gr.Button("Generate Forecast", variant="primary")
forecast_status = gr.Textbox(label="Status", lines=1)
with gr.Column():
forecast_info = gr.Textbox(label="Forecast Information", lines=8)
forecast_plot = gr.Plot(label="Forecast Results")
forecast_btn.click(
simple_forecast,
inputs=[horizon_slider],
outputs=[forecast_plot, forecast_info, forecast_status]
)
# Tab 3: Optimization
with gr.Tab("📦 Inventory Optimization"):
gr.Markdown("### Economic Order Quantity (EOQ) Model")
optimize_btn = gr.Button("Calculate Optimal Inventory", variant="primary")
with gr.Row():
opt_results = gr.Textbox(label="Optimization Results", lines=12)
opt_recommendations = gr.Textbox(label="Recommendations", lines=12)
optimize_btn.click(
calculate_eoq,
inputs=[],
outputs=[opt_results, opt_recommendations]
)
gr.Markdown("""
---
### 📚 About ForecastIQ Pro
A production-grade platform for demand forecasting and inventory optimization.
Combines time series analysis with operations research for data-driven decision making.
""")
if __name__ == "__main__":
demo.launch(share=True)
|