Spaces:
Sleeping
Sleeping
| 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()) |