File size: 6,864 Bytes
14ebf0e
 
 
 
 
 
 
 
 
0d539da
14ebf0e
 
 
 
 
0d539da
14ebf0e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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()