Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import joblib | |
| import numpy as np | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| # ----------------------------- | |
| # Load trained model | |
| # ----------------------------- | |
| MODEL_PATH = "models/influencer_roi_model.joblib" | |
| model = joblib.load(MODEL_PATH) | |
| # IMPORTANT: These must match the training feature columns (X.columns) | |
| # We'll load them from a saved list if you created one. | |
| # If you didn't save feature names yet, do Step 2.1 below. | |
| FEATURES_PATH = "models/feature_columns.joblib" | |
| feature_columns = joblib.load(FEATURES_PATH) | |
| # ----------------------------- | |
| # Helper: create input row | |
| # ----------------------------- | |
| def build_input_row(platform, influencer_category, campaign_type, | |
| engagements, estimated_reach, campaign_duration_days, | |
| assumed_cost_usd): | |
| """ | |
| Converts UI inputs into a single-row DataFrame with exact feature columns. | |
| We one-hot encode platform/category/type to match training. | |
| """ | |
| # Base numeric features | |
| base = { | |
| "engagements": engagements, | |
| "estimated_reach": estimated_reach, | |
| "campaign_duration_days": campaign_duration_days, | |
| } | |
| # Build a raw dataframe with the same pre-encoded columns you had before encoding: | |
| raw = pd.DataFrame([{ | |
| **base, | |
| "platform": platform, | |
| "influencer_category": influencer_category, | |
| "campaign_type": campaign_type | |
| }]) | |
| # One-hot encode like training (drop_first=True) | |
| encoded = pd.get_dummies( | |
| raw, | |
| columns=["platform", "influencer_category", "campaign_type"], | |
| drop_first=True | |
| ) | |
| # Align to training columns (missing columns -> 0, extra -> drop) | |
| for col in feature_columns: | |
| if col not in encoded.columns: | |
| encoded[col] = 0 | |
| encoded = encoded[feature_columns] | |
| return encoded | |
| # ----------------------------- | |
| # Main prediction function | |
| # ----------------------------- | |
| def predict_sales_and_roi(platform, influencer_category, campaign_type, | |
| engagements, estimated_reach, campaign_duration_days, | |
| assumed_cost_usd): | |
| """ | |
| Predict product_sales and compute an *estimated ROI* using user-provided cost. | |
| ROI = (Predicted Sales - Cost) / Cost | |
| """ | |
| # Guard against zero/negative cost | |
| if assumed_cost_usd <= 0: | |
| return "β οΈ Please enter a campaign cost greater than 0.", None | |
| X_input = build_input_row( | |
| platform, influencer_category, campaign_type, | |
| engagements, estimated_reach, campaign_duration_days, | |
| assumed_cost_usd | |
| ) | |
| # Predict sales | |
| pred_sales = float(model.predict(X_input)[0]) | |
| # Compute ROI (as %) | |
| roi = (pred_sales - assumed_cost_usd) / assumed_cost_usd | |
| roi_percent = roi * 100.0 | |
| # Label ROI quality | |
| if roi_percent >= 50: | |
| roi_label = "π’ Strong ROI" | |
| elif roi_percent >= 0: | |
| roi_label = "π‘ Moderate ROI" | |
| else: | |
| roi_label = "π΄ Negative ROI" | |
| # Build Plotly chart: Cost vs Predicted Sales | |
| fig = go.Figure() | |
| fig.add_bar(name="Campaign Cost", x=["Campaign"], y=[assumed_cost_usd]) | |
| fig.add_bar(name="Predicted Sales", x=["Campaign"], y=[pred_sales]) | |
| fig.update_layout( | |
| barmode="group", | |
| title="Spend vs Predicted Return", | |
| xaxis_title="", | |
| yaxis_title="USD", | |
| height=420 | |
| ) | |
| # Suggestions (simple, user-friendly) | |
| tips = [] | |
| if engagements < 2000: | |
| tips.append("Increase engagement (better content hook, CTA, posting time).") | |
| if estimated_reach < 10000: | |
| tips.append("Improve reach (cross-post, collab posts, hashtags, boosted content).") | |
| if campaign_duration_days < 7: | |
| tips.append("Consider longer campaigns (more touchpoints often improves conversions).") | |
| if not tips: | |
| tips_text = "Your inputs look strong. Focus on creative quality + audience match." | |
| else: | |
| tips_text = " β’ " + "\n β’ ".join(tips) | |
| result_md = f""" | |
| # π Influencer ROI Prediction | |
| ### Predicted Financial Return | |
| - **Predicted Product Sales:** `${pred_sales:,.2f}` | |
| - **Campaign Cost:** `${assumed_cost_usd:,.2f}` | |
| - **Estimated ROI:** **{roi_percent:,.2f}%** β {roi_label} | |
| ### What this means | |
| This prediction helps brands estimate whether a campaign is likely to be profitable **before spending money**. | |
| ### Suggestions to improve ROI | |
| {tips_text} | |
| """ | |
| return result_md, fig | |
| # ----------------------------- | |
| # UI (modern dashboard feel) | |
| # ----------------------------- | |
| with gr.Blocks(title="Influencer ROI Prediction Dashboard") as app: | |
| with gr.Tab("Home"): | |
| gr.Markdown(""" | |
| # β¨ Influencer ROI Prediction Dashboard | |
| This app predicts **financial return (product sales)** from influencer campaign inputs using **Regression ML**. | |
| ### Why it matters | |
| Marketing teams can use this to: | |
| - Compare influencer platforms (Instagram vs TikTok vs YouTube) | |
| - Estimate sales impact before launching a campaign | |
| - Run **what-if scenarios** (change budget, duration, engagement) | |
| β‘οΈ Go to the **Predict** tab to try it. | |
| """) | |
| with gr.Tab("Predict"): | |
| gr.Markdown("## π§ Predict Sales + Estimated ROI") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| platform = gr.Dropdown( | |
| choices=["Instagram", "YouTube", "TikTok", "Twitter", "Facebook"], | |
| value="Instagram", | |
| label="Platform" | |
| ) | |
| influencer_category = gr.Dropdown( | |
| choices=["Micro", "Macro", "Mega", "Nano"], | |
| value="Micro", | |
| label="Influencer Category" | |
| ) | |
| campaign_type = gr.Dropdown( | |
| choices=["Product Launch", "Brand Awareness", "Seasonal Promo", "Giveaway", "Affiliate"], | |
| value="Brand Awareness", | |
| label="Campaign Type" | |
| ) | |
| engagements = gr.Number(value=5000, label="Engagements (likes/comments/etc.)") | |
| estimated_reach = gr.Number(value=50000, label="Estimated Reach") | |
| campaign_duration_days = gr.Slider(1, 60, value=14, step=1, label="Campaign Duration (days)") | |
| assumed_cost_usd = gr.Number(value=1000, label="Campaign Cost (USD)") | |
| predict_btn = gr.Button("π Predict ROI", variant="primary") | |
| with gr.Column(scale=3): | |
| output_md = gr.Markdown() | |
| output_plot = gr.Plot() | |
| predict_btn.click( | |
| fn=predict_sales_and_roi, | |
| inputs=[platform, influencer_category, campaign_type, | |
| engagements, estimated_reach, campaign_duration_days, | |
| assumed_cost_usd], | |
| outputs=[output_md, output_plot] | |
| ) | |
| if __name__ == "__main__": | |
| app.launch() | |