import gradio as gr import pandas as pd import joblib import plotly.express as px import plotly.graph_objects as go # --- 1. DATA & MODEL LOADING --- # Load your model and feature list model = joblib.load("sales_model.joblib") feature_names = joblib.load("feature_names.joblib") # Load your CSV for EDA charts df = pd.read_csv("sales_data.csv") df['date'] = pd.to_datetime(df['date']) df['revenue'] = df['units_sold'] * df['price_unit'] df['weekday'] = df['date'].dt.day_name() # --- 2. HELPERS & INSIGHTS --- def get_business_insights(): promo_avg = df.groupby('promotion_flag')['units_sold'].mean() lift = ((promo_avg[1] - promo_avg[0]) / promo_avg[0]) * 100 top_brand = df.groupby('brand')['revenue'].sum().idxmax() top_region = df.groupby('region')['units_sold'].sum().idxmax() insights = f""" ### 💡 Key Business Insights * **Promotion Impact:** Promotions drive a **{lift:.1f}% increase** in average sales volume. * **Revenue Leader:** **{top_brand}** is currently the top-performing brand by total revenue. * **Regional Powerhouse:** **{top_region}** is the highest volume region. * **Inventory Note:** Average stock availability is currently **{df['stock_available'].mean():.1f} units**. """ return insights # --- 2. PREDICTION LOGIC --- def predict_sales(u_date, u_brand, u_region, u_price, u_promo, u_stock): target_date = pd.to_datetime(u_date) # Initialize input row with zeros matching training features input_row = pd.DataFrame(0, index=[0], columns=feature_names) # Fill Time Features input_row['month'] = target_date.month input_row['day_of_week'] = target_date.weekday() input_row['is_weekend'] = 1 if target_date.weekday() >= 5 else 0 # Fill Numerical Features input_row['price_unit'] = u_price input_row['promotion_flag'] = 1 if u_promo else 0 input_row['stock_available'] = u_stock # Fill Categorical Features (One-Hot Encoding match) brand_col = f"brand_{u_brand}" region_col = f"region_{u_region}" if brand_col in input_row.columns: input_row[brand_col] = 1 if region_col in input_row.columns: input_row[region_col] = 1 # Predict prediction = model.predict(input_row)[0] prediction = max(0, int(prediction)) revenue = prediction * u_price # Context Chart brand_avg = df[df['brand'] == u_brand]['units_sold'].mean() categories = ['Predicted', f'{u_brand} Avg'] values = [prediction, brand_avg] fig = px.bar(x=categories, y=values, color=categories, title=f"Forecast vs. {u_brand} Average", labels={'x': '', 'y': 'Units'}) fig.update_layout(showlegend=False, height=300) return f"{prediction} Units", f"${revenue:,.2f}", fig # --- 3. EDA CHART FUNCTIONS --- def plot_brand_revenue(): brand_rev = df.groupby('brand')['revenue'].sum().sort_values(ascending=True).reset_index() fig = px.bar(brand_rev, x='revenue', y='brand', orientation='h', title="Total Revenue by Brand", color='revenue', color_continuous_scale='Viridis') return fig def plot_promo_lift(): promo_data = df.groupby('promotion_flag')['units_sold'].mean().reset_index() promo_data['promotion_flag'] = promo_data['promotion_flag'].map({0: 'No Promo', 1: 'Promo Active'}) fig = px.bar(promo_data, x='promotion_flag', y='units_sold', color='promotion_flag', title="Average Volume: Promotion Impact") return fig def plot_region_sales(): region_sales = df.groupby('region')['units_sold'].sum().reset_index() fig = px.pie(region_sales, values='units_sold', names='region', title="Volume by Region", hole=0.4) return fig def plot_sales_trend(): trend = df.resample('W', on='date')['units_sold'].sum().reset_index() fig = px.line(trend, x='date', y='units_sold', title="Weekly Sales Trend", markers=True) return fig # --- 4. GRADIO UI LAYOUT --- with gr.Blocks() as demo: gr.Markdown("# 🥛 Smart Sales & Revenue Intelligence") gr.Markdown("Predict future performance and explore historical data patterns.") with gr.Tabs(): # TAB 1: DATA EXPLORATION with gr.TabItem("📊 EDA Dashboard"): gr.Markdown(get_business_insights()) with gr.Row(): gr.Plot(plot_brand_revenue()) gr.Plot(plot_promo_lift()) with gr.Row(): gr.Plot(plot_sales_trend()) gr.Plot(plot_region_sales()) with gr.Accordion("View Raw Data Snippet", open=False): gr.DataFrame(df.sample(10)) # TAB 2: PREDICTOR with gr.TabItem("🔮 Sales Forecast"): with gr.Row(): with gr.Column(): gr.Markdown("### Input Parameters") u_date = gr.DateTime(label="Select Target Date") u_brand = gr.Dropdown(sorted(df['brand'].unique().tolist()), label="Brand") u_region = gr.Dropdown(sorted(df['region'].unique().tolist()), label="Region") u_price = gr.Number(label="Unit Price ($)", value=2.50) u_promo = gr.Checkbox(label="Is Promotion Active?") u_stock = gr.Slider(0, 500, label="Stock Availability", value=150) predict_btn = gr.Button("Generate Prediction", variant="primary") with gr.Column(): gr.Markdown("### Model Output") out_sales = gr.Textbox(label="Predicted Sales Volume") out_rev = gr.Textbox(label="Estimated Gross Revenue") out_plot = gr.Plot(label="Forecast Context") gr.Markdown("---") gr.Info("Note: Predictions are based on historical XGBoost training patterns.") predict_btn.click( predict_sales, inputs=[u_date, u_brand, u_region, u_price, u_promo, u_stock], outputs=[out_sales, out_rev, out_plot] ) # --- 5. LAUNCH --- if __name__ == "__main__": demo.launch(theme=gr.themes.Soft())